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
.