]> Untitled Git - lemmy.git/blob - crates/api_crud/src/post/read.rs
Dont make webfinger request when viewing community/user profile (fixes #1896) (#2049)
[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   blocking,
5   check_private_instance,
6   get_local_user_view_from_jwt_opt,
7   mark_post_as_read,
8   post::*,
9   resolve_actor_identifier,
10 };
11 use lemmy_db_schema::{
12   from_opt_str_to_opt_enum,
13   source::community::Community,
14   traits::DeleteableOrRemoveable,
15   ListingType,
16   SortType,
17 };
18 use lemmy_db_views::{
19   comment_view::CommentQueryBuilder,
20   post_view::{PostQueryBuilder, PostView},
21 };
22 use lemmy_db_views_actor::{
23   community_moderator_view::CommunityModeratorView,
24   community_view::CommunityView,
25 };
26 use lemmy_utils::{ConnectionId, LemmyError};
27 use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
28
29 #[async_trait::async_trait(?Send)]
30 impl PerformCrud for GetPost {
31   type Response = GetPostResponse;
32
33   #[tracing::instrument(skip(context, _websocket_id))]
34   async fn perform(
35     &self,
36     context: &Data<LemmyContext>,
37     _websocket_id: Option<ConnectionId>,
38   ) -> Result<GetPostResponse, LemmyError> {
39     let data: &GetPost = self;
40     let local_user_view =
41       get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
42         .await?;
43
44     check_private_instance(&local_user_view, context.pool()).await?;
45
46     let show_bot_accounts = local_user_view
47       .as_ref()
48       .map(|t| t.local_user.show_bot_accounts);
49     let person_id = local_user_view.map(|u| u.person.id);
50
51     let id = data.id;
52     let mut post_view = blocking(context.pool(), move |conn| {
53       PostView::read(conn, id, person_id)
54     })
55     .await?
56     .map_err(LemmyError::from)
57     .map_err(|e| e.with_message("couldnt_find_post"))?;
58
59     // Mark the post as read
60     if let Some(person_id) = person_id {
61       mark_post_as_read(person_id, id, context.pool()).await?;
62     }
63
64     let id = data.id;
65     let mut comments = blocking(context.pool(), move |conn| {
66       CommentQueryBuilder::create(conn)
67         .my_person_id(person_id)
68         .show_bot_accounts(show_bot_accounts)
69         .post_id(id)
70         .limit(9999)
71         .list()
72     })
73     .await??;
74
75     // Necessary for the sidebar
76     let community_id = post_view.community.id;
77     let mut community_view = blocking(context.pool(), move |conn| {
78       CommunityView::read(conn, community_id, person_id)
79     })
80     .await?
81     .map_err(LemmyError::from)
82     .map_err(|e| e.with_message("couldnt_find_community"))?;
83
84     // Blank out deleted or removed info for non-logged in users
85     if person_id.is_none() {
86       if post_view.post.deleted || post_view.post.removed {
87         post_view.post = post_view.post.blank_out_deleted_or_removed_info();
88       }
89
90       for cv in comments
91         .iter_mut()
92         .filter(|cv| cv.comment.deleted || cv.comment.removed)
93       {
94         cv.comment = cv.to_owned().comment.blank_out_deleted_or_removed_info();
95       }
96       if community_view.community.deleted || community_view.community.removed {
97         community_view.community = community_view.community.blank_out_deleted_or_removed_info();
98       }
99     }
100
101     let moderators = blocking(context.pool(), move |conn| {
102       CommunityModeratorView::for_community(conn, community_id)
103     })
104     .await??;
105
106     let online = context
107       .chat_server()
108       .send(GetPostUsersOnline { post_id: data.id })
109       .await
110       .unwrap_or(1);
111
112     // Return the jwt
113     Ok(GetPostResponse {
114       post_view,
115       community_view,
116       comments,
117       moderators,
118       online,
119     })
120   }
121 }
122
123 #[async_trait::async_trait(?Send)]
124 impl PerformCrud for GetPosts {
125   type Response = GetPostsResponse;
126
127   #[tracing::instrument(skip(context, _websocket_id))]
128   async fn perform(
129     &self,
130     context: &Data<LemmyContext>,
131     _websocket_id: Option<ConnectionId>,
132   ) -> Result<GetPostsResponse, LemmyError> {
133     let data: &GetPosts = self;
134     let local_user_view =
135       get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
136         .await?;
137
138     check_private_instance(&local_user_view, context.pool()).await?;
139
140     let person_id = local_user_view.to_owned().map(|l| l.person.id);
141
142     let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
143     let show_bot_accounts = local_user_view
144       .as_ref()
145       .map(|t| t.local_user.show_bot_accounts);
146     let show_read_posts = local_user_view
147       .as_ref()
148       .map(|t| t.local_user.show_read_posts);
149
150     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
151     let listing_type: Option<ListingType> = from_opt_str_to_opt_enum(&data.type_);
152
153     let page = data.page;
154     let limit = data.limit;
155     let community_id = data.community_id;
156     let community_actor_id = if let Some(name) = &data.community_name {
157       resolve_actor_identifier::<Community>(name, context.pool())
158         .await
159         .ok()
160         .map(|c| c.actor_id)
161     } else {
162       None
163     };
164     let saved_only = data.saved_only;
165
166     let mut posts = blocking(context.pool(), move |conn| {
167       PostQueryBuilder::create(conn)
168         .listing_type(listing_type)
169         .sort(sort)
170         .show_nsfw(show_nsfw)
171         .show_bot_accounts(show_bot_accounts)
172         .show_read_posts(show_read_posts)
173         .community_id(community_id)
174         .community_actor_id(community_actor_id)
175         .saved_only(saved_only)
176         .my_person_id(person_id)
177         .page(page)
178         .limit(limit)
179         .list()
180     })
181     .await?
182     .map_err(LemmyError::from)
183     .map_err(|e| e.with_message("couldnt_get_posts"))?;
184
185     // Blank out deleted or removed info for non-logged in users
186     if person_id.is_none() {
187       for pv in posts
188         .iter_mut()
189         .filter(|p| p.post.deleted || p.post.removed)
190       {
191         pv.post = pv.to_owned().post.blank_out_deleted_or_removed_info();
192       }
193
194       for pv in posts
195         .iter_mut()
196         .filter(|p| p.community.deleted || p.community.removed)
197       {
198         pv.community = pv.to_owned().community.blank_out_deleted_or_removed_info();
199       }
200     }
201
202     Ok(GetPostsResponse { posts })
203   }
204 }