diff --git a/deepwell/Cargo.toml b/deepwell/Cargo.toml index 1414eab3f8..c27c956bf8 100644 --- a/deepwell/Cargo.toml +++ b/deepwell/Cargo.toml @@ -60,7 +60,7 @@ strum = "0.26" strum_macros = "0.26" subtle = "2.6" thiserror = "1" -time = { version = "0.3", features = ["parsing", "serde", "serde-human-readable"], default-features = false } +time = { version = "0.3", features = ["parsing", "serde"], default-features = false } tiny-keccak = { version = "2", features = ["k12"] } toml = { version = "0.8", features = ["parse"] } tokio = { version = "1", features = ["full"] } diff --git a/deepwell/src/api.rs b/deepwell/src/api.rs index 19606bf5fa..d658f4487a 100644 --- a/deepwell/src/api.rs +++ b/deepwell/src/api.rs @@ -29,8 +29,8 @@ use crate::config::{Config, Secrets}; use crate::endpoints::{ auth::*, blob::*, category::*, domain::*, email::*, file::*, file_revision::*, - link::*, locale::*, message::*, misc::*, page::*, page_revision::*, parent::*, - site::*, site_member::*, text::*, user::*, user_bot::*, view::*, vote::*, + info::*, link::*, locale::*, message::*, misc::*, page::*, page_revision::*, + parent::*, site::*, site_member::*, text::*, user::*, user_bot::*, view::*, vote::*, }; use crate::locales::Localizations; use crate::services::blob::MimeAnalyzer; @@ -176,13 +176,12 @@ async fn build_module(app_state: ServerState) -> anyhow::Result. + */ + +//! Endpoints associated with getting DEEPWELL daemon information. + +use super::prelude::*; +use crate::info; +use crate::utils::now; +use std::path::PathBuf; +use time::OffsetDateTime; + +#[derive(Serialize, Debug, Clone)] +pub struct Info { + package: PackageInfo, + compile_info: CompileInfo, + + #[serde(with = "time::serde::rfc3339")] + current_time: OffsetDateTime, + hostname: &'static str, + config_path: PathBuf, +} + +#[derive(Serialize, Debug, Clone)] +pub struct PackageInfo { + name: &'static str, + description: &'static str, + license: &'static str, + repository: &'static str, + version: &'static str, +} + +#[derive(Serialize, Debug, Clone)] +pub struct CompileInfo { + #[serde(with = "time::serde::rfc3339")] + built_at: OffsetDateTime, + rustc_version: &'static str, + endian: &'static str, + target: &'static str, + threads: u32, + git_commit: Option<&'static str>, +} + +pub async fn server_info( + ctx: &ServiceContext<'_>, + _params: Params<'static>, +) -> Result { + let config = ctx.config(); + + info!("Building server information response"); + Ok(Info { + package: PackageInfo { + name: info::PKG_NAME, + version: &info::VERSION_INFO, + description: info::PKG_DESCRIPTION, + license: info::PKG_LICENSE, + repository: info::PKG_REPOSITORY, + }, + compile_info: CompileInfo { + built_at: *info::BUILT_TIME_UTC, + rustc_version: info::RUSTC_VERSION, + endian: info::CFG_ENDIAN, + target: info::TARGET, + threads: info::NUM_JOBS, + git_commit: info::GIT_COMMIT_HASH, + }, + config_path: config.raw_toml_path.clone(), + hostname: &info::HOSTNAME, + current_time: now(), + }) +} diff --git a/deepwell/src/endpoints/misc.rs b/deepwell/src/endpoints/misc.rs index adf2405e2d..972eb617aa 100644 --- a/deepwell/src/endpoints/misc.rs +++ b/deepwell/src/endpoints/misc.rs @@ -19,10 +19,8 @@ */ use super::prelude::*; -use crate::info; use sea_orm::{ConnectionTrait, DatabaseBackend, Statement}; use serde_json::Value as JsonValue; -use std::path::PathBuf; use wikidot_normalize::normalize; async fn postgres_check(ctx: &ServiceContext<'_>) -> Result<()> { @@ -78,30 +76,6 @@ pub async fn yield_error( Err(ServiceError::BadRequest) } -pub async fn version( - _ctx: &ServiceContext<'_>, - _params: Params<'static>, -) -> Result<&'static str> { - info!("Getting DEEPWELL version"); - Ok(info::VERSION.as_str()) -} - -pub async fn full_version( - _ctx: &ServiceContext<'_>, - _params: Params<'static>, -) -> Result<&'static str> { - info!("Getting DEEPWELL version (full)"); - Ok(info::FULL_VERSION.as_str()) -} - -pub async fn hostname( - _ctx: &ServiceContext<'_>, - _params: Params<'static>, -) -> Result<&'static str> { - info!("Getting DEEPWELL hostname"); - Ok(info::HOSTNAME.as_str()) -} - pub async fn config_dump( ctx: &ServiceContext<'_>, _params: Params<'static>, @@ -110,14 +84,6 @@ pub async fn config_dump( Ok(ctx.config().raw_toml.to_string()) } -pub async fn config_path( - ctx: &ServiceContext<'_>, - _params: Params<'static>, -) -> Result { - info!("Dumping DEEPWELL configuration path for debugging"); - Ok(ctx.config().raw_toml_path.to_path_buf()) -} - pub async fn normalize_method( _ctx: &ServiceContext<'_>, params: Params<'static>, diff --git a/deepwell/src/endpoints/mod.rs b/deepwell/src/endpoints/mod.rs index f634062214..684b848967 100644 --- a/deepwell/src/endpoints/mod.rs +++ b/deepwell/src/endpoints/mod.rs @@ -49,6 +49,7 @@ pub mod domain; pub mod email; pub mod file; pub mod file_revision; +pub mod info; pub mod link; pub mod locale; pub mod message; diff --git a/deepwell/src/info.rs b/deepwell/src/info.rs index fdd18ec9f8..4bf08cbba1 100644 --- a/deepwell/src/info.rs +++ b/deepwell/src/info.rs @@ -23,13 +23,21 @@ mod build { } use once_cell::sync::Lazy; +use time::format_description::well_known::Rfc2822; +use time::OffsetDateTime; #[allow(unused_imports)] pub use self::build::{ - BUILT_TIME_UTC, GIT_COMMIT_HASH, NUM_JOBS, PKG_AUTHORS, PKG_DESCRIPTION, PKG_LICENSE, - PKG_NAME, PKG_REPOSITORY, PKG_VERSION, RUSTC_VERSION, TARGET, + BUILT_TIME_UTC as BUILT_TIME_UTC_STR, CFG_ENDIAN, GIT_COMMIT_HASH, NUM_JOBS, + PKG_AUTHORS, PKG_DESCRIPTION, PKG_LICENSE, PKG_NAME, PKG_REPOSITORY, PKG_VERSION, + RUSTC_VERSION, TARGET, }; +pub static BUILT_TIME_UTC: Lazy = Lazy::new(|| { + OffsetDateTime::parse(BUILT_TIME_UTC_STR, &Rfc2822) + .expect("Unable to parse built time string") +}); + pub static VERSION_INFO: Lazy = Lazy::new(|| { let mut version = format!("v{PKG_VERSION}"); @@ -40,19 +48,20 @@ pub static VERSION_INFO: Lazy = Lazy::new(|| { version }); -pub static FULL_VERSION: Lazy = Lazy::new(|| { - let mut version = format!("{PKG_NAME} {}\n\nCompiled:\n", *VERSION_INFO); - - str_writeln!(&mut version, "* across {NUM_JOBS} threads"); - str_writeln!(&mut version, "* by {RUSTC_VERSION}"); - str_writeln!(&mut version, "* for {TARGET}"); - str_writeln!(&mut version, "* on {BUILT_TIME_UTC}"); - - version +pub static COMPILE_INFO: Lazy = Lazy::new(|| { + let mut info = str!("Compile info:\n"); + str_writeln!(&mut info, "* on {BUILT_TIME_UTC_STR}"); + str_writeln!(&mut info, "* by {RUSTC_VERSION}"); + str_writeln!(&mut info, "* for {TARGET}"); + str_writeln!(&mut info, "* across {NUM_JOBS} threads"); + info }); pub static VERSION: Lazy = Lazy::new(|| format!("{PKG_NAME} {}", *VERSION_INFO)); +pub static FULL_VERSION: Lazy = + Lazy::new(|| format!("{}\n\n{}", *VERSION, *COMPILE_INFO)); + pub static GIT_COMMIT_HASH_SHORT: Lazy> = Lazy::new(|| build::GIT_COMMIT_HASH.map(|s| &s[..8])); diff --git a/deepwell/src/models/alias.rs b/deepwell/src/models/alias.rs index 3b489bfbb4..f502b823c1 100644 --- a/deepwell/src/models/alias.rs +++ b/deepwell/src/models/alias.rs @@ -10,6 +10,7 @@ pub struct Model { #[sea_orm(primary_key)] pub alias_id: i64, pub alias_type: AliasType, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, pub created_by: i64, pub target_id: i64, diff --git a/deepwell/src/models/blob_pending.rs b/deepwell/src/models/blob_pending.rs index 8cd96e2abf..5f89133319 100644 --- a/deepwell/src/models/blob_pending.rs +++ b/deepwell/src/models/blob_pending.rs @@ -9,7 +9,9 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub external_id: String, pub created_by: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339")] pub expires_at: TimeDateTimeWithTimeZone, pub expected_length: i64, #[sea_orm(column_type = "Text")] diff --git a/deepwell/src/models/file.rs b/deepwell/src/models/file.rs index ce05ac6f77..7421debd7b 100644 --- a/deepwell/src/models/file.rs +++ b/deepwell/src/models/file.rs @@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub file_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, pub from_wikidot: bool, #[sea_orm(column_type = "Text")] diff --git a/deepwell/src/models/file_revision.rs b/deepwell/src/models/file_revision.rs index b5250d6ea9..989483d82d 100644 --- a/deepwell/src/models/file_revision.rs +++ b/deepwell/src/models/file_revision.rs @@ -10,6 +10,7 @@ pub struct Model { #[sea_orm(primary_key)] pub revision_id: i64, pub revision_type: FileRevisionType, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, pub revision_number: i32, pub file_id: i64, diff --git a/deepwell/src/models/filter.rs b/deepwell/src/models/filter.rs index a62e24e527..e07cb1a3a8 100644 --- a/deepwell/src/models/filter.rs +++ b/deepwell/src/models/filter.rs @@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub filter_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, pub site_id: Option, pub affects_user: bool, diff --git a/deepwell/src/models/message_draft.rs b/deepwell/src/models/message_draft.rs index 2c2053e820..2a0baed73d 100644 --- a/deepwell/src/models/message_draft.rs +++ b/deepwell/src/models/message_draft.rs @@ -8,7 +8,9 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub external_id: String, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub user_id: i64, pub recipients: Json, @@ -18,6 +20,7 @@ pub struct Model { pub wikitext_hash: Vec, #[sea_orm(column_type = "VarBinary(StringLen::None)")] pub compiled_hash: Vec, + #[serde(with = "time::serde::rfc3339")] pub compiled_at: TimeDateTimeWithTimeZone, #[sea_orm(column_type = "Text")] pub compiled_generator: String, diff --git a/deepwell/src/models/message_record.rs b/deepwell/src/models/message_record.rs index 0d07530b06..9301f3000f 100644 --- a/deepwell/src/models/message_record.rs +++ b/deepwell/src/models/message_record.rs @@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub external_id: String, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339")] pub drafted_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub retracted_at: Option, pub sender_id: i64, #[sea_orm(column_type = "Text")] @@ -18,6 +21,7 @@ pub struct Model { pub wikitext_hash: Vec, #[sea_orm(column_type = "VarBinary(StringLen::None)")] pub compiled_hash: Vec, + #[serde(with = "time::serde::rfc3339")] pub compiled_at: TimeDateTimeWithTimeZone, #[sea_orm(column_type = "Text")] pub compiled_generator: String, diff --git a/deepwell/src/models/message_report.rs b/deepwell/src/models/message_report.rs index e1fc267014..60cf76eb5e 100644 --- a/deepwell/src/models/message_report.rs +++ b/deepwell/src/models/message_report.rs @@ -10,7 +10,9 @@ pub struct Model { pub message_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub reported_to_site_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, #[sea_orm(column_type = "Text")] pub reason: String, diff --git a/deepwell/src/models/page.rs b/deepwell/src/models/page.rs index ab0450e1dd..3d0070c2de 100644 --- a/deepwell/src/models/page.rs +++ b/deepwell/src/models/page.rs @@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub page_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, pub from_wikidot: bool, pub site_id: i64, diff --git a/deepwell/src/models/page_attribution.rs b/deepwell/src/models/page_attribution.rs index 47c70f1f40..e61c689dba 100644 --- a/deepwell/src/models/page_attribution.rs +++ b/deepwell/src/models/page_attribution.rs @@ -14,6 +14,7 @@ pub struct Model { pub attribution_type: String, #[sea_orm(primary_key, auto_increment = false)] pub attribution_date: TimeDate, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, } diff --git a/deepwell/src/models/page_category.rs b/deepwell/src/models/page_category.rs index b0c826dfe9..97c919c7c2 100644 --- a/deepwell/src/models/page_category.rs +++ b/deepwell/src/models/page_category.rs @@ -8,7 +8,9 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub category_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub site_id: i64, #[sea_orm(column_type = "Text")] diff --git a/deepwell/src/models/page_connection.rs b/deepwell/src/models/page_connection.rs index b95b82cad1..4c3887731e 100644 --- a/deepwell/src/models/page_connection.rs +++ b/deepwell/src/models/page_connection.rs @@ -12,7 +12,9 @@ pub struct Model { pub to_page_id: i64, #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub connection_type: String, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub count: i32, } diff --git a/deepwell/src/models/page_connection_missing.rs b/deepwell/src/models/page_connection_missing.rs index 119a3ae420..b931adeb0a 100644 --- a/deepwell/src/models/page_connection_missing.rs +++ b/deepwell/src/models/page_connection_missing.rs @@ -14,7 +14,9 @@ pub struct Model { pub to_page_slug: String, #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub connection_type: String, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub count: i32, } diff --git a/deepwell/src/models/page_link.rs b/deepwell/src/models/page_link.rs index 128499e77f..31c5436838 100644 --- a/deepwell/src/models/page_link.rs +++ b/deepwell/src/models/page_link.rs @@ -10,7 +10,9 @@ pub struct Model { pub page_id: i64, #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub url: String, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub count: i32, } diff --git a/deepwell/src/models/page_lock.rs b/deepwell/src/models/page_lock.rs index 4304700d34..d0350a191f 100644 --- a/deepwell/src/models/page_lock.rs +++ b/deepwell/src/models/page_lock.rs @@ -8,9 +8,13 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub page_lock_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub expires_at: Option, pub from_wikidot: bool, #[sea_orm(column_type = "Text")] diff --git a/deepwell/src/models/page_parent.rs b/deepwell/src/models/page_parent.rs index 0401235949..13a6cb9df2 100644 --- a/deepwell/src/models/page_parent.rs +++ b/deepwell/src/models/page_parent.rs @@ -10,6 +10,7 @@ pub struct Model { pub parent_page_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub child_page_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, } diff --git a/deepwell/src/models/page_revision.rs b/deepwell/src/models/page_revision.rs index 28a0aa3725..686c3a0350 100644 --- a/deepwell/src/models/page_revision.rs +++ b/deepwell/src/models/page_revision.rs @@ -10,7 +10,9 @@ pub struct Model { #[sea_orm(primary_key)] pub revision_id: i64, pub revision_type: PageRevisionType, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub revision_number: i32, pub page_id: i64, @@ -22,6 +24,7 @@ pub struct Model { pub wikitext_hash: Vec, #[sea_orm(column_type = "VarBinary(StringLen::None)")] pub compiled_hash: Vec, + #[serde(with = "time::serde::rfc3339")] pub compiled_at: TimeDateTimeWithTimeZone, #[sea_orm(column_type = "Text")] pub compiled_generator: String, diff --git a/deepwell/src/models/page_vote.rs b/deepwell/src/models/page_vote.rs index 9355247c31..5bf86256b2 100644 --- a/deepwell/src/models/page_vote.rs +++ b/deepwell/src/models/page_vote.rs @@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub page_vote_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub disabled_at: Option, pub disabled_by: Option, pub from_wikidot: bool, diff --git a/deepwell/src/models/relation.rs b/deepwell/src/models/relation.rs index 325c733902..f7a00e80bb 100644 --- a/deepwell/src/models/relation.rs +++ b/deepwell/src/models/relation.rs @@ -17,10 +17,13 @@ pub struct Model { pub from_id: i64, pub metadata: Json, pub created_by: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, pub overwritten_by: Option, + #[serde(with = "time::serde::rfc3339::option")] pub overwritten_at: Option, pub deleted_by: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, } diff --git a/deepwell/src/models/session.rs b/deepwell/src/models/session.rs index 613573bdac..c061dab585 100644 --- a/deepwell/src/models/session.rs +++ b/deepwell/src/models/session.rs @@ -9,7 +9,9 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub session_token: String, pub user_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339")] pub expires_at: TimeDateTimeWithTimeZone, #[sea_orm(column_type = "Text")] pub ip_address: String, diff --git a/deepwell/src/models/site.rs b/deepwell/src/models/site.rs index 1e818e0865..19e3787eeb 100644 --- a/deepwell/src/models/site.rs +++ b/deepwell/src/models/site.rs @@ -8,8 +8,11 @@ use serde::{Deserialize, Serialize}; pub struct Model { #[sea_orm(primary_key)] pub site_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, pub from_wikidot: bool, #[sea_orm(column_type = "Text")] diff --git a/deepwell/src/models/site_domain.rs b/deepwell/src/models/site_domain.rs index c1851b6e04..5efc3e1f35 100644 --- a/deepwell/src/models/site_domain.rs +++ b/deepwell/src/models/site_domain.rs @@ -9,6 +9,7 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false, column_type = "Text")] pub domain: String, pub site_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, } diff --git a/deepwell/src/models/user.rs b/deepwell/src/models/user.rs index a985950552..6133d205c4 100644 --- a/deepwell/src/models/user.rs +++ b/deepwell/src/models/user.rs @@ -10,8 +10,11 @@ pub struct Model { #[sea_orm(primary_key)] pub user_id: i64, pub user_type: UserType, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, + #[serde(with = "time::serde::rfc3339::option")] pub deleted_at: Option, pub from_wikidot: bool, #[sea_orm(column_type = "Text")] @@ -19,11 +22,14 @@ pub struct Model { #[sea_orm(column_type = "Text")] pub slug: String, pub name_changes_left: i16, + #[serde(with = "time::serde::rfc3339")] pub last_name_change_added_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub last_renamed_at: Option, #[sea_orm(column_type = "Text")] pub email: String, pub email_is_alias: Option, + #[serde(with = "time::serde::rfc3339::option")] pub email_verified_at: Option, #[sea_orm(column_type = "Text")] pub password: String, diff --git a/deepwell/src/models/user_bot_owner.rs b/deepwell/src/models/user_bot_owner.rs index b5bc1cc88a..d58021d290 100644 --- a/deepwell/src/models/user_bot_owner.rs +++ b/deepwell/src/models/user_bot_owner.rs @@ -10,7 +10,9 @@ pub struct Model { pub bot_user_id: i64, #[sea_orm(primary_key, auto_increment = false)] pub human_user_id: i64, + #[serde(with = "time::serde::rfc3339")] pub created_at: TimeDateTimeWithTimeZone, + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, #[sea_orm(column_type = "Text")] pub description: String, diff --git a/deepwell/src/services/blob/structs.rs b/deepwell/src/services/blob/structs.rs index 1ff7176ee9..e1b6a8ea7b 100644 --- a/deepwell/src/services/blob/structs.rs +++ b/deepwell/src/services/blob/structs.rs @@ -31,6 +31,8 @@ pub struct StartBlobUpload { pub struct StartBlobUploadOutput { pub pending_blob_id: String, pub presign_url: String, + + #[serde(with = "time::serde::rfc3339")] pub expires_at: OffsetDateTime, } @@ -60,5 +62,7 @@ pub struct GetBlobOutput { pub data: Vec, pub mime: String, pub size: i64, + + #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, } diff --git a/deepwell/src/services/file/structs.rs b/deepwell/src/services/file/structs.rs index 1913b0f34e..22d177283a 100644 --- a/deepwell/src/services/file/structs.rs +++ b/deepwell/src/services/file/structs.rs @@ -61,12 +61,20 @@ pub struct GetFileDetails<'a> { #[derive(Serialize, Debug, Clone)] pub struct GetFileOutput { pub file_id: i64, + + #[serde(with = "time::serde::rfc3339")] pub file_created_at: OffsetDateTime, + + #[serde(with = "time::serde::rfc3339::option")] pub file_updated_at: Option, + + #[serde(with = "time::serde::rfc3339::option")] pub file_deleted_at: Option, pub page_id: i64, pub revision_id: i64, pub revision_type: FileRevisionType, + + #[serde(with = "time::serde::rfc3339")] pub revision_created_at: OffsetDateTime, pub revision_number: i32, pub revision_user_id: i64, diff --git a/deepwell/src/services/import/structs.rs b/deepwell/src/services/import/structs.rs index 01c15b622e..29fea78dbd 100644 --- a/deepwell/src/services/import/structs.rs +++ b/deepwell/src/services/import/structs.rs @@ -23,6 +23,8 @@ use time::{Date, OffsetDateTime}; #[derive(Deserialize, Debug)] pub struct ImportUser { pub user_id: i64, + + #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, pub name: String, pub slug: String, @@ -40,6 +42,8 @@ pub struct ImportUser { #[derive(Deserialize, Debug)] pub struct ImportSite { pub site_id: i64, + + #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, pub name: String, pub slug: String, @@ -50,6 +54,8 @@ pub struct ImportSite { pub struct ImportPage { pub page_id: i64, pub site_id: i64, + + #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, pub slug: String, pub locked: bool, diff --git a/deepwell/src/services/link/structs.rs b/deepwell/src/services/link/structs.rs index 8878f0f346..31db6ad145 100644 --- a/deepwell/src/services/link/structs.rs +++ b/deepwell/src/services/link/structs.rs @@ -89,7 +89,10 @@ pub struct GetLinksExternalToOutput { #[derive(Serialize, Debug, Clone)] pub struct ToExternalLink { + #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, + + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub page_id: i64, pub count: i32, diff --git a/deepwell/src/services/page/structs.rs b/deepwell/src/services/page/structs.rs index 372ca50bfc..ac666f029e 100644 --- a/deepwell/src/services/page/structs.rs +++ b/deepwell/src/services/page/structs.rs @@ -92,8 +92,14 @@ pub struct GetPageAnyDetails { #[derive(Serialize, Debug, Clone)] pub struct GetPageOutput { pub page_id: i64, + + #[serde(with = "time::serde::rfc3339")] pub page_created_at: OffsetDateTime, + + #[serde(with = "time::serde::rfc3339::option")] pub page_updated_at: Option, + + #[serde(with = "time::serde::rfc3339::option")] pub page_deleted_at: Option, pub page_revision_count: i32, pub site_id: i64, @@ -102,11 +108,15 @@ pub struct GetPageOutput { pub discussion_thread_id: Option, pub revision_id: i64, pub revision_type: PageRevisionType, + + #[serde(with = "time::serde::rfc3339")] pub revision_created_at: OffsetDateTime, pub revision_number: i32, pub revision_user_id: i64, pub wikitext: Option, pub compiled_html: Option, + + #[serde(with = "time::serde::rfc3339")] pub compiled_at: OffsetDateTime, pub compiled_generator: String, pub revision_comments: String, @@ -122,8 +132,12 @@ pub struct GetPageOutput { #[derive(Serialize, Debug, Clone)] pub struct GetDeletedPageOutput { pub page_id: i64, + + #[serde(with = "time::serde::rfc3339")] pub page_created_at: OffsetDateTime, pub page_updated_at: Option, + + #[serde(with = "time::serde::rfc3339")] pub page_deleted_at: OffsetDateTime, pub page_revision_count: i32, pub site_id: i64, diff --git a/deepwell/src/services/page_query/structs.rs b/deepwell/src/services/page_query/structs.rs index aa099b476b..2fc063eb46 100644 --- a/deepwell/src/services/page_query/structs.rs +++ b/deepwell/src/services/page_query/structs.rs @@ -18,6 +18,7 @@ * along with this program. If not, see . */ +// TODO: add serde, include time fmt conversions #![allow(dead_code)] // TEMP use super::prelude::*; diff --git a/deepwell/src/services/page_revision/structs.rs b/deepwell/src/services/page_revision/structs.rs index 4905cd8c74..b3d78f09f8 100644 --- a/deepwell/src/services/page_revision/structs.rs +++ b/deepwell/src/services/page_revision/structs.rs @@ -158,7 +158,11 @@ pub struct PageRevisionCountOutput { pub struct PageRevisionModelFiltered { pub revision_id: i64, pub revision_type: PageRevisionType, + + #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, + + #[serde(with = "time::serde::rfc3339::option")] pub updated_at: Option, pub from_wikidot: bool, pub revision_number: i32, @@ -168,6 +172,8 @@ pub struct PageRevisionModelFiltered { pub changes: Vec, pub wikitext: Option, pub compiled_html: Option, + + #[serde(with = "time::serde::rfc3339")] pub compiled_at: OffsetDateTime, pub compiled_generator: String, pub comments: Option, diff --git a/deepwell/src/services/render/structs.rs b/deepwell/src/services/render/structs.rs index 0d7c4e2a39..aee9ce19e9 100644 --- a/deepwell/src/services/render/structs.rs +++ b/deepwell/src/services/render/structs.rs @@ -27,6 +27,8 @@ pub struct RenderOutput { pub html_output: HtmlOutput, pub errors: Vec, pub compiled_hash: TextHash, + + #[serde(with = "time::serde::rfc3339")] pub compiled_at: OffsetDateTime, pub compiled_generator: String, } diff --git a/framerail/src/lib/server/load/page.ts b/framerail/src/lib/server/load/page.ts index 104d81b8b6..4a155dc404 100644 --- a/framerail/src/lib/server/load/page.ts +++ b/framerail/src/lib/server/load/page.ts @@ -3,7 +3,6 @@ import { parseAcceptLangHeader } from "$lib/locales" import { translate } from "$lib/server/deepwell/translate" import { pageView } from "$lib/server/deepwell/views" import type { Optional, TranslateKeys } from "$lib/types" -import { parseDateEpoch } from "$lib/utils" import { error, redirect } from "@sveltejs/kit" // TODO form single deepwell request that does all the relevant prep stuff here @@ -80,7 +79,7 @@ export async function loadPage( if (errorStatus === null) { // Calculate difference of days since latest page edit - let updatedAt = parseDateEpoch(viewData.page.updated_at ?? viewData.page.created_at) + let updatedAt = Date.parse(viewData.page.updated_at ?? viewData.page.created_at) let daysDiff = Math.floor((Date.now() - updatedAt) / 1000 / 86400) translateKeys = { diff --git a/framerail/src/lib/utils.ts b/framerail/src/lib/utils.ts deleted file mode 100644 index 43b8a4f9d8..0000000000 --- a/framerail/src/lib/utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Convenience function that converts date string format provided by - * Deepwell as `YYYY-MM-DD HH:MM:SS.SSSSSS +HH:MM:SS` into - * `YYYY-MM-DDTHH:mm:ss.sss+HH:mm` - */ -export function convertDateString(dateStr: string): string { - let dateParts = dateStr.split(" ") - let time = dateParts[1].split(".") - let subsec = time.length == 2 ? "." + time[1].slice(0, 3) : "" - let timezone = dateParts[2].split(":") - timezone.pop() - let output = `${dateParts[0]}T${time[0]}${subsec}${timezone.join(":")}` - return output -} - -/** - * Convenience function that converts date string format provided by - * Deepwell as `YYYY-MM-DD HH:MM:SS.SSSSSS +HH:MM:SS` into unix epoch - */ -export function parseDateEpoch(dateStr: string): number { - return Date.parse(convertDateString(dateStr)) -} - -/** - * Convenience function that converts date string format provided by - * Deepwell as `YYYY-MM-DD HH:MM:SS.SSSSSS +HH:MM:SS` into date object - */ -export function parseDate(dateStr: string): Date { - return new Date(convertDateString(dateStr)) -} diff --git a/framerail/src/routes/+error.svelte b/framerail/src/routes/+error.svelte index ab7b14311a..fe46f11485 100644 --- a/framerail/src/routes/+error.svelte +++ b/framerail/src/routes/+error.svelte @@ -3,7 +3,6 @@ import { goto, invalidateAll } from "$app/navigation" import { useErrorPopup } from "$lib/stores" import { Layout } from "$lib/types" - import { parseDate } from "$lib/utils" let showErrorPopup = useErrorPopup() let showRestoreAction = false @@ -181,7 +180,7 @@ as soon as we can figure out prettier support for it. >{(deletedPage.rating > 0 ? "+" : "") + deletedPage.rating}) - {$page.error.internationalization?.["wiki-page-deleted"].replace( "{$datetime}", - parseDate(deletedPage.page_deleted_at).toLocaleString() + new Date(deletedPage.page_deleted_at).toLocaleString() )}
diff --git a/framerail/src/routes/[slug]/[...extra]/page.svelte b/framerail/src/routes/[slug]/[...extra]/page.svelte index d7f248f9c2..4f5863cbbb 100644 --- a/framerail/src/routes/[slug]/[...extra]/page.svelte +++ b/framerail/src/routes/[slug]/[...extra]/page.svelte @@ -4,7 +4,6 @@ import { onMount } from "svelte" import { useErrorPopup } from "$lib/stores" import { Layout } from "$lib/types" - import { parseDate } from "$lib/utils" let showErrorPopup = useErrorPopup() let showMoveAction = false @@ -703,7 +702,7 @@ ]}
- {parseDate(revisionItem.created_at).toLocaleString()} + {new Date(revisionItem.created_at).toLocaleString()}
{revisionItem.user_id}