mirror of https://github.com/LemmyNet/lemmy.git
Generate valid RSS feed (fixes #1274)
parent
405ea38959
commit
8920f439ce
|
@ -1,4 +1,5 @@
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
pub mod code_migrations;
|
pub mod code_migrations;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
|
@ -16,9 +16,15 @@ use lemmy_db::{
|
||||||
use lemmy_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_utils::{settings::Settings, utils::markdown_to_html, LemmyError};
|
use lemmy_utils::{settings::Settings, utils::markdown_to_html, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use rss::{CategoryBuilder, ChannelBuilder, GuidBuilder, Item, ItemBuilder};
|
use rss::{
|
||||||
|
extension::dublincore::DublinCoreExtensionBuilder,
|
||||||
|
ChannelBuilder,
|
||||||
|
GuidBuilder,
|
||||||
|
Item,
|
||||||
|
ItemBuilder,
|
||||||
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::str::FromStr;
|
use std::{collections::HashMap, str::FromStr};
|
||||||
use strum::ParseError;
|
use strum::ParseError;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -39,6 +45,17 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
.route("/feeds/all.xml", web::get().to(get_all_feed));
|
.route("/feeds/all.xml", web::get().to(get_all_feed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref RSS_NAMESPACE: HashMap<String, String> = {
|
||||||
|
let mut h = HashMap::new();
|
||||||
|
h.insert(
|
||||||
|
"dc".to_string(),
|
||||||
|
rss::extension::dublincore::NAMESPACE.to_string(),
|
||||||
|
);
|
||||||
|
h
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_all_feed(
|
async fn get_all_feed(
|
||||||
info: web::Query<Params>,
|
info: web::Query<Params>,
|
||||||
context: web::Data<LemmyContext>,
|
context: web::Data<LemmyContext>,
|
||||||
|
@ -70,6 +87,7 @@ fn get_feed_all_data(conn: &PgConnection, sort_type: &SortType) -> Result<String
|
||||||
|
|
||||||
let mut channel_builder = ChannelBuilder::default();
|
let mut channel_builder = ChannelBuilder::default();
|
||||||
channel_builder
|
channel_builder
|
||||||
|
.namespaces(RSS_NAMESPACE.to_owned())
|
||||||
.title(&format!("{} - All", site_view.name))
|
.title(&format!("{} - All", site_view.name))
|
||||||
.link(Settings::get().get_protocol_and_hostname())
|
.link(Settings::get().get_protocol_and_hostname())
|
||||||
.items(items);
|
.items(items);
|
||||||
|
@ -141,6 +159,7 @@ fn get_feed_user(
|
||||||
|
|
||||||
let mut channel_builder = ChannelBuilder::default();
|
let mut channel_builder = ChannelBuilder::default();
|
||||||
channel_builder
|
channel_builder
|
||||||
|
.namespaces(RSS_NAMESPACE.to_owned())
|
||||||
.title(&format!("{} - {}", site_view.name, user.name))
|
.title(&format!("{} - {}", site_view.name, user.name))
|
||||||
.link(user_url)
|
.link(user_url)
|
||||||
.items(items);
|
.items(items);
|
||||||
|
@ -166,6 +185,7 @@ fn get_feed_community(
|
||||||
|
|
||||||
let mut channel_builder = ChannelBuilder::default();
|
let mut channel_builder = ChannelBuilder::default();
|
||||||
channel_builder
|
channel_builder
|
||||||
|
.namespaces(RSS_NAMESPACE.to_owned())
|
||||||
.title(&format!("{} - {}", site_view.name, community.name))
|
.title(&format!("{} - {}", site_view.name, community.name))
|
||||||
.link(community.actor_id)
|
.link(community.actor_id)
|
||||||
.items(items);
|
.items(items);
|
||||||
|
@ -195,6 +215,7 @@ fn get_feed_front(
|
||||||
|
|
||||||
let mut channel_builder = ChannelBuilder::default();
|
let mut channel_builder = ChannelBuilder::default();
|
||||||
channel_builder
|
channel_builder
|
||||||
|
.namespaces(RSS_NAMESPACE.to_owned())
|
||||||
.title(&format!("{} - Subscribed", site_view.name))
|
.title(&format!("{} - Subscribed", site_view.name))
|
||||||
.link(Settings::get().get_protocol_and_hostname())
|
.link(Settings::get().get_protocol_and_hostname())
|
||||||
.items(items);
|
.items(items);
|
||||||
|
@ -224,6 +245,7 @@ fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result<ChannelBuilder, Le
|
||||||
|
|
||||||
let mut channel_builder = ChannelBuilder::default();
|
let mut channel_builder = ChannelBuilder::default();
|
||||||
channel_builder
|
channel_builder
|
||||||
|
.namespaces(RSS_NAMESPACE.to_owned())
|
||||||
.title(&format!("{} - Inbox", site_view.name))
|
.title(&format!("{} - Inbox", site_view.name))
|
||||||
.link(format!(
|
.link(format!(
|
||||||
"{}/inbox",
|
"{}/inbox",
|
||||||
|
@ -310,18 +332,11 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
|
||||||
|
|
||||||
for p in posts {
|
for p in posts {
|
||||||
let mut i = ItemBuilder::default();
|
let mut i = ItemBuilder::default();
|
||||||
|
let mut dc_extension = DublinCoreExtensionBuilder::default();
|
||||||
|
|
||||||
i.title(p.name);
|
i.title(p.name);
|
||||||
|
|
||||||
let author_url = format!(
|
dc_extension.creators(vec![p.creator_actor_id.to_owned()]);
|
||||||
"{}/u/{}",
|
|
||||||
Settings::get().get_protocol_and_hostname(),
|
|
||||||
p.creator_name
|
|
||||||
);
|
|
||||||
i.author(format!(
|
|
||||||
"/u/{} <a href=\"{}\">(link)</a>",
|
|
||||||
p.creator_name, author_url
|
|
||||||
));
|
|
||||||
|
|
||||||
let dt = DateTime::<Utc>::from_utc(p.published, Utc);
|
let dt = DateTime::<Utc>::from_utc(p.published, Utc);
|
||||||
i.pub_date(dt.to_rfc2822());
|
i.pub_date(dt.to_rfc2822());
|
||||||
|
@ -345,16 +360,8 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
|
||||||
p.community_name
|
p.community_name
|
||||||
);
|
);
|
||||||
|
|
||||||
let category = CategoryBuilder::default()
|
// TODO: for category we should just put the name of the category, but then we would have
|
||||||
.name(format!(
|
// to read each community from the db
|
||||||
"/c/{} <a href=\"{}\">(link)</a>",
|
|
||||||
p.community_name, community_url
|
|
||||||
))
|
|
||||||
.domain(Settings::get().hostname.to_owned())
|
|
||||||
.build()
|
|
||||||
.map_err(|e| anyhow!(e))?;
|
|
||||||
|
|
||||||
i.categories(vec![category]);
|
|
||||||
|
|
||||||
if let Some(url) = p.url {
|
if let Some(url) = p.url {
|
||||||
i.link(url);
|
i.link(url);
|
||||||
|
@ -362,7 +369,7 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
|
||||||
|
|
||||||
// TODO add images
|
// TODO add images
|
||||||
let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
|
let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
|
||||||
author_url,
|
p.creator_actor_id,
|
||||||
p.creator_name,
|
p.creator_name,
|
||||||
community_url,
|
community_url,
|
||||||
p.community_name,
|
p.community_name,
|
||||||
|
@ -377,6 +384,7 @@ fn create_post_items(posts: Vec<PostView>) -> Result<Vec<Item>, LemmyError> {
|
||||||
|
|
||||||
i.description(description);
|
i.description(description);
|
||||||
|
|
||||||
|
i.dublin_core_ext(dc_extension.build().map_err(|e| anyhow!(e))?);
|
||||||
items.push(i.build().map_err(|e| anyhow!(e))?);
|
items.push(i.build().map_err(|e| anyhow!(e))?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue