3 fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
5 announce_if_community_is_local,
6 get_community_id_from_activity,
7 get_user_from_activity,
8 receive_unhandled_activity,
17 use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
18 use actix_web::HttpResponse;
19 use anyhow::{anyhow, Context};
21 comment::{Comment, CommentForm},
22 comment_view::CommentView,
23 community::{Community, CommunityForm},
24 community_view::CommunityView,
26 post::{Post, PostForm},
32 comment::CommentResponse,
33 community::CommunityResponse,
35 websocket::{SendComment, SendCommunityRoomMessage, SendPost, UserOperation},
37 use lemmy_utils::{location_info, LemmyError};
39 pub async fn receive_remove(
41 context: &LemmyContext,
42 ) -> Result<HttpResponse, LemmyError> {
43 let remove = Remove::from_any_base(activity)?.context(location_info!())?;
44 let actor = get_user_from_activity(&remove, context).await?;
45 let community = get_community_id_from_activity(&remove)?;
46 if actor.actor_id()?.domain() != community.domain() {
47 return Err(anyhow!("Remove activities are only allowed on local objects").into());
50 match remove.object().as_single_kind_str() {
51 Some("Page") => receive_remove_post(remove, context).await,
52 Some("Note") => receive_remove_comment(remove, context).await,
53 Some("Group") => receive_remove_community(remove, context).await,
54 _ => receive_unhandled_activity(remove),
58 async fn receive_remove_post(
60 context: &LemmyContext,
61 ) -> Result<HttpResponse, LemmyError> {
62 let mod_ = get_user_from_activity(&remove, context).await?;
63 let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
64 .context(location_info!())?;
66 let post_ap_id = PostForm::from_apub(&page, context, None)
70 let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
72 let post_form = PostForm {
73 name: post.name.to_owned(),
74 url: post.url.to_owned(),
75 body: post.body.to_owned(),
76 creator_id: post.creator_id.to_owned(),
77 community_id: post.community_id,
83 updated: Some(naive_now()),
84 embed_title: post.embed_title,
85 embed_description: post.embed_description,
86 embed_html: post.embed_html,
87 thumbnail_url: post.thumbnail_url,
88 ap_id: Some(post.ap_id),
92 let post_id = post.id;
93 blocking(context.pool(), move |conn| {
94 Post::update(conn, post_id, &post_form)
99 let post_id = post.id;
100 let post_view = blocking(context.pool(), move |conn| {
101 PostView::read(conn, post_id, None)
105 let res = PostResponse { post: post_view };
107 context.chat_server().do_send(SendPost {
108 op: UserOperation::EditPost,
113 announce_if_community_is_local(remove, &mod_, context).await?;
114 Ok(HttpResponse::Ok().finish())
117 async fn receive_remove_comment(
119 context: &LemmyContext,
120 ) -> Result<HttpResponse, LemmyError> {
121 let mod_ = get_user_from_activity(&remove, context).await?;
122 let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
123 .context(location_info!())?;
125 let comment_ap_id = CommentForm::from_apub(¬e, context, None)
129 let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
131 let comment_form = CommentForm {
132 content: comment.content.to_owned(),
133 parent_id: comment.parent_id,
134 post_id: comment.post_id,
135 creator_id: comment.creator_id,
140 updated: Some(naive_now()),
141 ap_id: Some(comment.ap_id),
142 local: comment.local,
144 let comment_id = comment.id;
145 blocking(context.pool(), move |conn| {
146 Comment::update(conn, comment_id, &comment_form)
151 let comment_id = comment.id;
152 let comment_view = blocking(context.pool(), move |conn| {
153 CommentView::read(conn, comment_id, None)
157 // TODO get those recipient actor ids from somewhere
158 let recipient_ids = vec![];
159 let res = CommentResponse {
160 comment: comment_view,
165 context.chat_server().do_send(SendComment {
166 op: UserOperation::EditComment,
171 announce_if_community_is_local(remove, &mod_, context).await?;
172 Ok(HttpResponse::Ok().finish())
175 async fn receive_remove_community(
177 context: &LemmyContext,
178 ) -> Result<HttpResponse, LemmyError> {
179 let mod_ = get_user_from_activity(&remove, context).await?;
180 let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
181 .context(location_info!())?;
183 let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
186 .context(location_info!())?;
188 let community = blocking(context.pool(), move |conn| {
189 Community::read_from_actor_id(conn, &community_actor_id)
193 let community_form = CommunityForm {
194 name: community.name.to_owned(),
195 title: community.title.to_owned(),
196 description: community.description.to_owned(),
197 category_id: community.category_id, // Note: need to keep this due to foreign key constraint
198 creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
201 updated: Some(naive_now()),
203 nsfw: community.nsfw,
204 actor_id: Some(community.actor_id),
205 local: community.local,
206 private_key: community.private_key,
207 public_key: community.public_key,
208 last_refreshed_at: None,
209 icon: Some(community.icon.to_owned()),
210 banner: Some(community.banner.to_owned()),
213 let community_id = community.id;
214 blocking(context.pool(), move |conn| {
215 Community::update(conn, community_id, &community_form)
219 let community_id = community.id;
220 let res = CommunityResponse {
221 community: blocking(context.pool(), move |conn| {
222 CommunityView::read(conn, community_id, None)
227 let community_id = res.community.id;
229 context.chat_server().do_send(SendCommunityRoomMessage {
230 op: UserOperation::EditCommunity,
236 announce_if_community_is_local(remove, &mod_, context).await?;
237 Ok(HttpResponse::Ok().finish())