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, 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 = 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() }