diff --git a/src/commands/schedule_csv.rs b/src/commands/schedule_csv.rs index 19728cd..fa02251 100644 --- a/src/commands/schedule_csv.rs +++ b/src/commands/schedule_csv.rs @@ -25,7 +25,12 @@ struct CsvRecord { dinner: String, } -pub async fn with(api_client: &ApiClient, calendar: &str, csv_file: &Path) -> Result<()> { +pub async fn with( + api_client: &ApiClient, + calendar: &str, + csv_file: &Path, + yearly_recurring_events: bool, +) -> Result<()> { let mut csv = csv::Reader::from_path(csv_file)?; let records = csv.deserialize::().flatten().collect::>(); @@ -51,7 +56,7 @@ pub async fn with(api_client: &ApiClient, calendar: &str, csv_file: &Path) -> Re }) .flatten(); - publish_events(&api_client, calendar, events).await?; + publish_events(&api_client, calendar, events, yearly_recurring_events).await?; Ok(()) } @@ -111,6 +116,7 @@ async fn publish_events<'a, EventsIter>( api_client: &ApiClient, calendar: &str, events: EventsIter, + yearly_recurring_events: bool, ) -> Result<()> where EventsIter: Iterator, @@ -134,9 +140,28 @@ where &ev.ends_at.date(), &ev.recipe.name ); - let cal = icalendar::Calendar::new() - .push::(ev.into()) - .done(); + + let end_time = ev.ends_at; + let mut event: icalendar::Event = ev.into(); + + if yearly_recurring_events { + use chrono::Datelike; + use icalendar::Component; + + const DAY_NAMES: [&str; 7] = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]; + event.add_property( + "RRULE", + &format!( + "FREQ=YEARLY;BYDAY={weekday};BYWEEKNO={weekno}", + weekday = DAY_NAMES + .get(end_time.weekday().num_days_from_monday() as usize) + .unwrap(), + weekno = end_time.iso_week().week(), + ), + ); + } + + let cal = icalendar::Calendar::new().push(event).done(); let cal_as_string = (&cal.to_string()) .replacen( diff --git a/src/event.rs b/src/event.rs index f0dd326..c1009ae 100644 --- a/src/event.rs +++ b/src/event.rs @@ -3,7 +3,7 @@ use { crate::recipe::Recipe, - chrono::{/*Datelike, */ NaiveDate, NaiveDateTime, NaiveTime, Utc}, + chrono::{NaiveDate, NaiveDateTime, NaiveTime, Utc}, icalendar::Event as CalEvent, std::rc::Rc, }; @@ -47,8 +47,6 @@ impl Event { impl From for CalEvent { fn from(ev: Event) -> Self { use icalendar::Component; - - // const DAY_NAMES: [&str; 7] = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]; let start_time = ev.ends_at - ev.recipe.total_time(); let cal_event = CalEvent::new() @@ -59,23 +57,6 @@ impl From for CalEvent { .timestamp(Utc::now()) .starts(start_time) .ends(ev.ends_at) - /* FIXME - .add_property( - // TODO make configurable yearly repetition, for now this suits my personal uses - "RRULE", - &format!( - "FREQ=YEARLY;BYDAY={weekday};BYWEEKNO={weekno}", - weekday = DAY_NAMES - .get(start_time.weekday().num_days_from_monday() as usize) - .unwrap(), - weekno = start_time.iso_week().week(), - ), - )*/ - .add_property( - // TODO make configurable yearly repetition, for now this suits my personal uses - "RRULE", - "FREQ=YEARLY", - ) .done(); cal_event diff --git a/src/main.rs b/src/main.rs index 77b195b..1530f20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,6 +69,7 @@ fn setup_args() -> ArgMatches { .arg(server_arg.clone()) .arg(arg!( "")) .arg(arg!( "").value_parser(clap::value_parser!(PathBuf))) + .arg(arg!(-y --yearly "Setup yearly recurring events (preserving the day of the week)")) ) .subcommand( Command::new("purge") @@ -118,7 +119,14 @@ async fn parse_args(args: &ArgMatches) -> Result<()> { let calendar_name = sub_matches .get_one::("calendar_name") .expect(" is a mandatory parameter, it cannot be missing"); - commands::schedule_csv::with(&api_client, calendar_name.as_str(), &csv_file).await + let yearly_recurring_events = sub_matches.contains_id("yearly"); + commands::schedule_csv::with( + &api_client, + calendar_name.as_str(), + &csv_file, + yearly_recurring_events, + ) + .await } Some(("purge", sub_matches)) => { let api_client = get_api_client(&sub_matches, &configuration)?;