]> Untitled Git - lemmy.git/blob - lemmy_apub/src/inbox/activities/like.rs
Fix nginx config for local federation setup (#104)
[lemmy.git] / lemmy_apub / src / inbox / activities / like.rs
1 use crate::{
2   fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
3   inbox::shared_inbox::{
4     announce_if_community_is_local,
5     get_user_from_activity,
6     receive_unhandled_activity,
7   },
8   FromApub,
9   PageExt,
10 };
11 use activitystreams::{activity::Like, base::AnyBase, object::Note, prelude::*};
12 use actix_web::HttpResponse;
13 use anyhow::Context;
14 use lemmy_db::{
15   comment::{CommentForm, CommentLike, CommentLikeForm},
16   comment_view::CommentView,
17   post::{PostForm, PostLike, PostLikeForm},
18   post_view::PostView,
19   Likeable,
20 };
21 use lemmy_structs::{blocking, comment::CommentResponse, post::PostResponse};
22 use lemmy_utils::{location_info, LemmyError};
23 use lemmy_websocket::{
24   messages::{SendComment, SendPost},
25   LemmyContext,
26   UserOperation,
27 };
28
29 pub async fn receive_like(
30   activity: AnyBase,
31   context: &LemmyContext,
32 ) -> Result<HttpResponse, LemmyError> {
33   let like = Like::from_any_base(activity)?.context(location_info!())?;
34   match like.object().as_single_kind_str() {
35     Some("Page") => receive_like_post(like, context).await,
36     Some("Note") => receive_like_comment(like, context).await,
37     _ => receive_unhandled_activity(like),
38   }
39 }
40
41 async fn receive_like_post(like: Like, context: &LemmyContext) -> Result<HttpResponse, LemmyError> {
42   let user = get_user_from_activity(&like, context).await?;
43   let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
44     .context(location_info!())?;
45
46   let post = PostForm::from_apub(&page, context, None).await?;
47
48   let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
49     .await?
50     .id;
51
52   let like_form = PostLikeForm {
53     post_id,
54     user_id: user.id,
55     score: 1,
56   };
57   let user_id = user.id;
58   blocking(context.pool(), move |conn| {
59     PostLike::remove(conn, user_id, post_id)?;
60     PostLike::like(conn, &like_form)
61   })
62   .await??;
63
64   // Refetch the view
65   let post_view = blocking(context.pool(), move |conn| {
66     PostView::read(conn, post_id, None)
67   })
68   .await??;
69
70   let res = PostResponse { post: post_view };
71
72   context.chat_server().do_send(SendPost {
73     op: UserOperation::CreatePostLike,
74     post: res,
75     websocket_id: None,
76   });
77
78   announce_if_community_is_local(like, &user, context).await?;
79   Ok(HttpResponse::Ok().finish())
80 }
81
82 async fn receive_like_comment(
83   like: Like,
84   context: &LemmyContext,
85 ) -> Result<HttpResponse, LemmyError> {
86   let note = Note::from_any_base(like.object().to_owned().one().context(location_info!())?)?
87     .context(location_info!())?;
88   let user = get_user_from_activity(&like, context).await?;
89
90   let comment = CommentForm::from_apub(&note, context, None).await?;
91
92   let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
93     .await?
94     .id;
95
96   let like_form = CommentLikeForm {
97     comment_id,
98     post_id: comment.post_id,
99     user_id: user.id,
100     score: 1,
101   };
102   let user_id = user.id;
103   blocking(context.pool(), move |conn| {
104     CommentLike::remove(conn, user_id, comment_id)?;
105     CommentLike::like(conn, &like_form)
106   })
107   .await??;
108
109   // Refetch the view
110   let comment_view = blocking(context.pool(), move |conn| {
111     CommentView::read(conn, comment_id, None)
112   })
113   .await??;
114
115   // TODO get those recipient actor ids from somewhere
116   let recipient_ids = vec![];
117   let res = CommentResponse {
118     comment: comment_view,
119     recipient_ids,
120     form_id: None,
121   };
122
123   context.chat_server().do_send(SendComment {
124     op: UserOperation::CreateCommentLike,
125     comment: res,
126     websocket_id: None,
127   });
128
129   announce_if_community_is_local(like, &user, context).await?;
130   Ok(HttpResponse::Ok().finish())
131 }