From 51a8e1ff88a5a0fbddc08b2c0db137f00ebd3be1 Mon Sep 17 00:00:00 2001 From: Leonora Tindall Date: Tue, 1 Nov 2022 14:50:14 -0500 Subject: [PATCH] Add post-slurping (get markdown source for post) --- src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++-- static/index.html | 5 +++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 11b18a3..3359029 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ mod cohost_posts; mod syndication; mod webfinger; use cohost_account::{CohostAccount, COHOST_ACCOUNT_API_URL}; -use cohost_posts::{cohost_posts_api_url, CohostPostsPage}; +use cohost_posts::{cohost_posts_api_url, CohostPost, CohostPostsPage}; use webfinger::CohostWebfingerResource; #[derive(Parser, Debug)] @@ -46,6 +46,12 @@ fn index() -> RawHtml<&'static str> { RawHtml(include_str!("../static/index.html")) } +#[derive(Responder)] +#[response(content_type = "text/markdown")] +struct MdResponse { + inner: String, +} + #[derive(Responder)] #[response(content_type = "application/rss+xml")] struct RssResponse { @@ -61,6 +67,28 @@ enum ErrorResponse { InternalError(String), } +async fn get_post_from_page( + client: &mut Client, + project_id: &str, + post_id: u64, +) -> Result { + let mut page = 0; + loop { + let new_page = get_page_data(client, project_id, page).await?; + if new_page.items.is_empty() { + // Once there are no posts, we're done. + return Err(ErrorResponse::NotFound( + "End of posts reached, ID not found.".into(), + )); + } else { + page += 1; + if let Some(post) = new_page.items.into_iter().find(|post| post.id == post_id) { + return Ok(post); + } + } + } +} + async fn get_full_post_data( client: &mut Client, project_id: &str, @@ -130,6 +158,17 @@ async fn syndication_rss_route(project: &str) -> Result/")] +async fn post_md_route(project: &str, id: u64) -> Result { + let mut client = get_client()?; + + let _project_data = get_project_data(&mut client, project).await?; + let post_data = get_post_from_page(&mut client, project, id).await?; + Ok(MdResponse { + inner: post_data.plain_body, + }) +} + async fn get_project_data( client: &mut Client, project_id: &str, @@ -213,7 +252,7 @@ async fn main() -> Result<(), Box> { let _rocket = rocket::build() .mount( &ARGS.base_url, - routes![index, webfinger_route, syndication_rss_route], + routes![index, webfinger_route, syndication_rss_route, post_md_route], ) .ignite() .await? diff --git a/static/index.html b/static/index.html index fe650cf..409021f 100644 --- a/static/index.html +++ b/static/index.html @@ -30,6 +30,11 @@ Go to /project_name/feed.rss to get a feed for a project. For example, /noracodes/feed.rss will give you the feed for my page.

+

+ You can also get a particular post's original plain-text body at /project_name/post_id/, such as + /noracodes/169186/. (In a Cohost post URL, the ID is the numerical part after /post/. + For instance, in https://cohost.org/noracodes/post/169186-october-update, the ID is "169186".) +

Webfinger resources for accounts are provided at the Webfinger well-known URL /.well-known/webfinger?project_name.