2 api::{comment::CommentResponse, community::CommunityResponse, post::PostResponse},
4 fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
6 announce_if_community_is_local,
7 get_user_from_activity,
8 receive_unhandled_activity,
15 routes::ChatServerParam,
17 server::{SendComment, SendCommunityRoomMessage, SendPost},
23 use activitystreams::{activity::*, base::AnyBase, object::Note, prelude::*};
24 use actix_web::{client::Client, HttpResponse};
26 comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
27 comment_view::CommentView,
28 community::{Community, CommunityForm},
29 community_view::CommunityView,
31 post::{Post, PostForm, PostLike, PostLikeForm},
37 pub async fn receive_undo(
41 chat_server: ChatServerParam,
42 ) -> Result<HttpResponse, LemmyError> {
43 let undo = Undo::from_any_base(activity)?.unwrap();
44 match undo.object().as_single_kind_str() {
45 Some("Delete") => receive_undo_delete(undo, client, pool, chat_server).await,
46 Some("Remove") => receive_undo_remove(undo, client, pool, chat_server).await,
47 Some("Like") => receive_undo_like(undo, client, pool, chat_server).await,
48 Some("Dislike") => receive_undo_dislike(undo, client, pool, chat_server).await,
49 // TODO: handle undo_dislike?
50 _ => receive_unhandled_activity(undo),
54 async fn receive_undo_delete(
58 chat_server: ChatServerParam,
59 ) -> Result<HttpResponse, LemmyError> {
60 let delete = Delete::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap();
61 let type_ = delete.object().as_single_kind_str().unwrap();
63 "Note" => receive_undo_delete_comment(undo, &delete, client, pool, chat_server).await,
64 "Page" => receive_undo_delete_post(undo, &delete, client, pool, chat_server).await,
65 "Group" => receive_undo_delete_community(undo, &delete, client, pool, chat_server).await,
66 d => Err(format_err!("Undo Delete type {} not supported", d).into()),
70 async fn receive_undo_remove(
74 chat_server: ChatServerParam,
75 ) -> Result<HttpResponse, LemmyError> {
76 let remove = Remove::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap();
78 let type_ = remove.object().as_single_kind_str().unwrap();
80 "Note" => receive_undo_remove_comment(undo, &remove, client, pool, chat_server).await,
81 "Page" => receive_undo_remove_post(undo, &remove, client, pool, chat_server).await,
82 "Group" => receive_undo_remove_community(undo, &remove, client, pool, chat_server).await,
83 d => Err(format_err!("Undo Delete type {} not supported", d).into()),
87 async fn receive_undo_like(
91 chat_server: ChatServerParam,
92 ) -> Result<HttpResponse, LemmyError> {
93 let like = Like::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap();
95 let type_ = like.object().as_single_kind_str().unwrap();
97 "Note" => receive_undo_like_comment(undo, &like, client, pool, chat_server).await,
98 "Page" => receive_undo_like_post(undo, &like, client, pool, chat_server).await,
99 d => Err(format_err!("Undo Delete type {} not supported", d).into()),
103 async fn receive_undo_dislike(
107 _chat_server: ChatServerParam,
108 ) -> Result<HttpResponse, LemmyError> {
109 let dislike = Dislike::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap();
111 let type_ = dislike.object().as_single_kind_str().unwrap();
112 Err(format_err!("Undo Delete type {} not supported", type_).into())
115 async fn receive_undo_delete_comment(
120 chat_server: ChatServerParam,
121 ) -> Result<HttpResponse, LemmyError> {
122 let user = get_user_from_activity(delete, client, pool).await?;
123 let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap();
125 let comment_ap_id = CommentForm::from_apub(¬e, client, pool)
129 let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).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,
137 deleted: Some(false),
140 updated: Some(naive_now()),
141 ap_id: comment.ap_id,
142 local: comment.local,
144 let comment_id = comment.id;
145 blocking(pool, move |conn| {
146 Comment::update(conn, comment_id, &comment_form)
151 let comment_id = comment.id;
153 blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
155 // TODO get those recipient actor ids from somewhere
156 let recipient_ids = vec![];
157 let res = CommentResponse {
158 comment: comment_view,
163 chat_server.do_send(SendComment {
164 op: UserOperation::EditComment,
169 announce_if_community_is_local(undo, &user, client, pool).await?;
170 Ok(HttpResponse::Ok().finish())
173 async fn receive_undo_remove_comment(
178 chat_server: ChatServerParam,
179 ) -> Result<HttpResponse, LemmyError> {
180 let mod_ = get_user_from_activity(remove, client, pool).await?;
181 let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap();
183 let comment_ap_id = CommentForm::from_apub(¬e, client, pool)
187 let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).await?;
189 let comment_form = CommentForm {
190 content: comment.content.to_owned(),
191 parent_id: comment.parent_id,
192 post_id: comment.post_id,
193 creator_id: comment.creator_id,
194 removed: Some(false),
198 updated: Some(naive_now()),
199 ap_id: comment.ap_id,
200 local: comment.local,
202 let comment_id = comment.id;
203 blocking(pool, move |conn| {
204 Comment::update(conn, comment_id, &comment_form)
209 let comment_id = comment.id;
211 blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
213 // TODO get those recipient actor ids from somewhere
214 let recipient_ids = vec![];
215 let res = CommentResponse {
216 comment: comment_view,
221 chat_server.do_send(SendComment {
222 op: UserOperation::EditComment,
227 announce_if_community_is_local(undo, &mod_, client, pool).await?;
228 Ok(HttpResponse::Ok().finish())
231 async fn receive_undo_delete_post(
236 chat_server: ChatServerParam,
237 ) -> Result<HttpResponse, LemmyError> {
238 let user = get_user_from_activity(delete, client, pool).await?;
239 let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap();
241 let post_ap_id = PostForm::from_apub(&page, client, pool)
245 let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
247 let post_form = PostForm {
248 name: post.name.to_owned(),
249 url: post.url.to_owned(),
250 body: post.body.to_owned(),
251 creator_id: post.creator_id.to_owned(),
252 community_id: post.community_id,
254 deleted: Some(false),
258 updated: Some(naive_now()),
259 embed_title: post.embed_title,
260 embed_description: post.embed_description,
261 embed_html: post.embed_html,
262 thumbnail_url: post.thumbnail_url,
267 let post_id = post.id;
268 blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
271 let post_id = post.id;
272 let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
274 let res = PostResponse { post: post_view };
276 chat_server.do_send(SendPost {
277 op: UserOperation::EditPost,
282 announce_if_community_is_local(undo, &user, client, pool).await?;
283 Ok(HttpResponse::Ok().finish())
286 async fn receive_undo_remove_post(
291 chat_server: ChatServerParam,
292 ) -> Result<HttpResponse, LemmyError> {
293 let mod_ = get_user_from_activity(remove, client, pool).await?;
294 let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap();
296 let post_ap_id = PostForm::from_apub(&page, client, pool)
300 let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
302 let post_form = PostForm {
303 name: post.name.to_owned(),
304 url: post.url.to_owned(),
305 body: post.body.to_owned(),
306 creator_id: post.creator_id.to_owned(),
307 community_id: post.community_id,
308 removed: Some(false),
313 updated: Some(naive_now()),
314 embed_title: post.embed_title,
315 embed_description: post.embed_description,
316 embed_html: post.embed_html,
317 thumbnail_url: post.thumbnail_url,
322 let post_id = post.id;
323 blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
326 let post_id = post.id;
327 let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
329 let res = PostResponse { post: post_view };
331 chat_server.do_send(SendPost {
332 op: UserOperation::EditPost,
337 announce_if_community_is_local(undo, &mod_, client, pool).await?;
338 Ok(HttpResponse::Ok().finish())
341 async fn receive_undo_delete_community(
346 chat_server: ChatServerParam,
347 ) -> Result<HttpResponse, LemmyError> {
348 let user = get_user_from_activity(delete, client, pool).await?;
349 let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap();
351 let community_actor_id = CommunityForm::from_apub(&group, client, pool)
355 let community = blocking(pool, move |conn| {
356 Community::read_from_actor_id(conn, &community_actor_id)
360 let community_form = CommunityForm {
361 name: community.name.to_owned(),
362 title: community.title.to_owned(),
363 description: community.description.to_owned(),
364 category_id: community.category_id, // Note: need to keep this due to foreign key constraint
365 creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
368 updated: Some(naive_now()),
369 deleted: Some(false),
370 nsfw: community.nsfw,
371 actor_id: community.actor_id,
372 local: community.local,
373 private_key: community.private_key,
374 public_key: community.public_key,
375 last_refreshed_at: None,
378 let community_id = community.id;
379 blocking(pool, move |conn| {
380 Community::update(conn, community_id, &community_form)
384 let community_id = community.id;
385 let res = CommunityResponse {
386 community: blocking(pool, move |conn| {
387 CommunityView::read(conn, community_id, None)
392 let community_id = res.community.id;
394 chat_server.do_send(SendCommunityRoomMessage {
395 op: UserOperation::EditCommunity,
401 announce_if_community_is_local(undo, &user, client, pool).await?;
402 Ok(HttpResponse::Ok().finish())
405 async fn receive_undo_remove_community(
410 chat_server: ChatServerParam,
411 ) -> Result<HttpResponse, LemmyError> {
412 let mod_ = get_user_from_activity(remove, client, pool).await?;
413 let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap();
415 let community_actor_id = CommunityForm::from_apub(&group, client, pool)
419 let community = blocking(pool, move |conn| {
420 Community::read_from_actor_id(conn, &community_actor_id)
424 let community_form = CommunityForm {
425 name: community.name.to_owned(),
426 title: community.title.to_owned(),
427 description: community.description.to_owned(),
428 category_id: community.category_id, // Note: need to keep this due to foreign key constraint
429 creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint
430 removed: Some(false),
432 updated: Some(naive_now()),
434 nsfw: community.nsfw,
435 actor_id: community.actor_id,
436 local: community.local,
437 private_key: community.private_key,
438 public_key: community.public_key,
439 last_refreshed_at: None,
442 let community_id = community.id;
443 blocking(pool, move |conn| {
444 Community::update(conn, community_id, &community_form)
448 let community_id = community.id;
449 let res = CommunityResponse {
450 community: blocking(pool, move |conn| {
451 CommunityView::read(conn, community_id, None)
456 let community_id = res.community.id;
458 chat_server.do_send(SendCommunityRoomMessage {
459 op: UserOperation::EditCommunity,
465 announce_if_community_is_local(undo, &mod_, client, pool).await?;
466 Ok(HttpResponse::Ok().finish())
469 async fn receive_undo_like_comment(
474 chat_server: ChatServerParam,
475 ) -> Result<HttpResponse, LemmyError> {
476 let user = get_user_from_activity(like, client, pool).await?;
477 let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap();
479 let comment = CommentForm::from_apub(¬e, client, pool).await?;
481 let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool)
485 let like_form = CommentLikeForm {
487 post_id: comment.post_id,
491 blocking(pool, move |conn| CommentLike::remove(conn, &like_form)).await??;
495 blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
497 // TODO get those recipient actor ids from somewhere
498 let recipient_ids = vec![];
499 let res = CommentResponse {
500 comment: comment_view,
505 chat_server.do_send(SendComment {
506 op: UserOperation::CreateCommentLike,
511 announce_if_community_is_local(undo, &user, client, pool).await?;
512 Ok(HttpResponse::Ok().finish())
515 async fn receive_undo_like_post(
520 chat_server: ChatServerParam,
521 ) -> Result<HttpResponse, LemmyError> {
522 let user = get_user_from_activity(like, client, pool).await?;
523 let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap();
525 let post = PostForm::from_apub(&page, client, pool).await?;
527 let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool)
531 let like_form = PostLikeForm {
536 blocking(pool, move |conn| PostLike::remove(conn, &like_form)).await??;
539 let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
541 let res = PostResponse { post: post_view };
543 chat_server.do_send(SendPost {
544 op: UserOperation::CreatePostLike,
549 announce_if_community_is_local(undo, &user, client, pool).await?;
550 Ok(HttpResponse::Ok().finish())