Copy turns Atom generator
Dependencies
- [2]
3HT5CE6SManage TTL duration in config - [3]
WW3KRXX6Add page for reset game password - [4]
IM5ZPD4NUpdate dependencies - [5]
7R6HAATPOptional publish static files if use reverse-proxy - [6]
BCXEUKX6Add config, static files and web server - [7]
HTYEGVBUAdd data to reset password page - [8]
WVHXYKCVAdd postgresql pools - [*]
EVP2FSBHSplit index page - [*]
4MZ4VIR7Initial commit - [*]
65A3LIWUUse handlebars to render index - [*]
ZE5UFPX4Add TTL cache for CSRF - [*]
QEK76JYTProcess and log template render error
Change contents
- edit in src/pages/mod.rs at line 6
pub mod atom_turns; - edit in src/pages/mod.rs at line 16
pub base_url: String, - file addition: atom_turns.rs[10.17]
use crate::WebData;use actix_web::{web, HttpResponse};#[derive(serde_derive::Serialize)]struct FeedData {gameuid: String,gameuidenc: String,upddatetime: String,entries: Vec<EntriesData>,selflink: String,}#[derive(serde_derive::Serialize)]struct EntriesData {new: bool,turn: i32,turn_ts_str: String,turn_ts: i64,}#[actix_web::get("/atoms/{path}.xml")]pub async fn atom_turns(path: web::Path<String>, data: web::Data<WebData<'_>>) -> HttpResponse {let gameuid = path.into_inner();let gameuid = match gameuid.char_indices().nth(128) {None => gameuid,Some((idx, _)) => (&gameuid[..idx]).to_string(),};let dbclient = match data.pool_ro.get().await {Ok(client) => client,Err(e) => {log::error!("{}", e);return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());}};let stmt = match dbclient.prepare("select g.game_uid, t.turn, t.turn_ts from games.games g left join games.turns t on t.game_uid = g.game_uid where g.game_uid = $1 order by t.turn_ts desc limit 50;").await {Ok(stmt) => stmt,Err(e) => {log::error!("{}", e);return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());}};let rows = match dbclient.query(&stmt, &[&gameuid]).await {Ok(rows) => rows,Err(e) => {log::error!("{}", e);return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());}};if rows.is_empty() {log::info!("Empty data for {}", gameuid);return HttpResponse::NotFound().body(actix_web::body::None::new());}let mut upd_date_time = None;let mut entries = Vec::with_capacity(rows.len());for row in rows {if let Some(turn) = row.get::<_, Option<i32>>(1) {if let Some(turn_ts) = row.get::<_, Option<chrono::NaiveDateTime>>(2) {let entry_ts = chrono::DateTime::from_utc(turn_ts, chrono::Utc);entries.insert(0,EntriesData {new: turn <= 0,turn,turn_ts_str: entry_ts.to_rfc3339_opts(chrono::SecondsFormat::Secs, true),turn_ts: entry_ts.timestamp(),},);upd_date_time.get_or_insert(entry_ts);}}}let upd_date_time = upd_date_time.unwrap_or_else(chrono::Utc::now);let body = match data.handlebars.render("turns",&FeedData {gameuid: gameuid.to_string(),gameuidenc: pct_str::PctString::encode(gameuid.chars(), pct_str::URIReserved).into_string(),entries,upddatetime: upd_date_time.to_rfc3339_opts(chrono::SecondsFormat::Secs, true),selflink: data.base_url.to_string(),},) {Ok(b) => b,Err(e) => {log::error!("{}", e);return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());}};HttpResponse::Ok().insert_header(("Content-Type", "application/atom+xml")).insert_header(("Date",upd_date_time.format("%a, %d %b %Y %H:%M:%S GMT").to_string(),)).body(body)} - edit in src/main.rs at line 12
use pages::atom_turns::atom_turns; - edit in src/main.rs at line 44
base_url, - edit in src/main.rs at line 87
handlebars.register_template_string("atom-games", include_str!("templates/games.xml")).expect("atom games template");handlebars.register_template_string("atom-turns", include_str!("templates/turns.xml")).expect("atom games template"); - edit in src/main.rs at line 99
base_url, - replacement in src/main.rs at line 117
.service(post_reset_game_pwd);.service(post_reset_game_pwd).service(atom_turns); - edit in src/config.rs at line 15
pub base_url: String, - edit in Cargo.toml at line 24
chrono = "0.4"pct-str = "1.1" - replacement in Cargo.toml at line 33
features = ["with-uuid-0_8"]features = ["with-uuid-0_8", "with-chrono-0_4"] - replacement in Cargo.lock at line 191
"time","time 0.3.7", - edit in Cargo.lock at line 386
[[package]]name = "chrono"version = "0.4.19"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"dependencies = ["libc","num-integer","num-traits","time 0.1.43","winapi",] - replacement in Cargo.lock at line 428
"time","time 0.3.7", - edit in Cargo.lock at line 600
"chrono", - edit in Cargo.lock at line 606[14.537][3.20518]
"pct-str", - edit in Cargo.lock at line 1030
name = "num-integer"version = "0.1.44"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"dependencies = ["autocfg","num-traits",][[package]]name = "num-traits"version = "0.2.14"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"dependencies = ["autocfg",][[package]] - edit in Cargo.lock at line 1120
name = "pct-str"version = "1.1.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "1240e3e7bfdde5660ba0fc3e9e3565d3b30c2ae1973e218e93b869da771ff2e9"[[package]] - edit in Cargo.lock at line 1229
"chrono", - edit in Cargo.lock at line 1522
version = "0.1.43"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"dependencies = ["libc","winapi",][[package]]name = "time"