fix: datetime parsing

This commit is contained in:
nullishamy 2025-05-01 23:23:36 +01:00
parent f7f57e92e3
commit 41c0091e98
Signed by: amy
SSH key fingerprint: SHA256:WmV0uk6WgAQvDJlM8Ld4mFPHZo02CLXXP5VkwQ5xtyk
3 changed files with 37 additions and 6 deletions

View file

@ -1,14 +1,28 @@
use crate::types::{DbError, ObjectUri, ObjectUuid, db}; use crate::types::{DbError, ObjectUri, ObjectUuid, db};
use chrono::{DateTime, NaiveDateTime, Utc}; use chrono::{DateTime, NaiveDateTime, Utc};
use sqlx::SqliteConnection; use sqlx::SqliteConnection;
use tracing::info; use tracing::{info, error};
const SQLITE_TIME_FMT: &str = "%Y-%m-%d %H:%M:%S"; const SQLITE_TIME_FMT: &str = "%Y-%m-%d %H:%M:%S";
fn parse_ts(ts: String) -> Option<DateTime<Utc>> { fn parse_ts(ts: String) -> Option<DateTime<Utc>> {
NaiveDateTime::parse_from_str(&ts, SQLITE_TIME_FMT) // Depending on how the TS is queried it may be naive (so get it back to utc)
.ok() // or it may have a timezone associated with it
.map(|nt| nt.and_utc()) let dt = NaiveDateTime::parse_from_str(&ts, SQLITE_TIME_FMT)
.map(|ndt| {
ndt.and_utc()
})
.or_else(|_| {
DateTime::parse_from_rfc3339(&ts)
.map(|dt| dt.to_utc())
});
if let Err(err) = dt {
error!("could not parse datetime {} ({}), db weirdness", ts, err);
return None
}
Some(dt.unwrap())
} }
pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<db::User, DbError> { pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<db::User, DbError> {
@ -59,9 +73,10 @@ pub async fn user_by_id(id: ObjectUuid, conn: &mut SqliteConnection) -> Result<d
"#, "#,
record.user_id record.user_id
) )
.fetch_one(&mut *conn) .fetch_optional(&mut *conn)
.await .await
.map_err(|e| DbError::FetchError(e.to_string()))? .map_err(|e| DbError::FetchError(e.to_string()))?
.flatten()
.and_then(|ts| { .and_then(|ts| {
info!("parsing timestamp {}", ts); info!("parsing timestamp {}", ts);
parse_ts(ts) parse_ts(ts)

View file

@ -27,6 +27,12 @@ pub enum ObjectContext {
Vec(Vec<serde_json::Value>), Vec(Vec<serde_json::Value>),
} }
impl Default for ObjectContext {
fn default() -> Self {
ObjectContext::Str(String::new())
}
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct ObjectUri(pub String); pub struct ObjectUri(pub String);
@ -48,6 +54,7 @@ impl ObjectUuid {
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct Object { pub struct Object {
#[serde(rename = "@context")] #[serde(rename = "@context")]
#[serde(default)]
pub context: ObjectContext, pub context: ObjectContext,
pub id: ObjectUri, pub id: ObjectUri,
} }
@ -103,6 +110,8 @@ pub mod ap {
pub struct MinimalActivity { pub struct MinimalActivity {
#[serde(flatten)] #[serde(flatten)]
pub obj: Object, pub obj: Object,
#[serde(rename = "type")]
pub ty: ActivityType, pub ty: ActivityType,
} }
@ -123,6 +132,7 @@ pub mod ap {
#[serde(flatten)] #[serde(flatten)]
pub obj: Object, pub obj: Object,
#[serde(rename = "type")]
pub ty: ActivityType, pub ty: ActivityType,
pub object: Post, pub object: Post,
@ -139,6 +149,7 @@ pub mod ap {
#[serde(flatten)] #[serde(flatten)]
pub obj: Object, pub obj: Object,
#[serde(rename = "type")]
pub ty: ActivityType, pub ty: ActivityType,
pub object: String, pub object: String,
@ -150,6 +161,7 @@ pub mod ap {
#[serde(flatten)] #[serde(flatten)]
pub obj: Object, pub obj: Object,
#[serde(rename = "type")]
pub ty: ActivityType, pub ty: ActivityType,
pub object: String, pub object: String,
@ -161,6 +173,7 @@ pub mod ap {
#[serde(flatten)] #[serde(flatten)]
pub obj: Object, pub obj: Object,
#[serde(rename = "type")]
pub ty: ActivityType, pub ty: ActivityType,
pub actor: String, pub actor: String,
@ -175,6 +188,7 @@ pub mod ap {
#[serde(flatten)] #[serde(flatten)]
pub obj: Object, pub obj: Object,
#[serde(rename = "type")]
pub ty: ActivityType, pub ty: ActivityType,
#[serde(rename = "published")] #[serde(rename = "published")]

View file

@ -327,6 +327,8 @@ async fn handle_boost_activity<'a>(
); );
let user_id = actor_user.id(); let user_id = actor_user.id();
info!("inserting post with id {} uri {}", base_id, uri);
sqlx::query!( sqlx::query!(
" "
INSERT INTO post (id, uri, user_id, content, created_at, boosted_post_id) INSERT INTO post (id, uri, user_id, content, created_at, boosted_post_id)