2 fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
4 announce_if_community_is_local,
5 get_community_id_from_activity,
6 get_user_from_activity,
7 receive_unhandled_activity,
14 use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
15 use actix_web::HttpResponse;
16 use anyhow::{anyhow, Context};
18 comment::{Comment, CommentForm},
19 comment_view::CommentView,
20 community::{Community, CommunityForm},
21 community_view::CommunityView,
23 post::{Post, PostForm},
29 comment::CommentResponse,
30 community::CommunityResponse,
33 use lemmy_utils::{location_info, LemmyError};
34 use lemmy_websocket::{
35 messages::{SendComment, SendCommunityRoomMessage, SendPost},
40 pub async fn receive_remove(
42 context: &LemmyContext,
43 ) -> Result<HttpResponse, LemmyError> {
44 let remove = Remove::from_any_base(activity)?.context(location_info!())?;
45 let actor = get_user_from_activity(&remove, context).await?;
46 let community = get_community_id_from_activity(&remove)?;
47 if actor.actor_id()?.domain() != community.domain() {
48 return Err(anyhow!("Remove activities are only allowed on local objects").into());
51 match remove.object().as_single_kind_str() {
52 Some("Page") => receive_remove_post(remove, context).await,
53 Some("Note") => receive_remove_comment(remove, context).await,
54 Some("Group") => receive_remove_community(remove, context).await,
55 _ => receive_unhandled_activity(remove),
59 async fn receive_remove_post(
61 context: &LemmyContext,
62 ) -> Result<HttpResponse, LemmyError> {
63 let mod_ = get_user_from_activity(&remove, context).await?;
64 let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
65 .context(location_info!())?;
67 let post_ap_id = PostForm::from_apub(&page, context, None)
71 let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
73 let post_form = PostForm {
74 name: post.name.to_owned(),
75 url: post.url.to_owned(),
76 body: post.body.to_owned(),
77 creator_id: post.creator_id.to_owned(),
78 community_id: post.community_id,
84 updated: Some(naive_now()),
85 embed_title: post.embed_title,
86 embed_description: post.embed_description,
87 embed_html: post.embed_html,
88 thumbnail_url: post.thumbnail_url,
89 ap_id: Some(post.ap_id),
93 let post_id = post.id;
94 blocking(context.pool(), move |conn| {
95 Post::update(conn, post_id, &post_form)
100 let post_id = post.id;
101 let post_view = blocking(context.pool(), move |conn| {
102 PostView::read(conn, post_id, None)
106 let res = PostResponse { post: post_view };
108 context.chat_server().do_send(SendPost {
109 op: UserOperation::EditPost,
114 announce_if_community_is_local(remove, &mod_, context).await?;
115 Ok(HttpResponse::Ok().finish())
118 async fn receive_remove_comment(
120 context: &LemmyContext,
121 ) -> Result<HttpResponse, LemmyError> {
122 let mod_ = get_user_from_activity(&remove, context).await?;
123 let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
124 .context(location_info!())?;
126 let comment_ap_id = CommentForm::from_apub(¬e, context, None)
130 let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
132 let comment_form = CommentForm {
133 content: comment.content.to_owned(),
134 parent_id: comment.parent_id,
135 post_id: comment.post_id,
136 creator_id: comment.creator_id,
141 updated: Some(naive_now()),
142 ap_id: Some(comment.ap_id),
143 local: comment.local,
145 let comment_id = comment.id;
146 blocking(context.pool(), move |conn| {
147 Comment::update(conn, comment_id, &comment_form)
152 let comment_id = comment.id;
153 let comment_view = blocking(context.pool(), move |conn| {
154 CommentView::read(conn, comment_id, None)
158 // TODO get those recipient actor ids from somewhere
159 let recipient_ids = vec![];
160 let res = CommentResponse {
161 comment: comment_view,
166 context.chat_server().do_send(SendComment {
167 op: UserOperation::EditComment,
172 announce_if_community_is_local(remove, &mod_, context).await?;
173 Ok(HttpResponse::Ok().finish())
176 async fn receive_remove_community(
178 context: &LemmyContext,
179 ) -> Result<HttpResponse, LemmyError> {
180 let mod_ = get_user_from_activity(&remove, context).await?;
181 let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
182 .context(location_info!())?;
184 let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
187 .context(location_info!())?;
189 let community = blocking(context.pool(), move |conn| {
190 Community::read_from_actor_id(conn, &community_actor_id)
194 let community_form = CommunityForm {
195 name: community.name.to_owned(),
196 title: community.title.to_owned(),
197 description: community.description.to_owned(),
198 category_id: community.category_id, // Note: need to keep this due to foreign key constraint
199 creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
202 updated: Some(naive_now()),
204 nsfw: community.nsfw,
205 actor_id: Some(community.actor_id),
206 local: community.local,
207 private_key: community.private_key,
208 public_key: community.public_key,
209 last_refreshed_at: None,
210 icon: Some(community.icon.to_owned()),
211 banner: Some(community.banner.to_owned()),
214 let community_id = community.id;
215 blocking(context.pool(), move |conn| {
216 Community::update(conn, community_id, &community_form)
220 let community_id = community.id;
221 let res = CommunityResponse {
222 community: blocking(context.pool(), move |conn| {
223 CommunityView::read(conn, community_id, None)
228 let community_id = res.community.id;
230 context.chat_server().do_send(SendCommunityRoomMessage {
231 op: UserOperation::EditCommunity,
237 announce_if_community_is_local(remove, &mod_, context).await?;
238 Ok(HttpResponse::Ok().finish())