Links and correct sorting

This commit is contained in:
Leonora Tindall 2022-10-31 21:41:07 -05:00
parent cbd1ae6fa4
commit 17941d90be
Signed by: nora
GPG Key ID: 7A8B52EC67E09AAF
4 changed files with 27 additions and 5 deletions

1
Cargo.lock generated
View File

@ -295,6 +295,7 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
name = "corobel" name = "corobel"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"atom_syndication",
"chrono", "chrono",
"clap", "clap",
"eggbug", "eggbug",

View File

@ -17,3 +17,4 @@ once_cell = "1.16.0"
chrono = { version = "0.4.22", features = [ "serde" ] } chrono = { version = "0.4.22", features = [ "serde" ] }
rss = { version = "2.0.1", features = [ "builders", "atom", "chrono" ] } rss = { version = "2.0.1", features = [ "builders", "atom", "chrono" ] }
pulldown-cmark = "0.9.2" pulldown-cmark = "0.9.2"
atom_syndication = "0.11.0"

View File

@ -17,7 +17,7 @@ ports to use for development and deployment.
- [x] RSS feeds for projects - [x] RSS feeds for projects
- [x] Index page explaining what's going on - [x] Index page explaining what's going on
- [ ] RSS feeds for tags - [ ] RSS feeds for tags
- [ ] Atom Extension pagination support - [x] Atom Extension pagination support
- [ ] Read More support - [ ] Read More support
- [ ] Dublin Core support - [ ] Dublin Core support
- [ ] Media Envelope support - [ ] Media Envelope support

View File

@ -2,13 +2,20 @@ use crate::cohost_account::CohostAccount;
use crate::cohost_posts::*; use crate::cohost_posts::*;
use crate::ARGS; use crate::ARGS;
use rss::Channel; use rss::Channel;
use rss::extension::atom::{AtomExtensionBuilder, Link};
use atom_syndication::LinkBuilder;
fn rel_link_for(rel: &str, project_name: &str, page_number: u64) -> Link {
LinkBuilder::default().rel(rel).href(format!("https://{}{}{}/feed.rss?page={}", &ARGS.domain, &ARGS.base_url, project_name.clone(), page_number)).build()
}
pub fn channel_for_posts_page( pub fn channel_for_posts_page(
project_name: impl AsRef<str>, project_name: impl AsRef<str>,
page_number: u64, page_number: u64,
project: CohostAccount, project: CohostAccount,
page: CohostPostsPage, mut page: CohostPostsPage,
) -> Channel { ) -> Channel {
let project_name = project_name.as_ref().clone();
let mut builder = rss::ChannelBuilder::default(); let mut builder = rss::ChannelBuilder::default();
builder builder
.title(format!("{} Cohost Posts", project.display_name)) .title(format!("{} Cohost Posts", project.display_name))
@ -20,12 +27,25 @@ pub fn channel_for_posts_page(
))) )))
.link(format!( .link(format!(
"https://cohost.org/{}?page={}", "https://cohost.org/{}?page={}",
project_name.as_ref(), project_name,
page_number page_number
)); ));
let mut items = Vec::with_capacity(page.number_items); let mut atom = AtomExtensionBuilder::default();
let mut links = vec![rel_link_for("self", project_name, page_number), rel_link_for("first", project_name, 0)];
if page_number > 0 {
links.push(rel_link_for("prev", project_name, page_number - 1));
}
if page.number_items > 0 {
// Cohost API is wrong about the pagination so we can only guess. If there are posts, there might be more posts.
links.push(rel_link_for("next", project_name, page_number + 1));
}
atom.links(links);
builder.atom_ext(Some(atom.build()));
page.items.sort_by_key(|item| item.published_at);
let mut items = Vec::with_capacity(page.number_items);
for item in page.items { for item in page.items {
let mut item_builder = rss::ItemBuilder::default(); let mut item_builder = rss::ItemBuilder::default();
let mut categories: Vec<rss::Category> = Vec::with_capacity(item.tags.len()); let mut categories: Vec<rss::Category> = Vec::with_capacity(item.tags.len());
@ -47,7 +67,7 @@ pub fn channel_for_posts_page(
.pub_date(item.published_at.to_rfc2822()) .pub_date(item.published_at.to_rfc2822())
.source(Some(rss::Source { .source(Some(rss::Source {
title: Some(format!("{} Cohost Posts", project.display_name)), title: Some(format!("{} Cohost Posts", project.display_name)),
url: format!("https://{}/feed/{}.rss", ARGS.domain, project_name.as_ref()), url: format!("https://{}/feed/{}.rss", ARGS.domain, project_name),
})); }));
let mut body_text = String::new(); let mut body_text = String::new();