nextcloud-cooking-schedule/src/event.rs

81 lines
2.2 KiB
Rust

// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: AGPL-3.0-or-later
use {
crate::recipe::Recipe,
chrono::{DateTime, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone},
ics::properties as calprop,
ics::Event as CalEvent,
std::rc::Rc,
};
pub struct Event {
pub uid: String,
pub ends_at: NaiveDateTime,
pub recipe: Rc<Recipe>,
}
#[derive(strum_macros::Display)]
pub enum Meal {
Lunch,
Dinner,
}
impl Event {
pub fn new(date: NaiveDate, meal: Meal, recipe: Rc<Recipe>) -> Self {
let uid = format!(
"{}-{}@{}.montecristosoftware.eu",
date,
meal,
env!("CARGO_PKG_NAME")
);
let meal_time = match meal {
Meal::Lunch => NaiveTime::from_hms(12, 00, 00),
Meal::Dinner => NaiveTime::from_hms(19, 00, 00),
};
let ends_at = NaiveDateTime::new(date, meal_time);
Event {
uid,
ends_at,
recipe,
}
}
}
impl<'a> From<Event> for CalEvent<'a> {
fn from(ev: Event) -> Self {
let start_time = ev.ends_at - ev.recipe.total_time();
let mut event = ics::Event::new(ev.uid.clone(), dt_fmt(&Local::now()));
event.push(calprop::Summary::new(ev.recipe.name.clone()));
event.push(calprop::Description::new(format!(
"cookbook@{}",
ev.recipe.id
)));
event.push(calprop::Location::new(ev.recipe.url.clone()));
event.push(calprop::DtStart::new(dt_fmt(
&Local.from_local_datetime(&start_time).unwrap(),
)));
event.push(calprop::DtEnd::new(dt_fmt(
&Local.from_local_datetime(&ev.ends_at).unwrap(),
)));
// TODO make configurable yearly repetition, for now this suits my personal uses
event.push(calprop::RRule::new("FREQ=YEARLY"));
let alarm = ics::Alarm::display(
calprop::Trigger::new("-P15M"),
calprop::Description::new(ev.recipe.name.clone()),
);
event.add_alarm(alarm);
event
}
}
fn dt_fmt(datetime: &DateTime<Local>) -> String {
datetime.format("%Y%m%dT%H%M%S").to_string()
}