use color_eyre::eyre::Result;
use std::{
fs::create_dir_all,
path::{Path, PathBuf},
rc::Rc,
};
use crate::{
configuration::config::Config,
model::{calendar_collection::CalendarCollection, event::Event},
};
pub type EventSlice<'a> = &'a [Option<Rc<Event>>];
pub(crate) const VIEW_PATH: &str = "event";
const PAGE_TITLE: &str = "Event Page";
#[derive(Debug)]
pub struct EventView<'a> {
calendars: &'a CalendarCollection,
output_dir: PathBuf,
}
impl EventView<'_> {
pub fn new(calendars: &CalendarCollection) -> EventView<'_> {
let output_dir = calendars
.base_dir()
.join(&calendars.config.output_dir)
.join(VIEW_PATH);
EventView {
calendars,
output_dir,
}
}
fn config(&self) -> &Config {
&self.calendars.config
}
fn output_dir(&self) -> &Path {
&self.output_dir
}
pub fn create_html_pages(&self) -> Result<()> {
create_dir_all(self.output_dir())?;
let mut index_written = false;
for window in self.calendars.events_to_show()?.windows(3) {
let next_event_opt = &window[2];
let mut index_paths = vec![];
if !index_written {
if let Some(next_event) = next_event_opt {
if next_event.start().date_naive() > self.calendars.today_date() {
index_written = true;
index_paths.push(self.output_dir().join(PathBuf::from("index.html")));
}
} else {
index_written = true;
index_paths.push(self.output_dir().join(PathBuf::from("index.html")));
}
}
self.write_view(&window, index_paths.as_slice())?;
}
Ok(())
}
fn write_view(&self, event_slice: &EventSlice, index_paths: &[PathBuf]) -> Result<()> {
let previous_event = &event_slice[0];
let current_event = &event_slice[1]
.as_ref()
.expect("Current week is None. This should never happen.");
let next_event = &event_slice[2];
println!("event: {}", current_event);
println!(
" event: ({} {} {}) {} {}",
current_event.weekday(),
current_event.year(),
current_event.week(),
current_event.summary(),
current_event.start(),
);
let file_name = current_event.file_name();
let previous_file_name = previous_event.as_ref().map(|e| e.file_name());
let next_file_name = next_event.as_ref().map(|e| e.file_name());
let mut context = self.calendars.template_context();
context.insert("current_view", VIEW_PATH);
context.insert("page_title", PAGE_TITLE);
context.insert(
"view_date",
¤t_event
.start()
.format(&self.config().day_view_format)
.to_string(),
);
context.insert("year", ¤t_event.year());
context.insert("month", ¤t_event.month());
context.insert(
"month_name",
¤t_event
.month()
.map(|m| m.name())
.unwrap_or("UNKNOWN MONTH"),
);
context.insert("day", ¤t_event.day());
context.insert("event", ¤t_event.context(self.config()));
let base_url_path: unix_path::PathBuf =
self.calendars.config.base_url_path.path_buf().clone();
let binding = self.output_dir().join(PathBuf::from(&file_name));
let mut file_paths = vec![&binding];
file_paths.extend(index_paths);
for file_path in file_paths {
let view_path = base_url_path.join(VIEW_PATH);
context.insert(
"previous_file_name",
&previous_file_name.as_ref().map(|path| view_path.join(path)),
);
context.insert(
"next_file_name",
&next_file_name.as_ref().map(|path| view_path.join(path)),
);
self.calendars
.write_template("event.html", &context, file_path)?;
}
Ok(())
}
}