]> Untitled Git - lemmy.git/blob - lemmy_apub/src/activities/receive/comment.rs
Some API cleanup, adding site_id to site aggregates.
[lemmy.git] / lemmy_apub / src / activities / receive / comment.rs
1 use crate::{activities::receive::get_actor_as_user, objects::FromApub, ActorType, NoteExt};
2 use activitystreams::{
3   activity::{ActorAndObjectRefExt, Create, Dislike, Like, Remove, Update},
4   base::ExtendsExt,
5 };
6 use anyhow::Context;
7 use lemmy_db::{
8   source::{
9     comment::{Comment, CommentLike, CommentLikeForm},
10     post::Post,
11   },
12   views::comment_view::CommentView,
13   Crud,
14   Likeable,
15 };
16 use lemmy_structs::{blocking, comment::CommentResponse, send_local_notifs};
17 use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
18 use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
19
20 pub(crate) async fn receive_create_comment(
21   create: Create,
22   context: &LemmyContext,
23   request_counter: &mut i32,
24 ) -> Result<(), LemmyError> {
25   let user = get_actor_as_user(&create, context, request_counter).await?;
26   let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
27     .context(location_info!())?;
28
29   let comment = Comment::from_apub(&note, context, user.actor_id()?, request_counter).await?;
30
31   let post_id = comment.post_id;
32   let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
33
34   // Note:
35   // Although mentions could be gotten from the post tags (they are included there), or the ccs,
36   // Its much easier to scrape them from the comment body, since the API has to do that
37   // anyway.
38   let mentions = scrape_text_for_mentions(&comment.content);
39   let recipient_ids =
40     send_local_notifs(mentions, comment.clone(), &user, post, context.pool(), true).await?;
41
42   // Refetch the view
43   let comment_view = blocking(context.pool(), move |conn| {
44     CommentView::read(conn, comment.id, None)
45   })
46   .await??;
47
48   let res = CommentResponse {
49     comment_view,
50     recipient_ids,
51     form_id: None,
52   };
53
54   context.chat_server().do_send(SendComment {
55     op: UserOperation::CreateComment,
56     comment: res,
57     websocket_id: None,
58   });
59
60   Ok(())
61 }
62
63 pub(crate) async fn receive_update_comment(
64   update: Update,
65   context: &LemmyContext,
66   request_counter: &mut i32,
67 ) -> Result<(), LemmyError> {
68   let note = NoteExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
69     .context(location_info!())?;
70   let user = get_actor_as_user(&update, context, request_counter).await?;
71
72   let comment = Comment::from_apub(&note, context, user.actor_id()?, request_counter).await?;
73
74   let comment_id = comment.id;
75   let post_id = comment.post_id;
76   let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
77
78   let mentions = scrape_text_for_mentions(&comment.content);
79   let recipient_ids =
80     send_local_notifs(mentions, comment, &user, post, context.pool(), false).await?;
81
82   // Refetch the view
83   let comment_view = blocking(context.pool(), move |conn| {
84     CommentView::read(conn, comment_id, None)
85   })
86   .await??;
87
88   let res = CommentResponse {
89     comment_view,
90     recipient_ids,
91     form_id: None,
92   };
93
94   context.chat_server().do_send(SendComment {
95     op: UserOperation::EditComment,
96     comment: res,
97     websocket_id: None,
98   });
99
100   Ok(())
101 }
102
103 pub(crate) async fn receive_like_comment(
104   like: Like,
105   comment: Comment,
106   context: &LemmyContext,
107   request_counter: &mut i32,
108 ) -> Result<(), LemmyError> {
109   let user = get_actor_as_user(&like, context, request_counter).await?;
110
111   let comment_id = comment.id;
112   let like_form = CommentLikeForm {
113     comment_id,
114     post_id: comment.post_id,
115     user_id: user.id,
116     score: 1,
117   };
118   let user_id = user.id;
119   blocking(context.pool(), move |conn| {
120     CommentLike::remove(conn, user_id, comment_id)?;
121     CommentLike::like(conn, &like_form)
122   })
123   .await??;
124
125   // Refetch the view
126   let comment_view = blocking(context.pool(), move |conn| {
127     CommentView::read(conn, comment_id, None)
128   })
129   .await??;
130
131   // TODO get those recipient actor ids from somewhere
132   let recipient_ids = vec![];
133   let res = CommentResponse {
134     comment_view,
135     recipient_ids,
136     form_id: None,
137   };
138
139   context.chat_server().do_send(SendComment {
140     op: UserOperation::CreateCommentLike,
141     comment: res,
142     websocket_id: None,
143   });
144
145   Ok(())
146 }
147
148 pub(crate) async fn receive_dislike_comment(
149   dislike: Dislike,
150   comment: Comment,
151   context: &LemmyContext,
152   request_counter: &mut i32,
153 ) -> Result<(), LemmyError> {
154   let user = get_actor_as_user(&dislike, context, request_counter).await?;
155
156   let comment_id = comment.id;
157   let like_form = CommentLikeForm {
158     comment_id,
159     post_id: comment.post_id,
160     user_id: user.id,
161     score: -1,
162   };
163   let user_id = user.id;
164   blocking(context.pool(), move |conn| {
165     CommentLike::remove(conn, user_id, comment_id)?;
166     CommentLike::like(conn, &like_form)
167   })
168   .await??;
169
170   // Refetch the view
171   let comment_view = blocking(context.pool(), move |conn| {
172     CommentView::read(conn, comment_id, None)
173   })
174   .await??;
175
176   // TODO get those recipient actor ids from somewhere
177   let recipient_ids = vec![];
178   let res = CommentResponse {
179     comment_view,
180     recipient_ids,
181     form_id: None,
182   };
183
184   context.chat_server().do_send(SendComment {
185     op: UserOperation::CreateCommentLike,
186     comment: res,
187     websocket_id: None,
188   });
189
190   Ok(())
191 }
192
193 pub(crate) async fn receive_delete_comment(
194   context: &LemmyContext,
195   comment: Comment,
196 ) -> Result<(), LemmyError> {
197   let deleted_comment = blocking(context.pool(), move |conn| {
198     Comment::update_deleted(conn, comment.id, true)
199   })
200   .await??;
201
202   // Refetch the view
203   let comment_id = deleted_comment.id;
204   let comment_view = blocking(context.pool(), move |conn| {
205     CommentView::read(conn, comment_id, None)
206   })
207   .await??;
208
209   // TODO get those recipient actor ids from somewhere
210   let recipient_ids = vec![];
211   let res = CommentResponse {
212     comment_view,
213     recipient_ids,
214     form_id: None,
215   };
216   context.chat_server().do_send(SendComment {
217     op: UserOperation::EditComment,
218     comment: res,
219     websocket_id: None,
220   });
221
222   Ok(())
223 }
224
225 pub(crate) async fn receive_remove_comment(
226   context: &LemmyContext,
227   _remove: Remove,
228   comment: Comment,
229 ) -> Result<(), LemmyError> {
230   let removed_comment = blocking(context.pool(), move |conn| {
231     Comment::update_removed(conn, comment.id, true)
232   })
233   .await??;
234
235   // Refetch the view
236   let comment_id = removed_comment.id;
237   let comment_view = blocking(context.pool(), move |conn| {
238     CommentView::read(conn, comment_id, None)
239   })
240   .await??;
241
242   // TODO get those recipient actor ids from somewhere
243   let recipient_ids = vec![];
244   let res = CommentResponse {
245     comment_view,
246     recipient_ids,
247     form_id: None,
248   };
249   context.chat_server().do_send(SendComment {
250     op: UserOperation::EditComment,
251     comment: res,
252     websocket_id: None,
253   });
254
255   Ok(())
256 }