use super::posts::parse::Tag; use super::posts::{HtmlContent, Post}; use super::util::output_writer; use chrono::{DateTime, Utc}; use rss::{Category, ChannelBuilder, Guid, Item, ItemBuilder}; use std::collections::HashMap; use std::path::PathBuf; pub fn generate(posts: &[Post], tags: &HashMap<&Tag, Vec<&Post>>) { let all_feed = ChannelBuilder::default() .title("Shadowfacts") .link("https://shadowfacts.net") .last_build_date(Some(rfc_822(Utc::now()))) .items(posts.iter().map(to_rss_item).collect::>()) .build(); let all_writer = output_writer("/feed.xml").expect("feed.xml"); all_feed .pretty_write_to(all_writer, b' ', 2) .expect("write feed.xml"); for (tag, posts) in tags { let tag_feed = ChannelBuilder::default() .title(format!("Shadowfacts ({})", tag.name)) .link(format!("https://shadowfacts.net/{}", tag.slug)) .last_build_date(Some(rfc_822(Utc::now()))) .items(posts.iter().map(|&p| to_rss_item(p)).collect::>()) .build(); let mut buf = PathBuf::from(&tag.slug); buf.push("feed.xml"); let tag_writer = output_writer(buf).expect("tag feed.xml"); tag_feed .pretty_write_to(tag_writer, b' ', 2) .expect("write tag feed.xml"); } } fn rfc_822(datetime: DateTime) -> String { datetime.format("%a, %d %b %Y %H:%M:%S %z").to_string() } fn to_rss_item(post: &Post) -> Item { ItemBuilder::default() .title(Some(post.metadata.title.clone())) .link(Some(format!("https://shadowfacts.net{}", post.permalink()))) .guid(Some(Guid { value: format!("https://shadowfacts.net{}", post.permalink()), permalink: true, })) .pub_date(Some(rfc_822(post.metadata.date.into()))) .categories( post.metadata .tags .as_ref() .map(|tags| { tags.iter() .map(|t| Category { name: t.name.clone(), domain: None, }) .collect::>() }) .unwrap_or(vec![]), ) .content(Some(post.content.html().to_owned())) .build() }