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