Add Atom feeds for blogs and users
This commit is contained in:
parent
5cb994c15b
commit
97c0b533ab
|
@ -89,6 +89,16 @@ dependencies = [
|
||||||
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atom_syndication"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
@ -332,6 +342,25 @@ dependencies = [
|
||||||
"syntex_fmt_macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex_fmt_macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder_core"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diesel"
|
name = "diesel"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
|
@ -985,6 +1014,7 @@ name = "plume"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"activitypub 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"atom_syndication 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1100,6 +1130,16 @@ dependencies = [
|
||||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
@ -2074,6 +2114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||||
"checksum array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271"
|
"checksum array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271"
|
||||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||||
|
"checksum atom_syndication 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a9a7ab83635ff7a3b04856f4ad95324dccc9b947ab1e790fc5c769ee6d6f60c"
|
||||||
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
||||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||||
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
|
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
|
||||||
|
@ -2103,6 +2144,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum csrf 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "38f2ee2a7e76740d81de006e61eff53206c56448a30d8017b4ac97b5486682bd"
|
"checksum csrf 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "38f2ee2a7e76740d81de006e61eff53206c56448a30d8017b4ac97b5486682bd"
|
||||||
"checksum data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67df0571a74bf0d97fb8b2ed22abdd9a48475c96bd327db968b7d9cace99655e"
|
"checksum data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67df0571a74bf0d97fb8b2ed22abdd9a48475c96bd327db968b7d9cace99655e"
|
||||||
"checksum derive-error-chain 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4450afbe280461e78299b39182a085b70e3e71be049cf4a588ad72f1e44d33"
|
"checksum derive-error-chain 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4450afbe280461e78299b39182a085b70e3e71be049cf4a588ad72f1e44d33"
|
||||||
|
"checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439"
|
||||||
|
"checksum derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757"
|
||||||
"checksum diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24815a0c2094f2c8dafe74ab3b9e975892f44acbb94b4d4b4898025a7615efa4"
|
"checksum diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24815a0c2094f2c8dafe74ab3b9e975892f44acbb94b4d4b4898025a7615efa4"
|
||||||
"checksum diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6471a2b637b414d3ee1504cf230409a550381c79204282f8fe06c527e4ae56be"
|
"checksum diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6471a2b637b414d3ee1504cf230409a550381c79204282f8fe06c527e4ae56be"
|
||||||
"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc"
|
"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc"
|
||||||
|
@ -2186,6 +2229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
||||||
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
||||||
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
||||||
|
"checksum quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b14c27e04216596a49f2b82398a24f67ed9f131a5c0e0235496ea446bdacfb12"
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
|
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
|
||||||
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
||||||
|
|
|
@ -4,6 +4,7 @@ name = "plume"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
activitypub = "0.1.1"
|
activitypub = "0.1.1"
|
||||||
|
atom_syndication = "0.6"
|
||||||
colored = "1.6"
|
colored = "1.6"
|
||||||
dotenv = "*"
|
dotenv = "*"
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use activitypub::{Object, activity::{Create, Delete}};
|
use activitypub::{Object, activity::Create};
|
||||||
|
|
||||||
use activity_pub::Id;
|
use activity_pub::Id;
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl FromActivity<Note, PgConnection> for Comment {
|
||||||
sensitive: false // "sensitive" is not a standard property, we need to think about how to support it with the activitypub crate
|
sensitive: false // "sensitive" is not a standard property, we need to think about how to support it with the activitypub crate
|
||||||
});
|
});
|
||||||
|
|
||||||
// save mentions
|
// save mentionsd
|
||||||
if let Some(serde_json::Value::Array(tags)) = note.object_props.tag.clone() {
|
if let Some(serde_json::Value::Array(tags)) = note.object_props.tag.clone() {
|
||||||
for tag in tags.into_iter() {
|
for tag in tags.into_iter() {
|
||||||
serde_json::from_value::<link::Mention>(tag)
|
serde_json::from_value::<link::Mention>(tag)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![plugin(rocket_codegen)]
|
#![plugin(rocket_codegen)]
|
||||||
|
|
||||||
extern crate activitypub;
|
extern crate activitypub;
|
||||||
|
extern crate atom_syndication;
|
||||||
extern crate colored;
|
extern crate colored;
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
extern crate dotenv;
|
extern crate dotenv;
|
||||||
|
@ -45,6 +46,7 @@ fn main() {
|
||||||
routes::blogs::new,
|
routes::blogs::new,
|
||||||
routes::blogs::new_auth,
|
routes::blogs::new_auth,
|
||||||
routes::blogs::create,
|
routes::blogs::create,
|
||||||
|
routes::blogs::atom_feed,
|
||||||
|
|
||||||
routes::comments::create,
|
routes::comments::create,
|
||||||
|
|
||||||
|
@ -98,6 +100,7 @@ fn main() {
|
||||||
routes::user::ap_followers,
|
routes::user::ap_followers,
|
||||||
routes::user::new,
|
routes::user::new,
|
||||||
routes::user::create,
|
routes::user::create,
|
||||||
|
routes::user::atom_feed,
|
||||||
|
|
||||||
routes::well_known::host_meta,
|
routes::well_known::host_meta,
|
||||||
routes::well_known::nodeinfo,
|
routes::well_known::nodeinfo,
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use activitypub::collection::OrderedCollection;
|
use activitypub::collection::OrderedCollection;
|
||||||
|
use atom_syndication::{Entry, FeedBuilder};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
request::LenientForm,
|
request::LenientForm,
|
||||||
response::{Redirect, Flash}
|
response::{Redirect, Flash, content::Content},
|
||||||
|
http::ContentType
|
||||||
};
|
};
|
||||||
use rocket_contrib::Template;
|
use rocket_contrib::Template;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
@ -129,3 +131,18 @@ fn outbox(name: String, conn: DbConn) -> ActivityStream<OrderedCollection> {
|
||||||
let blog = Blog::find_local(&*conn, name).unwrap();
|
let blog = Blog::find_local(&*conn, name).unwrap();
|
||||||
blog.outbox(&*conn)
|
blog.outbox(&*conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/~/<name>/atom.xml")]
|
||||||
|
fn atom_feed(name: String, conn: DbConn) -> Content<String> {
|
||||||
|
let blog = Blog::find_by_fqn(&*conn, name.clone()).expect("Unable to find blog");
|
||||||
|
let feed = FeedBuilder::default()
|
||||||
|
.title(blog.title.clone())
|
||||||
|
.id(Instance::get_local(&*conn).unwrap().compute_box("~", name, "atom.xml"))
|
||||||
|
.entries(Post::get_recents_for_blog(&*conn, &blog, 15)
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| super::post_to_atom(p, &*conn))
|
||||||
|
.collect::<Vec<Entry>>())
|
||||||
|
.build()
|
||||||
|
.expect("Error building Atom feed");
|
||||||
|
Content(ContentType::new("application", "atom+xml"), feed.to_string())
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use atom_syndication::{ContentBuilder, Entry, EntryBuilder, LinkBuilder, Person, PersonBuilder};
|
||||||
|
use diesel::PgConnection;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
http::uri::{FromUriParam, UriDisplay},
|
http::uri::{FromUriParam, UriDisplay},
|
||||||
response::NamedFile
|
response::NamedFile
|
||||||
|
@ -7,6 +9,8 @@ use std::{
|
||||||
path::{Path, PathBuf}
|
path::{Path, PathBuf}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use plume_models::posts::Post;
|
||||||
|
|
||||||
macro_rules! may_fail {
|
macro_rules! may_fail {
|
||||||
($account:expr, $expr:expr, $template:expr, $msg:expr, | $res:ident | $block:block) => {
|
($account:expr, $expr:expr, $template:expr, $msg:expr, | $res:ident | $block:block) => {
|
||||||
{
|
{
|
||||||
|
@ -75,6 +79,25 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn post_to_atom(post: Post, conn: &PgConnection) -> Entry {
|
||||||
|
EntryBuilder::default()
|
||||||
|
.title(post.title.clone())
|
||||||
|
.content(ContentBuilder::default()
|
||||||
|
.value(format!("<![CDATA[{}]]>", *post.content.get()))
|
||||||
|
.src(post.ap_url.clone())
|
||||||
|
.content_type("html".to_string())
|
||||||
|
.build().expect("Atom feed: content error"))
|
||||||
|
.authors(post.get_authors(&*conn)
|
||||||
|
.into_iter()
|
||||||
|
.map(|a| PersonBuilder::default()
|
||||||
|
.name(a.display_name)
|
||||||
|
.uri(a.ap_url)
|
||||||
|
.build().expect("Atom feed: author error"))
|
||||||
|
.collect::<Vec<Person>>())
|
||||||
|
.links(vec![LinkBuilder::default().href(post.ap_url).build().expect("Atom feed: link error")])
|
||||||
|
.build().expect("Atom feed: entry error")
|
||||||
|
}
|
||||||
|
|
||||||
pub mod blogs;
|
pub mod blogs;
|
||||||
pub mod comments;
|
pub mod comments;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
|
|
@ -3,10 +3,12 @@ use activitypub::{
|
||||||
collection::OrderedCollection,
|
collection::OrderedCollection,
|
||||||
object::Article
|
object::Article
|
||||||
};
|
};
|
||||||
|
use atom_syndication::{Entry, FeedBuilder};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
State,
|
State,
|
||||||
request::LenientForm,
|
request::LenientForm,
|
||||||
response::{Redirect, Flash}
|
response::{Redirect, Flash, Content},
|
||||||
|
http::ContentType
|
||||||
};
|
};
|
||||||
use rocket_contrib::Template;
|
use rocket_contrib::Template;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
@ -276,3 +278,18 @@ fn ap_followers(name: String, conn: DbConn, _ap: ApRequest) -> ActivityStream<Or
|
||||||
coll.collection_props.set_items_link_vec(followers).expect("Follower collection: items error");
|
coll.collection_props.set_items_link_vec(followers).expect("Follower collection: items error");
|
||||||
ActivityStream::new(coll)
|
ActivityStream::new(coll)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/@/<name>/atom.xml")]
|
||||||
|
fn atom_feed(name: String, conn: DbConn) -> Content<String> {
|
||||||
|
let author = User::find_by_fqn(&*conn, name.clone()).expect("Unable to find author");
|
||||||
|
let feed = FeedBuilder::default()
|
||||||
|
.title(author.display_name.clone())
|
||||||
|
.id(Instance::get_local(&*conn).unwrap().compute_box("~", name, "atom.xml"))
|
||||||
|
.entries(Post::get_recents_for_author(&*conn, &author, 15)
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| super::post_to_atom(p, &*conn))
|
||||||
|
.collect::<Vec<Entry>>())
|
||||||
|
.build()
|
||||||
|
.expect("Error building Atom feed");
|
||||||
|
Content(ContentType::new("application", "atom+xml"), feed.to_string())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue