2 fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
4 announce_if_community_is_local,
5 get_user_from_activity,
6 receive_unhandled_activity,
12 use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
13 use actix_web::HttpResponse;
16 comment::{Comment, CommentForm},
17 comment_view::CommentView,
18 post::{Post, PostForm},
22 use lemmy_structs::{blocking, comment::CommentResponse, post::PostResponse, send_local_notifs};
23 use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
24 use lemmy_websocket::{
25 messages::{SendComment, SendPost},
30 pub async fn receive_update(
32 context: &LemmyContext,
33 ) -> Result<HttpResponse, LemmyError> {
34 let update = Update::from_any_base(activity)?.context(location_info!())?;
36 // ensure that update and actor come from the same instance
37 let user = get_user_from_activity(&update, context).await?;
38 update.id(user.actor_id()?.domain().context(location_info!())?)?;
40 match update.object().as_single_kind_str() {
41 Some("Page") => receive_update_post(update, context).await,
42 Some("Note") => receive_update_comment(update, context).await,
43 _ => receive_unhandled_activity(update),
47 async fn receive_update_post(
49 context: &LemmyContext,
50 ) -> Result<HttpResponse, LemmyError> {
51 let user = get_user_from_activity(&update, context).await?;
52 let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
53 .context(location_info!())?;
55 let post = PostForm::from_apub(&page, context, Some(user.actor_id()?)).await?;
57 let original_post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
61 blocking(context.pool(), move |conn| {
62 Post::update(conn, original_post_id, &post)
67 let post_view = blocking(context.pool(), move |conn| {
68 PostView::read(conn, original_post_id, None)
72 let res = PostResponse { post: post_view };
74 context.chat_server().do_send(SendPost {
75 op: UserOperation::EditPost,
80 announce_if_community_is_local(update, &user, context).await?;
81 Ok(HttpResponse::Ok().finish())
84 async fn receive_update_comment(
86 context: &LemmyContext,
87 ) -> Result<HttpResponse, LemmyError> {
88 let note = Note::from_any_base(update.object().to_owned().one().context(location_info!())?)?
89 .context(location_info!())?;
90 let user = get_user_from_activity(&update, context).await?;
92 let comment = CommentForm::from_apub(¬e, context, Some(user.actor_id()?)).await?;
94 let original_comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
98 let updated_comment = blocking(context.pool(), move |conn| {
99 Comment::update(conn, original_comment_id, &comment)
103 let post_id = updated_comment.post_id;
104 let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
106 let mentions = scrape_text_for_mentions(&updated_comment.content);
107 let recipient_ids = send_local_notifs(
118 let comment_view = blocking(context.pool(), move |conn| {
119 CommentView::read(conn, original_comment_id, None)
123 let res = CommentResponse {
124 comment: comment_view,
129 context.chat_server().do_send(SendComment {
130 op: UserOperation::EditComment,
135 announce_if_community_is_local(update, &user, context).await?;
136 Ok(HttpResponse::Ok().finish())