corobel/src/syndication.rs

101 lines
3.2 KiB
Rust

use crate::cohost_account::CohostAccount;
use crate::cohost_posts::*;
use crate::ARGS;
use rss::Channel;
pub fn channel_for_posts_page(
project_name: impl AsRef<str>,
page_number: u64,
project: CohostAccount,
page: CohostPostsPage,
) -> Channel {
let mut builder = rss::ChannelBuilder::default();
builder
.title(format!("{} Cohost Posts", project.display_name))
.description(project.description)
.generator(Some(format!(
"{} {}",
env!("CARGO_CRATE_NAME"),
env!("CARGO_PKG_VERSION")
)))
.link(format!(
"https://cohost.org/{}?page={}",
project_name.as_ref(),
page_number
));
let mut items = Vec::with_capacity(page.number_items);
for item in page.items {
let mut item_builder = rss::ItemBuilder::default();
let mut categories: Vec<rss::Category> = Vec::with_capacity(item.tags.len());
for tag in item.tags.iter().cloned() {
categories.push(rss::Category {
name: tag,
domain: Some("https://cohost.org".into()),
});
}
item_builder
.link(item.url.clone())
.title(item.headline)
.author(item.poster.handle)
.guid(Some(rss::Guid {
value: item.url.clone(),
permalink: true,
}))
.categories(categories)
.pub_date(item.published_at.to_rfc2822())
.source(Some(rss::Source {
title: Some(format!("{} Cohost Posts", project.display_name)),
url: format!("https://{}/feed/{}.rss", ARGS.domain, project_name.as_ref()),
}));
let mut body_text = String::new();
if item.share_tree.len() == 1 {
body_text.push_str("(in reply to another post)\n---\n")
} else if item.share_tree.len() > 1 {
body_text.push_str(&format!(
"(in reply to {} other posts)\n---\n",
item.share_tree.len()
));
}
if item.cws.is_empty() {
body_text.push_str(&item.plain_body);
} else {
body_text.push_str("Sensitive post, body text omitted. Content warnings:{}");
for cw in item.cws {
body_text.push_str(&format!(" {},", cw));
}
body_text.pop(); // Remove trailing comma
body_text.push_str("\n---\n")
};
if !item.tags.is_empty() {
body_text.push_str("\n\n Post tagged:");
for tag in item.tags {
body_text.push_str(&format!(" #{},", tag));
}
body_text.pop(); // Remove trailing comma
}
use pulldown_cmark::Options;
let options = Options::ENABLE_FOOTNOTES
& Options::ENABLE_STRIKETHROUGH
& Options::ENABLE_TABLES
& Options::ENABLE_TASKLISTS;
let parser = pulldown_cmark::Parser::new_ext(&body_text, options);
let mut html_output = String::new();
pulldown_cmark::html::push_html(&mut html_output, parser);
item_builder.content(html_output);
items.push(item_builder.build());
}
builder.items(items);
builder.build()
}