diff --git a/src/main.rs b/src/main.rs index e2fce47..b1633b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,11 +58,15 @@ struct Config { } impl Config { - fn downloads(&self) -> impl Iterator { + fn downloads(&self, now: DateTime) -> impl Iterator { self.campfires .iter() .map(|cf| cf.dl.clone()) - .chain(self.common_ninjas.iter().map(|cn| cn.simple_download())) + .chain( + self.common_ninjas + .iter() + .map(move |cn| cn.simple_download(now)), + ) .chain(self.icals.iter().map(|ical| ical.dl.clone())) } } @@ -434,12 +438,14 @@ static APP_USER_AGENT: &str = concat!( async fn do_everything(cli: &CliAuto) -> Result<()> { let config = std::fs::read_to_string(&cli.config)?; let config: Config = toml::from_str(&config)?; + let tz = &config.output.timezone; + let now = Utc::now().with_timezone(tz); tracing::info!(?APP_USER_AGENT); let client = reqwest::Client::builder() .user_agent(APP_USER_AGENT) .build()?; - for dl in config.downloads() { + for dl in config.downloads(now) { let Some(download_url) = &dl.download_url else { continue; }; @@ -456,9 +462,6 @@ async fn do_everything(cli: &CliAuto) -> Result<()> { } let data = read_data_from_disk(&config)?; - - let tz = &config.output.timezone; - let now = Utc::now().with_timezone(tz); let instances = process_data(&data, &config.output, now)?; output_html(&config.output, &instances, now)?; Ok(()) @@ -484,15 +487,15 @@ fn main_auto(cli: CliAuto) -> Result<()> { fn main_debug_output(cli: CliDebugOutput) -> Result<()> { tracing_subscriber::fmt::init(); tracing::info!("Started tracing"); - let config = std::fs::read_to_string(&cli.config)?; - let config: Config = toml::from_str(&config)?; + let config = std::fs::read_to_string(&cli.config).context("Failed to read config file")?; + let config: Config = toml::from_str(&config).context("Failed to parse config file")?; - let data = read_data_from_disk(&config)?; + let data = read_data_from_disk(&config).context("Failed to read data from disk")?; let tz = &config.output.timezone; let now = Utc::now().with_timezone(tz); - let instances = process_data(&data, &config.output, now)?; - output_html(&config.output, &instances, now)?; + let instances = process_data(&data, &config.output, now).context("Failed to process data")?; + output_html(&config.output, &instances, now).context("Failed to output HTML")?; Ok(()) } diff --git a/src/wac_common_ninja.rs b/src/wac_common_ninja.rs index 4d6174f..52fb1b1 100644 --- a/src/wac_common_ninja.rs +++ b/src/wac_common_ninja.rs @@ -1,16 +1,17 @@ use super::{CalendarUi, EventInstance, Parameters, SimpleDownload}; use crate::prelude::*; +use chrono::DateTime; -#[derive(Clone, Default, Deserialize)] +#[derive(Clone, Deserialize)] struct SillyDownloadable { /// URL to scrape to download the file from - download_url: Option, + download_url: Url, /// Disk location to cache the file for debugging file_path: Utf8PathBuf, } -#[derive(Clone, Default, Deserialize)] +#[derive(Clone, Deserialize)] pub(crate) struct Config { #[serde(flatten)] pub(crate) dl: SillyDownloadable, @@ -20,8 +21,15 @@ pub(crate) struct Config { } impl Config { - pub(crate) fn simple_download(&self) -> SimpleDownload { - todo!() + pub(crate) fn simple_download(&self, now: DateTime) -> SimpleDownload { + let date = now.format("%Y-%m-%d").to_string(); + let mut url = self.dl.download_url.clone(); + url.query_pairs_mut().append_pair("date", &date); + + SimpleDownload { + download_url: Some(url), + file_path: self.dl.file_path.clone(), + } } } @@ -52,7 +60,7 @@ pub(crate) struct Calendar { impl Calendar { fn to_event_instance(&self, params: &Parameters, ev: &Event) -> Result> { - let dt = chrono::DateTime::from_timestamp_millis(ev.timestamp) + let dt = DateTime::from_timestamp_millis(ev.timestamp) .context("cannot represent timestamp as a date")? .with_timezone(¶ms.tz); let dtstart = crate::DatePerhapsTime { dt, all_day: false }; @@ -95,27 +103,47 @@ impl Calendar { mod tests { use super::*; - #[test] - fn end_to_end() { - let s = r#" -{"data":{"items":[{"timestamp":1748989800000,"durationInMinutes":90,"title":"Foo Bar","description":""},{"timestamp":1749999600000,"durationInMinutes":30,"title":"Snaf Oo","description":""}]},"success":true,"message":""} - "#; - - let cfg = Config { + fn example_config() -> Config { + Config { dl: SillyDownloadable { - download_url: None, + download_url: Url::parse("https://www.commoninja.com/api/apps/calendar/get-monthly-events?widgetId=00000000-0000-0000-000000000000").unwrap(), file_path: ".".into(), }, ui: CalendarUi { html_url: None, short_name: "asdf".into(), }, - }; + } + } + + #[test] + fn end_to_end() { + let s = r#" +{"data":{"items":[{"timestamp":1748989800000,"durationInMinutes":90,"title":"Foo Bar","description":""},{"timestamp":1749999600000,"durationInMinutes":30,"title":"Snaf Oo","description":""}]},"success":true,"message":""} + "#; + + let cfg = example_config(); let cal = Calendar::read_from_str(cfg, s).unwrap(); - let params = - Parameters::new(Utc::now().with_timezone(&chrono_tz::America::Chicago)).unwrap(); + let params = Parameters::new( + DateTime::from_timestamp(1748989700, 0) + .unwrap() + .with_timezone(&chrono_tz::America::Chicago), + ) + .unwrap(); let instances = cal.event_instances(¶ms).unwrap(); assert_eq!(instances.len(), 2); } + + #[test] + fn unsillify() { + let dt = DateTime::from_timestamp(1756190298, 0) + .unwrap() + .with_timezone(&chrono_tz::America::Chicago); + let cfg = example_config(); + assert_eq!( + cfg.simple_download(dt).download_url.unwrap().to_string(), + "https://www.commoninja.com/api/apps/calendar/get-monthly-events?widgetId=00000000-0000-0000-000000000000&date=2025-08-26" + ); + } }