Mercurial > lbo > hg > geohub
changeset 4:5a0ac0fe8fb6
Implement robust timestamp parsing
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 01 Dec 2020 20:03:31 +0100 |
parents | 3586f77a0142 |
children | b879b0124a07 |
files | TODO src/main.rs |
diffstat | 2 files changed, 43 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/TODO Tue Dec 01 19:07:32 2020 +0100 +++ b/TODO Tue Dec 01 20:03:31 2020 +0100 @@ -1,6 +1,3 @@ -* move table into schema -* use ids for geo records -* ids only alphanumeric * notify via dynamic channels? static channels? polling? * deploy first version
--- a/src/main.rs Tue Dec 01 19:07:32 2020 +0100 +++ b/src/main.rs Tue Dec 01 20:03:31 2020 +0100 @@ -8,20 +8,54 @@ #[rocket_contrib::database("geohub")] struct DBConn(postgres::Connection); +/// Parse timestamps flexibly. Without any zone information, UTC is assumed. +fn flexible_timestamp_parse(ts: String) -> Option<chrono::DateTime<chrono::Utc>> { + let fmtstrings = &[ + "%Y-%m-%dT%H:%M:%S%.f%:z", + "%Y-%m-%dT%H:%M:%S%.fZ", + "%Y-%m-%d %H:%M:%S%.f", + ]; + for fs in fmtstrings { + println!("{} {}", fs, ts); + let (naive, withtz) = ( + chrono::NaiveDateTime::parse_from_str(ts.as_str(), fs).ok(), + chrono::DateTime::parse_from_str(ts.as_str(), fs).ok(), + ); + if let Some(p) = withtz { + println!("tz: {:?}", p); + return Some(p.with_timezone(&chrono::Utc)); + } + if let Some(p) = naive { + println!("naive: {:?}", p); + let utcd = chrono::Utc.from_utc_datetime(&p); + return Some(utcd); + } + } + None +} + /// lat, long are floats /// time is like 2020-11-30T20:12:36.444Z (ISO 8601) -#[rocket::get("/geo/<name>/log?<lat>&<longitude>&<time>&<s>")] -fn hello(db: DBConn, name: String, lat: f64, longitude: f64, time: String, s: f64) -> &'static str { - let ts = chrono::NaiveDateTime::parse_from_str(time.as_str(), "%Y-%m-%dT%H:%M:%S%.fZ") - .ok() - .map(|t| chrono::Utc::now().timezone().from_utc_datetime(&t)); - println!("{:?}", ts); +#[rocket::get("/geo/<name>/log?<lat>&<longitude>&<time>&<s>&<ele>")] +fn hello( + db: DBConn, + name: String, + lat: f64, + longitude: f64, + time: String, + s: f64, + ele: Option<f64>, +) -> rocket::http::Status { + if name.chars().any(|c| !c.is_alphanumeric()) { + return rocket::http::Status::NotAcceptable; + } + let ts = flexible_timestamp_parse(time); db.0.execute( - "INSERT INTO geohub.geodata (id, lat, long, spd, t) VALUES ($1, $2, $3, $4, $5)", - &[&name, &lat, &longitude, &s, &ts], + "INSERT INTO geohub.geodata (id, lat, long, spd, t, ele) VALUES ($1, $2, $3, $4, $5, $6)", + &[&name, &lat, &longitude, &s, &ts, &ele], ) .unwrap(); - "OK" + rocket::http::Status::Ok } fn main() {