]> Untitled Git - lemmy.git/blob - crates/api_crud/src/post/read.rs
Extract Activitypub logic into separate library (#2288)
[lemmy.git] / crates / api_crud / src / post / read.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   post::{GetPost, GetPostResponse},
5   utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read},
6 };
7 use lemmy_db_schema::traits::DeleteableOrRemoveable;
8 use lemmy_db_views::{comment_view::CommentQueryBuilder, structs::PostView};
9 use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
10 use lemmy_utils::{error::LemmyError, ConnectionId};
11 use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
12
13 #[async_trait::async_trait(?Send)]
14 impl PerformCrud for GetPost {
15   type Response = GetPostResponse;
16
17   #[tracing::instrument(skip(context, _websocket_id))]
18   async fn perform(
19     &self,
20     context: &Data<LemmyContext>,
21     _websocket_id: Option<ConnectionId>,
22   ) -> Result<GetPostResponse, LemmyError> {
23     let data: &GetPost = self;
24     let local_user_view =
25       get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
26         .await?;
27
28     check_private_instance(&local_user_view, context.pool()).await?;
29
30     let show_bot_accounts = local_user_view
31       .as_ref()
32       .map(|t| t.local_user.show_bot_accounts);
33     let person_id = local_user_view.map(|u| u.person.id);
34
35     let id = data.id;
36     let mut post_view = blocking(context.pool(), move |conn| {
37       PostView::read(conn, id, person_id)
38     })
39     .await?
40     .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?;
41
42     // Mark the post as read
43     if let Some(person_id) = person_id {
44       mark_post_as_read(person_id, id, context.pool()).await?;
45     }
46
47     let id = data.id;
48     let mut comments = blocking(context.pool(), move |conn| {
49       CommentQueryBuilder::create(conn)
50         .my_person_id(person_id)
51         .show_bot_accounts(show_bot_accounts)
52         .post_id(id)
53         .limit(9999)
54         .list()
55     })
56     .await??;
57
58     // Necessary for the sidebar
59     let community_id = post_view.community.id;
60     let mut community_view = blocking(context.pool(), move |conn| {
61       CommunityView::read(conn, community_id, person_id)
62     })
63     .await?
64     .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
65
66     // Blank out deleted or removed info for non-logged in users
67     if person_id.is_none() {
68       if post_view.post.deleted || post_view.post.removed {
69         post_view.post = post_view.post.blank_out_deleted_or_removed_info();
70       }
71
72       for cv in comments
73         .iter_mut()
74         .filter(|cv| cv.comment.deleted || cv.comment.removed)
75       {
76         cv.comment = cv.to_owned().comment.blank_out_deleted_or_removed_info();
77       }
78       if community_view.community.deleted || community_view.community.removed {
79         community_view.community = community_view.community.blank_out_deleted_or_removed_info();
80       }
81     }
82
83     let moderators = blocking(context.pool(), move |conn| {
84       CommunityModeratorView::for_community(conn, community_id)
85     })
86     .await??;
87
88     let online = context
89       .chat_server()
90       .send(GetPostUsersOnline { post_id: data.id })
91       .await
92       .unwrap_or(1);
93
94     // Return the jwt
95     Ok(GetPostResponse {
96       post_view,
97       community_view,
98       comments,
99       moderators,
100       online,
101     })
102   }
103 }