]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/receive/post.rs
Fix API and clippy warnings
[lemmy.git] / crates / apub / src / activities / receive / post.rs
1 use crate::{
2   activities::receive::get_actor_as_person,
3   inbox::receive_for_community::verify_mod_activity,
4   objects::FromApub,
5   ActorType,
6   PageExt,
7 };
8 use activitystreams::{
9   activity::{Announce, Create, Dislike, Like, Update},
10   prelude::*,
11 };
12 use anyhow::Context;
13 use lemmy_api_common::{blocking, post::PostResponse};
14 use lemmy_db_queries::{source::post::Post_, ApubObject, Crud, Likeable};
15 use lemmy_db_schema::{
16   source::{
17     community::Community,
18     post::{Post, PostLike, PostLikeForm},
19   },
20   DbUrl,
21 };
22 use lemmy_db_views::post_view::PostView;
23 use lemmy_utils::{location_info, LemmyError};
24 use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud};
25
26 pub(crate) async fn receive_create_post(
27   create: Create,
28   context: &LemmyContext,
29   request_counter: &mut i32,
30 ) -> Result<(), LemmyError> {
31   let person = get_actor_as_person(&create, context, request_counter).await?;
32   let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
33     .context(location_info!())?;
34
35   let post = Post::from_apub(&page, context, person.actor_id(), request_counter, false).await?;
36
37   // Refetch the view
38   let post_id = post.id;
39   let post_view = blocking(context.pool(), move |conn| {
40     PostView::read(conn, post_id, None)
41   })
42   .await??;
43
44   let res = PostResponse { post_view };
45
46   context.chat_server().do_send(SendPost {
47     op: UserOperationCrud::CreatePost,
48     post: res,
49     websocket_id: None,
50   });
51
52   Ok(())
53 }
54
55 pub(crate) async fn receive_update_post(
56   update: Update,
57   announce: Option<Announce>,
58   context: &LemmyContext,
59   request_counter: &mut i32,
60 ) -> Result<(), LemmyError> {
61   let person = get_actor_as_person(&update, context, request_counter).await?;
62   let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
63     .context(location_info!())?;
64
65   let post_id: DbUrl = page
66     .id_unchecked()
67     .context(location_info!())?
68     .to_owned()
69     .into();
70   let old_post = blocking(context.pool(), move |conn| {
71     Post::read_from_apub_id(conn, &post_id)
72   })
73   .await??;
74
75   // If sticked or locked state was changed, make sure the actor is a mod
76   let stickied = page.ext_one.stickied.context(location_info!())?;
77   let locked = !page.ext_one.comments_enabled.context(location_info!())?;
78   let mut mod_action_allowed = false;
79   if (stickied != old_post.stickied) || (locked != old_post.locked) {
80     let community = blocking(context.pool(), move |conn| {
81       Community::read(conn, old_post.community_id)
82     })
83     .await??;
84     // Only check mod status if the community is local, otherwise we trust that it was sent correctly.
85     if community.local {
86       verify_mod_activity(&update, announce, &community, context).await?;
87     }
88     mod_action_allowed = true;
89   }
90
91   let post = Post::from_apub(
92     &page,
93     context,
94     person.actor_id(),
95     request_counter,
96     mod_action_allowed,
97   )
98   .await?;
99
100   let post_id = post.id;
101   // Refetch the view
102   let post_view = blocking(context.pool(), move |conn| {
103     PostView::read(conn, post_id, None)
104   })
105   .await??;
106
107   let res = PostResponse { post_view };
108
109   context.chat_server().do_send(SendPost {
110     op: UserOperationCrud::EditPost,
111     post: res,
112     websocket_id: None,
113   });
114
115   Ok(())
116 }
117
118 pub(crate) async fn receive_like_post(
119   like: Like,
120   post: Post,
121   context: &LemmyContext,
122   request_counter: &mut i32,
123 ) -> Result<(), LemmyError> {
124   let person = get_actor_as_person(&like, context, request_counter).await?;
125
126   let post_id = post.id;
127   let like_form = PostLikeForm {
128     post_id,
129     person_id: person.id,
130     score: 1,
131   };
132   let person_id = person.id;
133   blocking(context.pool(), move |conn| {
134     PostLike::remove(conn, person_id, post_id)?;
135     PostLike::like(conn, &like_form)
136   })
137   .await??;
138
139   // Refetch the view
140   let post_view = blocking(context.pool(), move |conn| {
141     PostView::read(conn, post_id, None)
142   })
143   .await??;
144
145   let res = PostResponse { post_view };
146
147   context.chat_server().do_send(SendPost {
148     op: UserOperation::CreatePostLike,
149     post: res,
150     websocket_id: None,
151   });
152
153   Ok(())
154 }
155
156 pub(crate) async fn receive_dislike_post(
157   dislike: Dislike,
158   post: Post,
159   context: &LemmyContext,
160   request_counter: &mut i32,
161 ) -> Result<(), LemmyError> {
162   let person = get_actor_as_person(&dislike, context, request_counter).await?;
163
164   let post_id = post.id;
165   let like_form = PostLikeForm {
166     post_id,
167     person_id: person.id,
168     score: -1,
169   };
170   let person_id = person.id;
171   blocking(context.pool(), move |conn| {
172     PostLike::remove(conn, person_id, post_id)?;
173     PostLike::like(conn, &like_form)
174   })
175   .await??;
176
177   // Refetch the view
178   let post_view = blocking(context.pool(), move |conn| {
179     PostView::read(conn, post_id, None)
180   })
181   .await??;
182
183   let res = PostResponse { post_view };
184
185   context.chat_server().do_send(SendPost {
186     op: UserOperation::CreatePostLike,
187     post: res,
188     websocket_id: None,
189   });
190
191   Ok(())
192 }
193
194 pub(crate) async fn receive_delete_post(
195   context: &LemmyContext,
196   post: Post,
197 ) -> Result<(), LemmyError> {
198   let deleted_post = blocking(context.pool(), move |conn| {
199     Post::update_deleted(conn, post.id, true)
200   })
201   .await??;
202
203   // Refetch the view
204   let post_id = deleted_post.id;
205   let post_view = blocking(context.pool(), move |conn| {
206     PostView::read(conn, post_id, None)
207   })
208   .await??;
209
210   let res = PostResponse { post_view };
211   context.chat_server().do_send(SendPost {
212     op: UserOperationCrud::EditPost,
213     post: res,
214     websocket_id: None,
215   });
216
217   Ok(())
218 }
219
220 pub(crate) async fn receive_remove_post(
221   context: &LemmyContext,
222   post: Post,
223 ) -> Result<(), LemmyError> {
224   let removed_post = blocking(context.pool(), move |conn| {
225     Post::update_removed(conn, post.id, true)
226   })
227   .await??;
228
229   // Refetch the view
230   let post_id = removed_post.id;
231   let post_view = blocking(context.pool(), move |conn| {
232     PostView::read(conn, post_id, None)
233   })
234   .await??;
235
236   let res = PostResponse { post_view };
237   context.chat_server().do_send(SendPost {
238     op: UserOperationCrud::EditPost,
239     post: res,
240     websocket_id: None,
241   });
242
243   Ok(())
244 }