]> Untitled Git - lemmy.git/commitdiff
WIP: federate posts between instances
authorFelix Ableitner <me@nutomic.com>
Sat, 14 Mar 2020 00:05:42 +0000 (01:05 +0100)
committerFelix Ableitner <me@nutomic.com>
Sat, 14 Mar 2020 00:05:42 +0000 (01:05 +0100)
docker/federation-test/docker-compose.yml
server/Cargo.lock
server/Cargo.toml
server/src/api/post.rs
server/src/apub/community.rs
server/src/apub/mod.rs
server/src/apub/post.rs
server/src/apub/puller.rs
server/src/routes/federation.rs
server/src/websocket/server.rs

index 464d7081295b8214421dc4d63165d069c39fe428..1a7265e1ba6fa760d0752025a680bfd1c7f81b09 100644 (file)
@@ -52,3 +52,11 @@ services:
     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
index 3b44606b0f4f9e0254d70e1869a10b13adee11f5..9360230eac1f32fbbcc5f89ffb037d9d81728edb 100644 (file)
@@ -2,21 +2,21 @@
 # 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)",
@@ -772,15 +772,6 @@ dependencies = [
  "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"
@@ -1048,14 +1039,6 @@ dependencies = [
  "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"
@@ -1297,16 +1280,6 @@ dependencies = [
  "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"
@@ -1511,26 +1484,6 @@ dependencies = [
  "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"
@@ -1609,7 +1562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 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)",
@@ -3064,28 +3017,6 @@ name = "typenum"
 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"
@@ -3350,8 +3281,8 @@ dependencies = [
 ]
 
 [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"
@@ -3421,7 +3352,6 @@ dependencies = [
 "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"
@@ -3450,7 +3380,6 @@ dependencies = [
 "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"
@@ -3481,7 +3410,6 @@ dependencies = [
 "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"
@@ -3501,8 +3429,6 @@ dependencies = [
 "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"
@@ -3668,8 +3594,6 @@ dependencies = [
 "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"
index 4c41d4ade0e2e26b8af0b4d9ebf81e52521e613d..2efec965687307f1b9146dd73924dcba2e67516f 100644 (file)
@@ -9,7 +9,7 @@ diesel = { version = "1.4.2", features = ["postgres","chrono", "r2d2", "64-colum
 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"]}
index fb022589195e2d9bcaf1f2085d83d512c5e9ae1e..cefa5b076fc237b27ac7202cfdf71866978f54f3 100644 (file)
@@ -33,7 +33,7 @@ pub struct GetPostResponse {
   pub online: usize,
 }
 
-#[derive(Serialize, Deserialize)]
+#[derive(Serialize, Deserialize, Debug)]
 pub struct GetPosts {
   type_: String,
   sort: String,
index b5b365d0f24713e5bc73de080c9ce0a0ea612cf5..61b0b2ce2e5442866b3d7f811036a571d91a7e45 100644 (file)
@@ -3,6 +3,8 @@ use crate::convert_datetime;
 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,
@@ -43,7 +45,7 @@ impl Community {
     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();
@@ -60,6 +62,34 @@ impl Community {
       .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)]
@@ -67,6 +97,7 @@ pub struct CommunityQuery {
   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();
 
@@ -90,7 +121,23 @@ pub async fn get_apub_community_followers(
     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())
index 0fa665c50c37417f8e3fd80a92ee1d23a24810a2..6ce599929c6a5abcf53ed9e6aeaefb161a4f762e 100644 (file)
@@ -11,7 +11,6 @@ use url::Url;
 #[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};
@@ -69,35 +68,6 @@ mod tests {
       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`
index f0599eef25288e0cc082b12a5b7e9e396ebc1de9..6950e561a0e9679793c092ac2efc55edbf58a65a 100644 (file)
@@ -1,17 +1,18 @@
 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))?
@@ -21,8 +22,9 @@ impl Post {
       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 {
index aa34ce500faa16c2ae80701b738f32fc85ce40e2..941fbc3fad3b5baa917f59ce013d8c7dc6021da9 100644 (file)
@@ -1,11 +1,11 @@
 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
@@ -25,24 +25,33 @@ fn fetch_communities_from_instance(domain: &str) -> Result<Vec<CommunityView>, E
   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
@@ -52,8 +61,8 @@ pub fn get_remote_community(identifier: String) -> Result<GetCommunityResponse,
     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()
@@ -87,7 +96,7 @@ pub fn get_remote_community(identifier: String) -> Result<GetCommunityResponse,
         .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,
index 6816f1bc036f622db5a0d603db5b371dbbf4c542..0be051eb87d21d522c9adab80cbfe9f1076bba5a 100644 (file)
@@ -20,6 +20,10 @@ pub fn config(cfg: &mut web::ServiceConfig) {
         "/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),
index 727eb7d833117c220822e0a7a71da5609ef5fb07..21588a5884d88bc512551614abeb6d9facba4ad4 100644 (file)
@@ -648,6 +648,9 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result<Str
     }
     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);