diff --git a/src/main.rs b/src/main.rs index 9606824..2b8ec99 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::sync::{Mutex, RwLock}; use std::collections::VecDeque; use rustorm::{pool::Pool, DbError}; use chrono::offset::Utc; +use reqwest::header::{IF_NONE_MATCH, IF_MODIFIED_SINCE, ETAG, LAST_MODIFIED, USER_AGENT}; mod config; use config::{Config, CalendarOptions}; @@ -46,22 +47,57 @@ impl Resources { Some(next) => next, None => return Ok(()), }; - let tx = self.transaction()?; - let cal: Option = - tx.query("SELECT * FROM calendar WHERE id=$1", &[&id])?; - if cal.is_none() { - tx.insert(&[&new::Calendar { - id: id.clone(), - url: cal_opts.url.clone(), - last_fetch: Utc::now(), - }])?; - } else { - tx.exec("UPDATE calendar SET last_fetch=$2 WHERE id=$1", &[&id, &"NOW()"])?; + let (etag, last_modified) = { + let tx = self.transaction()?; + let cal: Option = + tx.query("SELECT * FROM calendar WHERE id=$1", &[&id])?; + let result = match cal { + None => { + tx.insert(&[&new::Calendar { + id: id.clone(), + url: cal_opts.url.clone(), + last_fetch: Utc::now(), + }])?; + (None, None) + } + Some(cal) => { + tx.exec("UPDATE calendar SET last_fetch=$2 WHERE id=$1", &[&id, &Utc::now()])?; + (cal.etag, cal.last_modified) + } + }; + tx.commit()?; + result + }; + + let mut req = self.http_client.get(&cal_opts.url) + .header(USER_AGENT, "Ticker/0.0.0"); + match etag { + Some(etag) => req = req.header(IF_NONE_MATCH, etag), + None => (), + } + match last_modified { + Some(last_modified) => req = req.header(IF_MODIFIED_SINCE, last_modified), + None => (), + } + let mut res = req.send()?; + + println!("{} {}", res.status(), cal_opts.url); + if res.status() != 200 { + let tx = self.transaction()?; + let msg = format!("HTTP {}", res.status()); + tx.exec("UPDATE calendar SET last_success=$2, error_message=$3 WHERE id=$1", &[&id, &Utc::now(), &msg])?; + tx.commit()?; + return Ok(()) } - let mut res = self.http_client.get(&cal_opts.url).send()?; - println!("{} {} {:?}", res.status(), cal_opts.url, res.headers()); + let etag = res.headers().get(ETAG) + .and_then(|v| v.to_str().ok()); + let last_modified = res.headers().get(LAST_MODIFIED) + .and_then(|v| v.to_str().ok()); + + let tx = self.transaction()?; + tx.exec("UPDATE calendar SET last_success=$2, error_message=NULL, etag=$3, last_modified=$4 WHERE id=$1", &[&id, &Utc::now(), &etag, &last_modified])?; let mut p = Parser::new(); let mut buf = [0; 1024]; @@ -81,7 +117,7 @@ impl Resources { } tx.commit()?; - + Ok(()) } }