v6/src/generator/rss.rs

67 lines
2.3 KiB
Rust

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<HtmlContent>], tags: &HashMap<&Tag, Vec<&Post<HtmlContent>>>) {
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::<Vec<_>>())
.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::<Vec<_>>())
.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<Utc>) -> String {
datetime.format("%a, %d %b %Y %H:%M:%S %z").to_string()
}
fn to_rss_item(post: &Post<HtmlContent>) -> 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::<Vec<_>>()
})
.unwrap_or(vec![]),
)
.content(Some(post.content.html().to_owned()))
.build()
}