Merge pull request #34 from stevedylandev/fix/rss-date-formats
f7d10d49
fix: rss date formats
5 file(s) · +25 −7
fix: rss date formats
| 704 | 704 | "askama_web", |
|
| 705 | 705 | "axum", |
|
| 706 | 706 | "base64", |
|
| 707 | + | "chrono", |
|
| 707 | 708 | "dotenvy", |
|
| 708 | 709 | "image", |
|
| 709 | 710 | "nanoid", |
|
| 3154 | 3155 | "askama 0.15.6", |
|
| 3155 | 3156 | "askama_web", |
|
| 3156 | 3157 | "axum", |
|
| 3158 | + | "chrono", |
|
| 3157 | 3159 | "dotenvy", |
|
| 3158 | 3160 | "nanoid", |
|
| 3159 | 3161 | "pulldown-cmark", |
|
| 1 | 1 | [package] |
|
| 2 | 2 | name = "cellar" |
|
| 3 | - | version = "0.2.0" |
|
| 3 | + | version = "0.2.1" |
|
| 4 | 4 | edition = "2024" |
|
| 5 | 5 | description = "Personal wine tasting log" |
|
| 6 | 6 | license = "MIT" |
|
| 29 | 29 | base64 = "0.22" |
|
| 30 | 30 | image = "0.25" |
|
| 31 | 31 | serde_rusqlite = "0.41" |
|
| 32 | + | chrono = "0.4" |
|
| 114 | 114 | .replace('\'', "'") |
|
| 115 | 115 | } |
|
| 116 | 116 | ||
| 117 | + | fn to_rfc2822(sqlite_ts: &str) -> String { |
|
| 118 | + | chrono::NaiveDateTime::parse_from_str(sqlite_ts, "%Y-%m-%d %H:%M:%S") |
|
| 119 | + | .map(|naive| naive.and_utc().to_rfc2822()) |
|
| 120 | + | .unwrap_or_else(|_| sqlite_ts.to_string()) |
|
| 121 | + | } |
|
| 122 | + | ||
| 117 | 123 | pub async fn rss_feed(State(state): State<Arc<AppState>>) -> Response { |
|
| 118 | 124 | let site_url = &state.site_url; |
|
| 119 | 125 | ||
| 140 | 146 | desc_parts.push(wine.notes.clone()); |
|
| 141 | 147 | } |
|
| 142 | 148 | let description = xml_escape(&desc_parts.join(" — ")); |
|
| 143 | - | let pub_date = &wine.created_at; |
|
| 149 | + | let pub_date = to_rfc2822(&wine.created_at); |
|
| 144 | 150 | let guid = format!("{}/wines/{}", site_url, xml_escape(&wine.short_id)); |
|
| 145 | 151 | ||
| 146 | 152 | items.push_str(&format!( |
|
| 150 | 156 | ||
| 151 | 157 | let last_build = wines |
|
| 152 | 158 | .first() |
|
| 153 | - | .map(|w| w.created_at.as_str()) |
|
| 154 | - | .unwrap_or(""); |
|
| 159 | + | .map(|w| to_rfc2822(&w.created_at)) |
|
| 160 | + | .unwrap_or_default(); |
|
| 155 | 161 | ||
| 156 | 162 | let xml = format!( |
|
| 157 | 163 | r#"<?xml version="1.0" encoding="UTF-8"?> |
|
| 1 | 1 | [package] |
|
| 2 | 2 | name = "posts" |
|
| 3 | - | version = "0.1.4" |
|
| 3 | + | version = "0.1.5" |
|
| 4 | 4 | edition = "2024" |
|
| 5 | 5 | description = "CMS blog with admin interface" |
|
| 6 | 6 | license = "MIT" |
|
| 27 | 27 | askama = "0.15" |
|
| 28 | 28 | askama_web = { version = "0.15", features = ["axum-0.8"] } |
|
| 29 | 29 | pulldown-cmark = "0.12" |
|
| 30 | + | chrono = "0.4" |
|
| 30 | 31 | zip = { workspace = true } |
|
| 193 | 193 | .replace('\'', "'") |
|
| 194 | 194 | } |
|
| 195 | 195 | ||
| 196 | + | fn to_rfc2822(sqlite_ts: &str) -> String { |
|
| 197 | + | chrono::NaiveDateTime::parse_from_str(sqlite_ts, "%Y-%m-%d %H:%M:%S") |
|
| 198 | + | .map(|naive| naive.and_utc().to_rfc2822()) |
|
| 199 | + | .unwrap_or_else(|_| sqlite_ts.to_string()) |
|
| 200 | + | } |
|
| 201 | + | ||
| 196 | 202 | pub async fn rss_feed(State(state): State<Arc<AppState>>) -> Response { |
|
| 197 | 203 | let blog_title = get_blog_title(&state.db); |
|
| 198 | 204 | let blog_description = get_setting_or_default(&state.db, "blog_description"); |
|
| 217 | 223 | xml_escape(&plain) |
|
| 218 | 224 | } |
|
| 219 | 225 | }; |
|
| 220 | - | let pub_date = post.published_date.as_deref().unwrap_or(&post.created_at); |
|
| 226 | + | let raw_date = post.published_date.as_deref().unwrap_or(&post.created_at); |
|
| 227 | + | let pub_date = to_rfc2822(raw_date); |
|
| 221 | 228 | let guid = format!("{}/posts/{}", site_url, xml_escape(&post.slug)); |
|
| 222 | 229 | ||
| 223 | 230 | items.push_str(&format!( |
|
| 228 | 235 | let last_build = posts |
|
| 229 | 236 | .first() |
|
| 230 | 237 | .and_then(|p| p.published_date.as_deref()) |
|
| 231 | - | .unwrap_or(""); |
|
| 238 | + | .map(to_rfc2822) |
|
| 239 | + | .unwrap_or_default(); |
|
| 232 | 240 | ||
| 233 | 241 | let xml = format!( |
|
| 234 | 242 | r#"<?xml version="1.0" encoding="UTF-8"?> |
|