Skip to content

Commit

Permalink
Make timezone offset used for creates/updates configurable
Browse files Browse the repository at this point in the history
Doesn't really take dst into account since these are offsets. Should
probably take an actual timezone instead but this is still better than
hardcoded offsets in code.
  • Loading branch information
davidwilemski committed Jan 8, 2024
1 parent 82b7d67 commit 9400731
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 13 deletions.
12 changes: 8 additions & 4 deletions src/bin/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ async fn main() -> Result<(), anyhow::Error> {
{
let dbpool = dbpool.clone();
let templates = templates.clone();
move || handlers::get_archive_handler(None, dbpool.clone(), templates.clone())
let c = site_config.clone();
move || handlers::get_archive_handler(None, dbpool.clone(), templates.clone(), c.clone())
}
),
)
Expand All @@ -109,7 +110,8 @@ async fn main() -> Result<(), anyhow::Error> {
{
let dbpool = dbpool.clone();
let templates = Arc::new(crate::templates::Templates::atom_default(atom_ctx));
move || handlers::get_atom_handler(dbpool.clone(), templates.clone())
let c = site_config.clone();
move || handlers::get_atom_handler(dbpool.clone(), templates.clone(), c.clone())
}
),
)
Expand Down Expand Up @@ -185,8 +187,9 @@ async fn main() -> Result<(), anyhow::Error> {
{
let dbpool = dbpool.clone();
let templates = templates.clone();
let c = site_config.clone();
move |Path(tag): Path<String>| {
handlers::get_archive_handler(Some(tag), dbpool.clone(), templates.clone())
handlers::get_archive_handler(Some(tag), dbpool.clone(), templates.clone(), c.clone())
}
}
),
Expand All @@ -210,9 +213,10 @@ async fn main() -> Result<(), anyhow::Error> {
MethodFilter::GET.union(MethodFilter::HEAD),
{
let dbpool = dbpool.clone();
let c = site_config.clone();
move |Path(post_slug): Path<String>| {
info!("in get post handler");
handlers::get_post_handler(post_slug, dbpool.clone(), templates.clone())
handlers::get_post_handler(post_slug, dbpool.clone(), templates.clone(), c.clone())
}
}
)
Expand Down
20 changes: 20 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ pub struct MicropubConfig {
#[serde(default = "default_max_upload_length")]
pub media_endpoint_max_upload_length: usize,
pub micropub_endpoint: String,

#[serde(deserialize_with="offset_deserialize::deserialize")]
pub current_timezone_offset: chrono::FixedOffset,
}

fn default_auth_token_endpoint() -> String {
Expand All @@ -45,3 +48,20 @@ fn default_auth_endpoint() -> String {
fn default_max_upload_length() -> usize {
crate::DEFAULT_MAX_CONTENT_LENGTH
}

mod offset_deserialize {
use chrono::FixedOffset;
use serde::{self, Deserialize, Deserializer};

pub fn deserialize<'de, D>(
deserializer: D,
) -> Result<FixedOffset, D::Error>
where
D: Deserializer<'de>,
{
let offset_seconds = i32::deserialize(deserializer)?;
let offset = FixedOffset::east_opt(offset_seconds)
.ok_or(serde::de::Error::custom("invalid offset"))?;
Ok(offset)
}
}
3 changes: 2 additions & 1 deletion src/handlers/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub async fn get_archive_handler(
tag: Option<String>,
pool: Arc<r2d2::Pool<r2d2::ConnectionManager<SqliteConnection>>>,
templates: Arc<templates::Templates>,
site_config: Arc<crate::MicropubSiteConfig>,
) -> Result<impl IntoResponse, StatusCode> {
let tag_ref = tag.as_ref().map(|t| t.as_str());
let db = MicropubDB::new(pool);
Expand Down Expand Up @@ -46,7 +47,7 @@ pub async fn get_archive_handler(
for mut post in posts {
// TODO this is copied from FetchHandler. Both should not do this and should instead be
// handled e.g. at the view model creation time.
let datetime = post_util::get_local_datetime(&post.created_at, None).map_err(|e| {
let datetime = post_util::get_local_datetime(&post.created_at, &site_config.micropub.current_timezone_offset).map_err(|e| {
error!("date parsing error: {:?}", e);
// TODO shouldn't be a template error but realistically this would only happen if
// the DB had malformed data for template rendering...
Expand Down
3 changes: 2 additions & 1 deletion src/handlers/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub struct AtomHandler<DB: WithDB> {
pub async fn get_atom_handler(
pool: Arc<r2d2::Pool<r2d2::ConnectionManager<SqliteConnection>>>,
templates: Arc<templates::Templates>,
site_config: Arc<crate::MicropubSiteConfig>,
) -> Result<impl IntoResponse, StatusCode> {
let db = MicropubDB::new(pool);
let mut conn = db.dbconn()?;
Expand Down Expand Up @@ -60,7 +61,7 @@ pub async fn get_atom_handler(
for mut post in posts {
// TODO this is copied from FetchHandler. Both should not do this and should instead be
// handled e.g. at the view model creation time.
let datetime = post_util::get_local_datetime(&post.created_at, None).map_err(|e| {
let datetime = post_util::get_local_datetime(&post.created_at, &site_config.micropub.current_timezone_offset).map_err(|e| {
error!("date parsing error: {:?}", e);
// TODO shouldn't be a template error but realistically this would only happen if
// the DB had malformed data for template rendering...
Expand Down
3 changes: 2 additions & 1 deletion src/handlers/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub async fn get_post_handler(
url_slug: String,
pool: Arc<r2d2::Pool<r2d2::ConnectionManager<SqliteConnection>>>,
templates: Arc<templates::Templates>,
site_config: Arc<crate::MicropubSiteConfig>,
) -> Result<impl IntoResponse, StatusCode> {
info!("fetch_post url_slug:{:?}", url_slug);
let db = MicropubDB::new(pool);
Expand All @@ -45,7 +46,7 @@ pub async fn get_post_handler(
.map_err(|e| db.handle_errors(e))?;

debug!("input datetime: {:?}", post.created_at);
let datetime = post_util::get_local_datetime(&post.created_at, None).map_err(|e| {
let datetime = post_util::get_local_datetime(&post.created_at, &site_config.micropub.current_timezone_offset).map_err(|e| {
error!("date parsing error: {:?}", e);
// TODO shouldn't be a template error but realistically this would only happen if
// the DB had malformed data for template rendering...
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub async fn get_index_handler(
.add_context("TOKEN_ENDPOINT", &site_config.micropub.auth_token_endpoint)
.add_context("MICROPUB_ENDPOINT", &site_config.micropub.micropub_endpoint);

let datetime = post_util::get_local_datetime(&post.created_at, None).map_err(|e| {
let datetime = post_util::get_local_datetime(&post.created_at, &site_config.micropub.current_timezone_offset).map_err(|e| {
error!("date parsing error: {:?}", e);
// TODO shouldn't be a template error but realistically this would only happen if
// the DB had malformed data for template rendering...
Expand Down
4 changes: 1 addition & 3 deletions src/handlers/micropub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,9 +812,7 @@ async fn handle_update(
// TODO consider saving copies of the old post in a history table before updating? Inserting a
// new version into same table?
db.run_txn(|conn| {
// TODO make timezone part of server config
let chicago = chrono::offset::FixedOffset::west_opt(6 * 3600).unwrap();
let new_updated_at = Local::now().with_timezone(&chicago)
let new_updated_at = Local::now().with_timezone(&site_config.micropub.current_timezone_offset)
.format("%Y-%m-%d %H:%M:%S");

use crate::schema::posts::dsl::*;
Expand Down
4 changes: 2 additions & 2 deletions src/post_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ pub fn get_slug(name: Option<&str>, now_fn: fn() -> DateTime<Local>) -> String {

pub fn get_local_datetime(
datetime: &str,
offset: Option<chrono::FixedOffset>,
offset: &chrono::FixedOffset,
) -> Result<DateTime<Local>, chrono::format::ParseError> {
chrono::NaiveDateTime::parse_from_str(datetime, "%Y-%m-%d %H:%M:%S").map(|ndt| {
chrono::DateTime::<chrono::Local>::from_utc(
ndt,
offset.unwrap_or(chrono::FixedOffset::west_opt(8 * 3600).unwrap()),
*offset,
)
})
}
Expand Down

0 comments on commit 9400731

Please sign in to comment.