3 fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
5 announce_if_community_is_local,
6 get_user_from_activity,
7 receive_unhandled_activity,
15 use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
16 use actix_web::HttpResponse;
20 comment::CommentResponse,
23 websocket::{SendComment, SendPost, UserOperation},
26 comment::{Comment, CommentForm},
27 comment_view::CommentView,
28 post::{Post, PostForm},
32 use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
34 pub async fn receive_update(
36 context: &LemmyContext,
37 ) -> Result<HttpResponse, LemmyError> {
38 let update = Update::from_any_base(activity)?.context(location_info!())?;
40 // ensure that update and actor come from the same instance
41 let user = get_user_from_activity(&update, context).await?;
42 update.id(user.actor_id()?.domain().context(location_info!())?)?;
44 match update.object().as_single_kind_str() {
45 Some("Page") => receive_update_post(update, context).await,
46 Some("Note") => receive_update_comment(update, context).await,
47 _ => receive_unhandled_activity(update),
51 async fn receive_update_post(
53 context: &LemmyContext,
54 ) -> Result<HttpResponse, LemmyError> {
55 let user = get_user_from_activity(&update, context).await?;
56 let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
57 .context(location_info!())?;
59 let post = PostForm::from_apub(&page, context, Some(user.actor_id()?)).await?;
61 let original_post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
65 blocking(context.pool(), move |conn| {
66 Post::update(conn, original_post_id, &post)
71 let post_view = blocking(context.pool(), move |conn| {
72 PostView::read(conn, original_post_id, None)
76 let res = PostResponse { post: post_view };
78 context.chat_server().do_send(SendPost {
79 op: UserOperation::EditPost,
84 announce_if_community_is_local(update, &user, context).await?;
85 Ok(HttpResponse::Ok().finish())
88 async fn receive_update_comment(
90 context: &LemmyContext,
91 ) -> Result<HttpResponse, LemmyError> {
92 let note = Note::from_any_base(update.object().to_owned().one().context(location_info!())?)?
93 .context(location_info!())?;
94 let user = get_user_from_activity(&update, context).await?;
96 let comment = CommentForm::from_apub(¬e, context, Some(user.actor_id()?)).await?;
98 let original_comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
102 let updated_comment = blocking(context.pool(), move |conn| {
103 Comment::update(conn, original_comment_id, &comment)
107 let post_id = updated_comment.post_id;
108 let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
110 let mentions = scrape_text_for_mentions(&updated_comment.content);
111 let recipient_ids = send_local_notifs(
122 let comment_view = blocking(context.pool(), move |conn| {
123 CommentView::read(conn, original_comment_id, None)
127 let res = CommentResponse {
128 comment: comment_view,
133 context.chat_server().do_send(SendComment {
134 op: UserOperation::EditComment,
139 announce_if_community_is_local(update, &user, context).await?;
140 Ok(HttpResponse::Ok().finish())