]> Untitled Git - lemmy.git/blob - crates/api_crud/src/post/read.rs
Use .map_err in api code (fixes #1573) (#1575)
[lemmy.git] / crates / api_crud / src / post / read.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, post::*};
4 use lemmy_db_queries::{ListingType, SortType};
5 use lemmy_db_views::{
6   comment_view::CommentQueryBuilder,
7   post_view::{PostQueryBuilder, PostView},
8 };
9 use lemmy_db_views_actor::{
10   community_moderator_view::CommunityModeratorView,
11   community_view::CommunityView,
12 };
13 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
14 use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
15 use std::str::FromStr;
16
17 #[async_trait::async_trait(?Send)]
18 impl PerformCrud for GetPost {
19   type Response = GetPostResponse;
20
21   async fn perform(
22     &self,
23     context: &Data<LemmyContext>,
24     _websocket_id: Option<ConnectionId>,
25   ) -> Result<GetPostResponse, LemmyError> {
26     let data: &GetPost = &self;
27     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
28     let person_id = local_user_view.map(|u| u.person.id);
29
30     let id = data.id;
31     let post_view = blocking(context.pool(), move |conn| {
32       PostView::read(conn, id, person_id)
33     })
34     .await?
35     .map_err(|_| ApiError::err("couldnt_find_post"))?;
36
37     let id = data.id;
38     let comments = blocking(context.pool(), move |conn| {
39       CommentQueryBuilder::create(conn)
40         .my_person_id(person_id)
41         .post_id(id)
42         .limit(9999)
43         .list()
44     })
45     .await??;
46
47     let community_id = post_view.community.id;
48     let moderators = blocking(context.pool(), move |conn| {
49       CommunityModeratorView::for_community(conn, community_id)
50     })
51     .await??;
52
53     // Necessary for the sidebar
54     let community_view = blocking(context.pool(), move |conn| {
55       CommunityView::read(conn, community_id, person_id)
56     })
57     .await?
58     .map_err(|_| ApiError::err("couldnt_find_community"))?;
59
60     let online = context
61       .chat_server()
62       .send(GetPostUsersOnline { post_id: data.id })
63       .await
64       .unwrap_or(1);
65
66     // Return the jwt
67     Ok(GetPostResponse {
68       post_view,
69       community_view,
70       comments,
71       moderators,
72       online,
73     })
74   }
75 }
76
77 #[async_trait::async_trait(?Send)]
78 impl PerformCrud for GetPosts {
79   type Response = GetPostsResponse;
80
81   async fn perform(
82     &self,
83     context: &Data<LemmyContext>,
84     _websocket_id: Option<ConnectionId>,
85   ) -> Result<GetPostsResponse, LemmyError> {
86     let data: &GetPosts = &self;
87     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
88
89     let person_id = local_user_view.to_owned().map(|l| l.person.id);
90
91     let show_nsfw = match &local_user_view {
92       Some(uv) => uv.local_user.show_nsfw,
93       None => false,
94     };
95
96     let type_ = ListingType::from_str(&data.type_)?;
97     let sort = SortType::from_str(&data.sort)?;
98
99     let page = data.page;
100     let limit = data.limit;
101     let community_id = data.community_id;
102     let community_name = data.community_name.to_owned();
103     let saved_only = data.saved_only;
104
105     let posts = blocking(context.pool(), move |conn| {
106       PostQueryBuilder::create(conn)
107         .listing_type(&type_)
108         .sort(&sort)
109         .show_nsfw(show_nsfw)
110         .community_id(community_id)
111         .community_name(community_name)
112         .saved_only(saved_only)
113         .my_person_id(person_id)
114         .page(page)
115         .limit(limit)
116         .list()
117     })
118     .await?
119     .map_err(|_| ApiError::err("couldnt_get_posts"))?;
120
121     Ok(GetPostsResponse { posts })
122   }
123 }