volumes:
- ./volumes/postgres_beta:/var/lib/postgresql/data
restart: always
+
+ iframely:
+ image: dogbin/iframely:latest
+ ports:
+ - "127.0.0.1:8061:80"
+ volumes:
+ - ./iframely.config.local.js:/iframely/config.local.js:ro
+ restart: always
# It is not intended for manual editing.
[[package]]
name = "activitystreams"
-version = "0.4.0-alpha.3"
+version = "0.5.0-alpha.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "activitystreams-derive 0.4.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "activitystreams-derive 0.5.0-alpha.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "activitystreams-derive"
-version = "0.4.0-alpha.2"
+version = "0.5.0-alpha.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "ctor"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "curl"
version = "0.4.26"
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "erased-serde"
-version = "0.3.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "error-chain"
version = "0.12.1"
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "ghost"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "h2"
version = "0.1.26"
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "inventory"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "ctor 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "inventory-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "inventory-impl"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "iovec"
version = "0.1.4"
name = "lemmy_server"
version = "0.0.1"
dependencies = [
- "activitystreams 0.4.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "activitystreams 0.5.0-alpha.0 (registry+https://github.com/rust-lang/crates.io-index)",
"actix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-files 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "typetag"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "inventory 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
- "typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "typetag-impl"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "unicase"
version = "2.6.0"
]
[metadata]
-"checksum activitystreams 0.4.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cb3bd10f03af2030e904226c7c1d86ba96e8993f93f7f73959ea78833c00a314"
-"checksum activitystreams-derive 0.4.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbb2213ea81c06ac7d5ce5947be3c1c4623bea2ce2303884cb9acdd29c067cb4"
+"checksum activitystreams 0.5.0-alpha.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48f1b48fa9d528f1f5fdef4c54622e7d84f1fd2c4fdfb1ef474b424ae89dc462"
+"checksum activitystreams-derive 0.5.0-alpha.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab374464a70b290cf771fc15ca2f096feb9ad9f5a7b86564219727e23421d59e"
"checksum actix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4af87564ff659dee8f9981540cac9418c45e910c8072fdedd643a262a38fcaf"
"checksum actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380"
"checksum actix-connect 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c95cc9569221e9802bf4c377f6c18b90ef10227d787611decf79fd47d2a8e76c"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
-"checksum ctor 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1"
"checksum curl 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "ecb534fed9060d04bccaa8b8e1e2d3d5a0d7a9ec6d9c667691c80a3c6b7d19ef"
"checksum curl-sys 0.4.28+curl-7.69.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c6b7fa5d36aa192e410788b77af65f339af24c8786419e8b48173689a484bf"
"checksum darling 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
"checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28"
"checksum enum-as-inner 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4bfcfacb61d231109d1d55202c1f33263319668b168843e02ad4652725ec9c"
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
-"checksum erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9"
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
"checksum failure 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b"
"checksum failure_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
-"checksum ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
"checksum h2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9d5c295d1c0c68e4e42003d75f908f5e16a1edd1cbe0b0d02e4dc2006a384f47"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
-"checksum inventory 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf98296081bd2cb540acc09ef9c97f22b7e487841520350293605db1b2c7a27"
-"checksum inventory-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8e30575afe28eea36a9a39136b70b2fb6b0dd0a212a5bd1f30a498395c0274"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f"
"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
-"checksum typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebb2c484029d695fb68a06d80e1536c68d491b3e0cf874c66abed255e831cfe"
-"checksum typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204"
"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
diesel_migrations = "1.4.0"
dotenv = "0.15.0"
bcrypt = "0.6.1"
-activitystreams = "0.4.0-alpha.3"
+activitystreams = "0.5.0-alpha.0"
chrono = { version = "0.4.7", features = ["serde"] }
failure = "0.1.5"
serde_json = { version = "1.0.45", features = ["preserve_order"]}
pub online: usize,
}
-#[derive(Serialize, Deserialize)]
+#[derive(Serialize, Deserialize, Debug)]
pub struct GetPosts {
type_: String,
sort: String,
use crate::db::community::Community;
use crate::db::community_view::CommunityFollowerView;
use crate::db::establish_unpooled_connection;
+use crate::db::post_view::{PostQueryBuilder, PostView};
+use activitystreams::collection::apub::OrderedCollection;
use activitystreams::{
actor::apub::Group, collection::apub::UnorderedCollection, context,
object::properties::ObjectProperties,
Ok(group)
}
- pub fn followers_as_collection(&self) -> Result<UnorderedCollection, Error> {
+ pub fn get_followers(&self) -> Result<UnorderedCollection, Error> {
let base_url = make_apub_endpoint("c", &self.name);
let connection = establish_unpooled_connection();
.set_total_items(community_followers.len() as u64)?;
Ok(collection)
}
+
+ pub fn get_outbox(&self) -> Result<OrderedCollection, Error> {
+ let base_url = make_apub_endpoint("c", &self.name);
+
+ let connection = establish_unpooled_connection();
+ //As we are an object, we validated that the community id was valid
+ let community_posts: Vec<PostView> = PostQueryBuilder::create(&connection)
+ .for_community_id(self.id)
+ .list()
+ .unwrap();
+
+ let mut collection = OrderedCollection::default();
+ let oprops: &mut ObjectProperties = collection.as_mut();
+ oprops
+ .set_context_xsd_any_uri(context())?
+ .set_id(base_url)?;
+ collection
+ .collection_props
+ .set_many_items_object_boxs(
+ community_posts
+ .iter()
+ .map(|c| c.as_page().unwrap())
+ .collect(),
+ )?
+ .set_total_items(community_posts.len() as u64)?;
+
+ Ok(collection)
+ }
}
#[derive(Deserialize)]
community_name: String,
}
+// TODO: move all this boilerplate code to routes::federation or such
pub async fn get_apub_community(info: Path<CommunityQuery>) -> Result<HttpResponse<Body>, Error> {
let connection = establish_unpooled_connection();
Ok(
HttpResponse::Ok()
.content_type("application/activity+json")
- .body(serde_json::to_string(&community.followers_as_collection()?).unwrap()),
+ .body(serde_json::to_string(&community.get_followers()?).unwrap()),
+ )
+ } else {
+ Ok(HttpResponse::NotFound().finish())
+ }
+}
+
+pub async fn get_apub_community_outbox(
+ info: Path<CommunityQuery>,
+) -> Result<HttpResponse<Body>, Error> {
+ let connection = establish_unpooled_connection();
+
+ if let Ok(community) = Community::read_from_name(&connection, info.community_name.to_owned()) {
+ Ok(
+ HttpResponse::Ok()
+ .content_type("application/activity+json")
+ .body(serde_json::to_string(&community.get_outbox()?).unwrap()),
)
} else {
Ok(HttpResponse::NotFound().finish())
#[cfg(test)]
mod tests {
use crate::db::community::Community;
- use crate::db::post::Post;
use crate::db::user::User_;
use crate::db::{ListingType, SortType};
use crate::{naive_now, Settings};
group.unwrap().object_props.get_id().unwrap().to_string()
);
}
-
- #[test]
- fn test_post() {
- let post = Post {
- id: 62,
- name: "A test post".into(),
- url: None,
- body: None,
- creator_id: 52,
- community_id: 42,
- published: naive_now(),
- removed: false,
- locked: false,
- stickied: false,
- nsfw: false,
- deleted: false,
- updated: None,
- embed_title: None,
- embed_description: None,
- embed_html: None,
- thumbnail_url: None,
- };
-
- let page = post.as_page();
- assert_eq!(
- format!("https://{}/federation/post/62", Settings::get().hostname),
- page.unwrap().object_props.get_id().unwrap().to_string()
- );
- }
}
// TODO: this should take an enum community/user/post for `point`
use crate::apub::make_apub_endpoint;
use crate::convert_datetime;
-use crate::db::post::Post;
-use activitystreams::{context, object::apub::Page, object::properties::ObjectProperties};
+use crate::db::post_view::PostView;
+use activitystreams::{object::apub::Page, object::properties::ObjectProperties};
use failure::Error;
-impl Post {
+impl PostView {
pub fn as_page(&self) -> Result<Page, Error> {
let base_url = make_apub_endpoint("post", self.id);
let mut page = Page::default();
let oprops: &mut ObjectProperties = page.as_mut();
oprops
- .set_context_xsd_any_uri(context())?
+ // Not needed when the Post is embedded in a collection (like for community outbox)
+ //.set_context_xsd_any_uri(context())?
.set_id(base_url)?
.set_name_xsd_string(self.name.to_owned())?
.set_published(convert_datetime(self.published))?
oprops.set_content_xsd_string(body.to_owned())?;
}
- if let Some(url) = &self.url {
- oprops.set_url_xsd_any_uri(url.to_owned())?;
+ if let Some(_url) = &self.url {
+ // TODO: crashes here
+ //oprops.set_url_xsd_any_uri(url.to_owned())?;
}
if let Some(u) = self.updated {
extern crate reqwest;
use crate::api::community::{GetCommunityResponse, ListCommunitiesResponse};
-use crate::api::post::GetPosts;
+use crate::api::post::GetPostsResponse;
use crate::db::community_view::CommunityView;
use crate::settings::Settings;
use activitystreams::actor::apub::Group;
-use activitystreams::collection::apub::UnorderedCollection;
+use activitystreams::collection::apub::{OrderedCollection, UnorderedCollection};
use failure::Error;
// TODO: right now all of the data is requested on demand, for production we will need to store
Ok(communities2)
}
-pub fn get_remote_community_posts(name: String) -> Result<GetPosts, Error> {
- // TODO: this is for urls like /c/!main@example.com, activitypub exposes it through the outbox
- // https://www.w3.org/TR/activitypub/#outbox
- dbg!(name);
+// TODO: this should be cached or stored in the database
+fn get_remote_community_uri(identifier: String) -> String {
+ let x: Vec<&str> = identifier.split('@').collect();
+ let name = x[0].replace("!", "");
+ let instance = x[1];
+ format!("http://{}/federation/c/{}", instance, name)
+}
+
+pub fn get_remote_community_posts(identifier: String) -> Result<GetPostsResponse, Error> {
+ let community: Group = reqwest::get(&get_remote_community_uri(identifier))?.json()?;
+ let outbox_uri = &community.ap_actor_props.get_outbox().to_string();
+ let outbox: OrderedCollection = reqwest::get(outbox_uri)?.json()?;
+ let items = outbox.collection_props.get_many_items_object_boxs();
+ dbg!(items);
unimplemented!()
}
pub fn get_remote_community(identifier: String) -> Result<GetCommunityResponse, failure::Error> {
- let x: Vec<&str> = identifier.split('@').collect();
- let name = x[0].replace("!", "");
- let instance = x[1];
- let community_uri = format!("http://{}/federation/c/{}", instance, name);
- let community: Group = reqwest::get(&community_uri)?.json()?;
+ let community: Group = reqwest::get(&get_remote_community_uri(identifier.clone()))?.json()?;
let followers_uri = &community
.ap_actor_props
.get_followers()
.unwrap()
.to_string();
+ let outbox_uri = &community.ap_actor_props.get_outbox().to_string();
+ let outbox: OrderedCollection = reqwest::get(outbox_uri)?.json()?;
+ // TODO: this need to be done in get_remote_community_posts() (meaning we need to store the outbox uri?)
let followers: UnorderedCollection = reqwest::get(followers_uri)?.json()?;
// TODO: looks like a bunch of data is missing from the activitypub response
admins: vec![],
community: CommunityView {
// TODO: we need to merge id and name into a single thing (stuff like @user@instance.com)
- id: -1, //community.object_props.get_id()
- name,
+ id: 1337, //community.object_props.get_id()
+ name: identifier,
title: community
.object_props
.get_name_xsd_string()
.get_total_items()
.unwrap()
.as_ref() as i64, // TODO: need to use the same type
- number_of_posts: -1,
+ number_of_posts: *outbox.collection_props.get_total_items().unwrap().as_ref() as i64,
number_of_comments: -1,
hot_rank: -1,
user_id: None,
"/federation/c/{community_name}/followers",
web::get().to(apub::community::get_apub_community_followers),
)
+ .route(
+ "/federation/c/{community_name}/outbox",
+ web::get().to(apub::community::get_apub_community_outbox),
+ )
.route(
"/federation/u/{user_name}",
web::get().to(apub::user::get_apub_user),
}
UserOperation::GetPosts => {
let get_posts: GetPosts = serde_json::from_str(data)?;
+ dbg!(&get_posts);
+ // TODO: intercept here (but the type is wrong)
+ //get_remote_community_posts(get_posts.community_id.unwrap())
if get_posts.community_id.is_none() {
// 0 is the "all" community
chat.join_community_room(0, msg.id);