use crate::*; use std::collections::VecDeque; use chrono::{DateTime, Utc, Local}; pub fn generate_rss(feed: &Feed, website: &Website) -> String { let path = &feed.source_path; let content = std::fs::read_to_string(path).unwrap(); let mut lines: VecDeque<&str> = content.lines().collect(); let base_url = website.config.get("rss.base_url"); if base_url.is_empty() { warn!("No value was given for 'rss.base_url' key in toaster.conf"); } let (parent_url, _) = feed.url.split_once('/').unwrap(); let channel_title = lines.pop_front().unwrap_or("No title"); let last_build_date = match feed.last_modified { Some(system_time) => system_time.into(), None => Utc::now(), }.to_rfc2822(); let mut all_entries = String::new(); for line in &lines { if line.is_empty() { continue } if let Some((timestamp, name)) = line.split_once("::") { let mut timestamp = timestamp.to_string(); let entry_title = name; if !timestamp.contains('T') { timestamp.push_str("T00:00:00"); } if !timestamp.contains('Z') || timestamp.contains('+') { let offset = Local::now().offset().to_string(); timestamp.push_str(&offset); } let Ok(entry_time) = DateTime::parse_from_rfc3339(×tamp) else { warn!("Invalid timestamp in RSS file {path:?}: {timestamp:?}"); continue; }; let entry_link = format!("{base_url}/{parent_url}/{}.html", to_slug(name)); // Check that child page exists. if let None = website.has_page(feed, name, "html") { warn!("Feed {feed:?} contains link to nonexistent page {name:?}"); } let entry_string = format!(" {entry_title} {entry_link} {entry_time} "); all_entries.push_str(&entry_string); } else { warn!("Invalid line in RSS file {path:?}: {line:?}"); } } format!( r#" {channel_title} {base_url} {last_build_date} {all_entries} "#) }