Support media envelopes and feed w/o transparent shares
This commit is contained in:
parent
0f7af7c13a
commit
95f6887eda
|
@ -17,6 +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
|
||||||
- [x] Better support for transparent shares
|
- [x] Better support for transparent shares
|
||||||
|
- [x] Add feed without shares
|
||||||
- [ ] More robust parsing (defaults for all!)
|
- [ ] More robust parsing (defaults for all!)
|
||||||
- [ ] RSS feeds for tags
|
- [ ] RSS feeds for tags
|
||||||
- [x] Atom Extension pagination support
|
- [x] Atom Extension pagination support
|
||||||
|
|
|
@ -44,14 +44,9 @@ pub struct CohostPost {
|
||||||
default
|
default
|
||||||
)]
|
)]
|
||||||
pub url: String,
|
pub url: String,
|
||||||
#[serde(
|
#[serde(deserialize_with = "deserialize_null_default", default)]
|
||||||
deserialize_with = "deserialize_null_default",
|
|
||||||
default
|
|
||||||
)]
|
|
||||||
pub blocks: Vec<CohostPostBlock>,
|
pub blocks: Vec<CohostPostBlock>,
|
||||||
#[serde(
|
#[serde(rename = "transparentShareOfPostId")]
|
||||||
rename = "transparentShareOfPostId",
|
|
||||||
)]
|
|
||||||
pub transparent_share_of_post_id: Option<u64>,
|
pub transparent_share_of_post_id: Option<u64>,
|
||||||
#[serde(rename = "postingProject")]
|
#[serde(rename = "postingProject")]
|
||||||
pub poster: CohostPostingProject,
|
pub poster: CohostPostingProject,
|
||||||
|
@ -93,7 +88,6 @@ pub struct CohostPostLink {
|
||||||
pub t_type: String,
|
pub t_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct CohostPostBlock {
|
pub struct CohostPostBlock {
|
||||||
pub attachment: Option<CohostPostAttachment>,
|
pub attachment: Option<CohostPostAttachment>,
|
||||||
|
@ -101,7 +95,11 @@ pub struct CohostPostBlock {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct CohostPostAttachment {
|
pub struct CohostPostAttachment {
|
||||||
#[serde(rename = "fileURL", deserialize_with = "deserialize_null_default", default)]
|
#[serde(
|
||||||
|
rename = "fileURL",
|
||||||
|
deserialize_with = "deserialize_null_default",
|
||||||
|
default
|
||||||
|
)]
|
||||||
pub file_url: String,
|
pub file_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -194,12 +194,22 @@ async fn get_project_data(project_id: String) -> Result<CohostAccount, ErrorResp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/<project>/originals.rss")]
|
||||||
|
async fn syndication_originals_rss_route(project: String) -> Result<RssResponse, ErrorResponse> {
|
||||||
|
let project_data = get_project_data(project.clone()).await?;
|
||||||
|
let page_data = get_full_post_data(project.clone()).await?;
|
||||||
|
Ok(RssResponse {
|
||||||
|
inner: syndication::channel_for_posts_page(project.clone(), project_data, page_data, true)
|
||||||
|
.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/<project>/feed.rss")]
|
#[get("/<project>/feed.rss")]
|
||||||
async fn syndication_rss_route(project: String) -> Result<RssResponse, ErrorResponse> {
|
async fn syndication_rss_route(project: String) -> Result<RssResponse, ErrorResponse> {
|
||||||
let project_data = get_project_data(project.clone()).await?;
|
let project_data = get_project_data(project.clone()).await?;
|
||||||
let page_data = get_full_post_data(project.clone()).await?;
|
let page_data = get_full_post_data(project.clone()).await?;
|
||||||
Ok(RssResponse {
|
Ok(RssResponse {
|
||||||
inner: syndication::channel_for_posts_page(project.clone(), project_data, page_data)
|
inner: syndication::channel_for_posts_page(project.clone(), project_data, page_data, false)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -244,7 +254,13 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let _rocket = rocket::build()
|
let _rocket = rocket::build()
|
||||||
.mount(
|
.mount(
|
||||||
&ARGS.base_url,
|
&ARGS.base_url,
|
||||||
routes![index, webfinger_route, syndication_rss_route, post_md_route],
|
routes![
|
||||||
|
index,
|
||||||
|
webfinger_route,
|
||||||
|
syndication_rss_route,
|
||||||
|
syndication_originals_rss_route,
|
||||||
|
post_md_route
|
||||||
|
],
|
||||||
)
|
)
|
||||||
.ignite()
|
.ignite()
|
||||||
.await?
|
.await?
|
||||||
|
|
|
@ -22,11 +22,16 @@ pub fn channel_for_posts_page(
|
||||||
project_name: impl AsRef<str>,
|
project_name: impl AsRef<str>,
|
||||||
project: CohostAccount,
|
project: CohostAccount,
|
||||||
mut page: CohostPostsPage,
|
mut page: CohostPostsPage,
|
||||||
|
originals_only: bool,
|
||||||
) -> Channel {
|
) -> Channel {
|
||||||
let project_name = project_name.as_ref().clone();
|
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,
|
||||||
|
if originals_only { "" } else { " and Shares" }
|
||||||
|
))
|
||||||
.description(project.description)
|
.description(project.description)
|
||||||
.generator(Some(format!(
|
.generator(Some(format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
|
@ -73,7 +78,13 @@ pub fn channel_for_posts_page(
|
||||||
let mut body_text = String::new();
|
let mut body_text = String::new();
|
||||||
|
|
||||||
if let Some(shared_post_id) = item.transparent_share_of_post_id {
|
if let Some(shared_post_id) = item.transparent_share_of_post_id {
|
||||||
body_text.push_str(&format!("(share of post {} without any commentary)\n\n---\n\n", shared_post_id));
|
if originals_only {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
body_text.push_str(&format!(
|
||||||
|
"(share of post {} without any commentary)\n\n---\n\n",
|
||||||
|
shared_post_id
|
||||||
|
));
|
||||||
} else if item.share_tree.len() == 1 {
|
} else if item.share_tree.len() == 1 {
|
||||||
body_text.push_str("(in reply to another post)\n\n---\n\n")
|
body_text.push_str("(in reply to another post)\n\n---\n\n")
|
||||||
} else if item.share_tree.len() > 1 {
|
} else if item.share_tree.len() > 1 {
|
||||||
|
@ -113,9 +124,16 @@ pub fn channel_for_posts_page(
|
||||||
item_builder.content(html_output);
|
item_builder.content(html_output);
|
||||||
|
|
||||||
for attachment in item.blocks.into_iter().filter_map(|block| block.attachment) {
|
for attachment in item.blocks.into_iter().filter_map(|block| block.attachment) {
|
||||||
use rss::EnclosureBuilder;
|
|
||||||
use mime_guess::from_path as guess_mime_from_path;
|
use mime_guess::from_path as guess_mime_from_path;
|
||||||
let enclosure = EnclosureBuilder::default().mime_type(guess_mime_from_path(&attachment.file_url).first_or_octet_stream().to_string()).url(attachment.file_url).build();
|
use rss::EnclosureBuilder;
|
||||||
|
let enclosure = EnclosureBuilder::default()
|
||||||
|
.mime_type(
|
||||||
|
guess_mime_from_path(&attachment.file_url)
|
||||||
|
.first_or_octet_stream()
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.url(attachment.file_url)
|
||||||
|
.build();
|
||||||
item_builder.enclosure(enclosure);
|
item_builder.enclosure(enclosure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,9 @@
|
||||||
<h2>Standard Data from Cohost Posts and Projects</h2>
|
<h2>Standard Data from Cohost Posts and Projects</h2>
|
||||||
<p>
|
<p>
|
||||||
<h3>Project RSS Feeds</h3>
|
<h3>Project RSS Feeds</h3>
|
||||||
Go to <code>/project_name/feed.rss</code> to get a feed for a project.
|
Go to <code>/project_name/feed.rss</code> to get a feed for a project, or <code>/project_name/originals.rss</code> for just original posts (including shared posts with commentary).
|
||||||
For example, <a href="/noracodes/feed.rss"><code>/noracodes/feed.rss</code></a> will give you the feed for my page.
|
For example, <a href="/noracodes/feed.rss"><code>/noracodes/feed.rss</code></a> will give you the feed for my page,
|
||||||
|
or <a href="/noracodes/original.rss"><code>/noracodes/feed.rss</code></a> for just my original posts.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<h3>Markdown Extraction</h3>
|
<h3>Markdown Extraction</h3>
|
||||||
|
|
Loading…
Reference in New Issue