use color_eyre::eyre::{Context, Result};
use icalendar::{Calendar, Component, Event, EventLike, Property};
use std::{
fs::{create_dir_all, File},
io::Write,
path::{Path, PathBuf},
};
use crate::model::calendar_collection::CalendarCollection;
pub(crate) const VIEW_PATH: &str = "feed";
#[derive(Debug)]
pub struct FeedView<'a> {
calendars: &'a CalendarCollection,
output_dir: PathBuf,
}
impl FeedView<'_> {
pub fn new(calendars: &CalendarCollection) -> FeedView<'_> {
let output_dir = calendars
.base_dir()
.join(&calendars.config.output_dir)
.join(VIEW_PATH);
FeedView {
calendars,
output_dir,
}
}
fn output_dir(&self) -> &Path {
&self.output_dir
}
pub(crate) fn create_view_files(&self) -> Result<()> {
create_dir_all(self.output_dir())?;
let mut calendar = Calendar::new();
calendar
.name("statical feed")
.description("a concatenation of all of the calendars provided to statical")
.timezone(&self.calendars.display_timezone().to_string())
.append_property(Property::new("METHOD", "PUBLISH"));
for event in self.calendars.events() {
let ical_event = Event::new()
.summary(event.summary())
.description(event.description())
.add_property("CLASS", "PUBLIC")
.starts(event.start())
.ends(event.end())
.done();
calendar.push(ical_event);
}
let file_path = self.output_dir().join("feed.ics");
eprintln!("Writing calendar feed to file: {:?}", file_path);
let mut output_file = File::create(file_path)?;
output_file
.write_all(format!("{}", calendar).as_bytes())
.wrap_err("could not write calendar feed file")?;
Ok(())
}
}