add parsing for Campfire

This commit is contained in:
_ 2025-08-14 04:39:24 +00:00
parent 92c30167df
commit d789425e47
6 changed files with 263 additions and 37 deletions

View file

@ -9,6 +9,7 @@ use url::Url;
#[cfg(test)]
mod tests;
mod wac_campfire;
mod wac_ical;
#[derive(Clone, Default, Deserialize)]
@ -29,18 +30,6 @@ struct CalendarUi {
short_name: String,
}
/// The Sierra Club uses a calendar software called Campfire, which luckily puts out nice JSON files
///
/// It's also deterministic, which is lovely. You get the same JSON byte-for-byte unless the events changed
#[derive(Clone, Deserialize)]
struct ConfigCampfire {
#[serde(flatten)]
dl: Downloadable,
#[serde(flatten)]
ui: CalendarUi,
}
#[derive(Deserialize)]
struct ConfigOutput {
/// Used as the OpenGraph description in meta tags
@ -62,7 +51,7 @@ struct ConfigOutput {
#[derive(Deserialize)]
struct Config {
campfires: Vec<ConfigCampfire>,
campfires: Vec<wac_campfire::Config>,
icals: Vec<wac_ical::Config>,
output: ConfigOutput,
}
@ -131,6 +120,10 @@ impl Parameters {
#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
struct DatePerhapsTime {
dt: DateTime<chrono_tz::Tz>,
/// True if the event has no specific time and takes all day on the given date
///
/// Not implemented for Campfire because it hasn't shown up in the test data
all_day: bool,
}
@ -154,6 +147,9 @@ struct EventInstance {
calendar_ui: CalendarUi,
dtstart: DatePerhapsTime,
location: Option<String>,
/// Used internally to handle recurrence exceptions in ics
///
/// Not implemented for Campfire
recurrence_id: Option<DatePerhapsTime>,
summary: Option<String>,
uid: Option<String>,
@ -178,17 +174,23 @@ impl EventInstance {
#[derive(Default)]
struct Data {
campfires: Vec<wac_campfire::Calendar>,
icals: Vec<wac_ical::Calendar>,
}
fn read_data_from_disk(config: &Config) -> Result<Data> {
let mut data = Data::default();
for config_ical in &config.icals {
let cal = wac_ical::Calendar::read_from_downloadable(config_ical.clone())?;
data.icals.push(cal);
}
Ok(data)
Ok(Data {
campfires: config
.campfires
.iter()
.map(|cfg| wac_campfire::Calendar::read_from_config(cfg.clone()))
.collect::<Result<Vec<_>, _>>()?,
icals: config
.icals
.iter()
.map(|cfg| wac_ical::Calendar::read_from_config(cfg.clone()))
.collect::<Result<Vec<_>, _>>()?,
})
}
fn process_data<'a>(
@ -199,17 +201,28 @@ fn process_data<'a>(
let params = Parameters::new(now)?;
let mut instances = vec![];
for ical in &data.icals {
for ei in ical
for campfire in &data.campfires {
for ev in campfire
.event_instances(&params)?
.into_iter()
.filter(|x| x.filter(config_output))
{
instances.push(ei);
instances.push(ev);
}
}
instances.sort_by_key(|ei| ei.dtstart);
for ical in &data.icals {
for ev in ical
.event_instances(&params)?
.into_iter()
.filter(|x| x.filter(config_output))
{
instances.push(ev);
}
}
instances.sort_by_key(|ev| ev.dtstart);
Ok(instances)
}