diff --git a/crates/apub/src/collections/community_followers.rs b/crates/apub/src/collections/community_followers.rs new file mode 100644 index 000000000..41155b194 --- /dev/null +++ b/crates/apub/src/collections/community_followers.rs @@ -0,0 +1,38 @@ +use crate::generate_followers_url; +use activitystreams::collection::kind::CollectionType; +use lemmy_api_common::blocking; +use lemmy_db_schema::source::community::Community; +use lemmy_db_views_actor::community_follower_view::CommunityFollowerView; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CommunityFollowers { + id: Url, + r#type: CollectionType, + total_items: i32, + items: Vec<()>, +} + +impl CommunityFollowers { + pub(crate) async fn new( + community: Community, + context: &LemmyContext, + ) -> Result { + let community_id = community.id; + let community_followers = blocking(context.pool(), move |conn| { + CommunityFollowerView::for_community(conn, community_id) + }) + .await??; + + Ok(CommunityFollowers { + id: generate_followers_url(&community.actor_id)?.into_inner(), + r#type: CollectionType::Collection, + total_items: community_followers.len() as i32, + items: vec![], + }) + } +} diff --git a/crates/apub/src/collections/community_moderators.rs b/crates/apub/src/collections/community_moderators.rs index 2d190f4e2..d91b41c45 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -14,10 +14,8 @@ use lemmy_db_schema::{ use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView; use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; -use serde_with::skip_serializing_none; use url::Url; -#[skip_serializing_none] #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct GroupModerators { diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index 9d870f0e8..98fb66448 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -18,15 +18,14 @@ use lemmy_db_schema::{ }; use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; -use serde_with::skip_serializing_none; use url::Url; -#[skip_serializing_none] #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct GroupOutbox { r#type: OrderedCollectionType, id: Url, + total_items: i32, ordered_items: Vec, } @@ -83,6 +82,7 @@ impl ApubObject for ApubCommunityOutbox { Ok(GroupOutbox { r#type: OrderedCollectionType::OrderedCollection, id: generate_outbox_url(&data.0.actor_id)?.into(), + total_items: ordered_items.len() as i32, ordered_items, }) } diff --git a/crates/apub/src/collections/mod.rs b/crates/apub/src/collections/mod.rs index e2a274a01..378e14c04 100644 --- a/crates/apub/src/collections/mod.rs +++ b/crates/apub/src/collections/mod.rs @@ -1,8 +1,10 @@ use crate::objects::community::ApubCommunity; use lemmy_websocket::LemmyContext; +pub(crate) mod community_followers; pub(crate) mod community_moderators; pub(crate) mod community_outbox; +pub(crate) mod user_outbox; /// Put community in the data, so we dont have to read it again from the database. pub(crate) struct CommunityContext(pub ApubCommunity, pub LemmyContext); diff --git a/crates/apub/src/collections/user_outbox.rs b/crates/apub/src/collections/user_outbox.rs new file mode 100644 index 000000000..59c6975e4 --- /dev/null +++ b/crates/apub/src/collections/user_outbox.rs @@ -0,0 +1,26 @@ +use crate::generate_outbox_url; +use activitystreams::collection::kind::OrderedCollectionType; +use lemmy_db_schema::source::person::Person; +use lemmy_utils::LemmyError; +use serde::{Deserialize, Serialize}; +use url::Url; + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct UserOutbox { + r#type: OrderedCollectionType, + id: Url, + ordered_items: Vec<()>, + total_items: i32, +} + +impl UserOutbox { + pub(crate) async fn new(user: Person) -> Result { + Ok(UserOutbox { + r#type: OrderedCollectionType::OrderedCollection, + id: generate_outbox_url(&user.actor_id)?.into_inner(), + ordered_items: vec![], + total_items: 0, + }) + } +} diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 6c9c632e1..73f59d035 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -6,6 +6,7 @@ use crate::{ verify_person_in_community, }, collections::{ + community_followers::CommunityFollowers, community_moderators::ApubCommunityModerators, community_outbox::ApubCommunityOutbox, CommunityContext, @@ -21,10 +22,6 @@ use crate::{ }, objects::community::ApubCommunity, }; -use activitystreams::{ - base::BaseExt, - collection::{CollectionExt, UnorderedCollection}, -}; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ @@ -32,7 +29,6 @@ use lemmy_apub_lib::{ verify::verify_domains_match, }; use lemmy_db_schema::source::community::Community; -use lemmy_db_views_actor::community_follower_view::CommunityFollowerView; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use log::info; @@ -118,19 +114,8 @@ pub(crate) async fn get_apub_community_followers( Community::read_from_name(conn, &info.community_name) }) .await??; - - let community_id = community.id; - let community_followers = blocking(context.pool(), move |conn| { - CommunityFollowerView::for_community(conn, community_id) - }) - .await??; - - let mut collection = UnorderedCollection::new(); - collection - .set_id(community.followers_url.into()) - .set_total_items(community_followers.len() as u64); - let collection = WithContext::new(collection); - Ok(create_apub_response(&collection)) + let followers = CommunityFollowers::new(community, &context).await?; + Ok(create_apub_response(&followers)) } /// Returns the community outbox, which is populated by a maximum of 20 posts (but no other diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 2cc187681..a2d4fedd8 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -8,8 +8,8 @@ use crate::{ undo_delete::UndoDeletePrivateMessage, }, }, + collections::user_outbox::UserOutbox, context::WithContext, - generate_outbox_url, http::{ create_apub_response, create_apub_tombstone_response, @@ -18,10 +18,6 @@ use crate::{ }, objects::person::ApubPerson, }; -use activitystreams::{ - base::BaseExt, - collection::{CollectionExt, OrderedCollection}, -}; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ApubObject}; @@ -30,7 +26,6 @@ use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use log::info; use serde::{Deserialize, Serialize}; -use url::Url; #[derive(Deserialize)] pub struct PersonQuery { @@ -100,12 +95,6 @@ pub(crate) async fn get_apub_person_outbox( Person::find_by_name(conn, &info.user_name) }) .await??; - // TODO: populate the person outbox - let mut collection = OrderedCollection::new(); - collection - .set_many_items(Vec::::new()) - .set_id(generate_outbox_url(&person.actor_id)?.into()) - .set_total_items(0_u64); - let collection = WithContext::new(collection); - Ok(create_apub_response(&collection)) + let outbox = UserOutbox::new(person).await?; + Ok(create_apub_response(&outbox)) }