2 activity_lists::GroupInboxActivities,
4 community_featured::ApubCommunityFeatured,
5 community_moderators::ApubCommunityModerators,
6 community_outbox::ApubCommunityOutbox,
8 http::{create_apub_response, create_apub_tombstone_response},
9 objects::{community::ApubCommunity, person::ApubPerson},
10 protocol::collections::group_followers::GroupFollowers,
12 use activitypub_federation::{
13 actix_web::inbox::receive_activity,
15 protocol::context::WithContext,
16 traits::{Collection, Object},
18 use actix_web::{web, web::Bytes, HttpRequest, HttpResponse};
19 use lemmy_api_common::context::LemmyContext;
20 use lemmy_db_schema::{source::community::Community, traits::ApubActor};
21 use lemmy_utils::error::{LemmyError, LemmyErrorType};
22 use serde::Deserialize;
24 #[derive(Deserialize)]
25 pub(crate) struct CommunityQuery {
26 community_name: String,
29 /// Return the ActivityPub json representation of a local community over HTTP.
30 #[tracing::instrument(skip_all)]
31 pub(crate) async fn get_apub_community_http(
32 info: web::Path<CommunityQuery>,
33 context: Data<LemmyContext>,
34 ) -> Result<HttpResponse, LemmyError> {
35 let community: ApubCommunity =
36 Community::read_from_name(&mut context.pool(), &info.community_name, true)
40 if !community.deleted && !community.removed {
41 let apub = community.into_json(&context).await?;
43 create_apub_response(&apub)
45 create_apub_tombstone_response(community.actor_id.clone())
49 /// Handler for all incoming receive to community inboxes.
50 #[tracing::instrument(skip_all)]
51 pub async fn community_inbox(
54 data: Data<LemmyContext>,
55 ) -> Result<HttpResponse, LemmyError> {
56 receive_activity::<WithContext<GroupInboxActivities>, ApubPerson, LemmyContext>(
62 /// Returns an empty followers collection, only populating the size (for privacy).
63 pub(crate) async fn get_apub_community_followers(
64 info: web::Path<CommunityQuery>,
65 context: Data<LemmyContext>,
66 ) -> Result<HttpResponse, LemmyError> {
68 Community::read_from_name(&mut context.pool(), &info.community_name, false).await?;
69 let followers = GroupFollowers::new(community, &context).await?;
70 create_apub_response(&followers)
73 /// Returns the community outbox, which is populated by a maximum of 20 posts (but no other
74 /// activites like votes or comments).
75 pub(crate) async fn get_apub_community_outbox(
76 info: web::Path<CommunityQuery>,
77 context: Data<LemmyContext>,
78 ) -> Result<HttpResponse, LemmyError> {
79 let community: ApubCommunity =
80 Community::read_from_name(&mut context.pool(), &info.community_name, false)
83 if community.deleted || community.removed {
84 return Err(LemmyErrorType::Deleted)?;
86 let outbox = ApubCommunityOutbox::read_local(&community, &context).await?;
87 create_apub_response(&outbox)
90 #[tracing::instrument(skip_all)]
91 pub(crate) async fn get_apub_community_moderators(
92 info: web::Path<CommunityQuery>,
93 context: Data<LemmyContext>,
94 ) -> Result<HttpResponse, LemmyError> {
95 let community: ApubCommunity =
96 Community::read_from_name(&mut context.pool(), &info.community_name, false)
99 if community.deleted || community.removed {
100 return Err(LemmyErrorType::Deleted)?;
102 let moderators = ApubCommunityModerators::read_local(&community, &context).await?;
103 create_apub_response(&moderators)
106 /// Returns collection of featured (stickied) posts.
107 pub(crate) async fn get_apub_community_featured(
108 info: web::Path<CommunityQuery>,
109 context: Data<LemmyContext>,
110 ) -> Result<HttpResponse, LemmyError> {
111 let community: ApubCommunity =
112 Community::read_from_name(&mut context.pool(), &info.community_name, false)
115 if community.deleted || community.removed {
116 return Err(LemmyErrorType::Deleted)?;
118 let featured = ApubCommunityFeatured::read_local(&community, &context).await?;
119 create_apub_response(&featured)