]> Untitled Git - lemmy.git/blob - crates/api_crud/src/post/read.rs
Split api crate into api_structs and api
[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 = match blocking(context.pool(), move |conn| {
32       PostView::read(conn, id, person_id)
33     })
34     .await?
35     {
36       Ok(post) => post,
37       Err(_e) => return Err(ApiError::err("couldnt_find_post").into()),
38     };
39
40     let id = data.id;
41     let comments = blocking(context.pool(), move |conn| {
42       CommentQueryBuilder::create(conn)
43         .my_person_id(person_id)
44         .post_id(id)
45         .limit(9999)
46         .list()
47     })
48     .await??;
49
50     let community_id = post_view.community.id;
51     let moderators = blocking(context.pool(), move |conn| {
52       CommunityModeratorView::for_community(conn, community_id)
53     })
54     .await??;
55
56     // Necessary for the sidebar
57     let community_view = match blocking(context.pool(), move |conn| {
58       CommunityView::read(conn, community_id, person_id)
59     })
60     .await?
61     {
62       Ok(community) => community,
63       Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
64     };
65
66     let online = context
67       .chat_server()
68       .send(GetPostUsersOnline { post_id: data.id })
69       .await
70       .unwrap_or(1);
71
72     // Return the jwt
73     Ok(GetPostResponse {
74       post_view,
75       community_view,
76       comments,
77       moderators,
78       online,
79     })
80   }
81 }
82
83 #[async_trait::async_trait(?Send)]
84 impl PerformCrud for GetPosts {
85   type Response = GetPostsResponse;
86
87   async fn perform(
88     &self,
89     context: &Data<LemmyContext>,
90     _websocket_id: Option<ConnectionId>,
91   ) -> Result<GetPostsResponse, LemmyError> {
92     let data: &GetPosts = &self;
93     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
94
95     let person_id = match &local_user_view {
96       Some(uv) => Some(uv.person.id),
97       None => None,
98     };
99
100     let show_nsfw = match &local_user_view {
101       Some(uv) => uv.local_user.show_nsfw,
102       None => false,
103     };
104
105     let type_ = ListingType::from_str(&data.type_)?;
106     let sort = SortType::from_str(&data.sort)?;
107
108     let page = data.page;
109     let limit = data.limit;
110     let community_id = data.community_id;
111     let community_name = data.community_name.to_owned();
112     let saved_only = data.saved_only;
113
114     let posts = match blocking(context.pool(), move |conn| {
115       PostQueryBuilder::create(conn)
116         .listing_type(&type_)
117         .sort(&sort)
118         .show_nsfw(show_nsfw)
119         .community_id(community_id)
120         .community_name(community_name)
121         .saved_only(saved_only)
122         .my_person_id(person_id)
123         .page(page)
124         .limit(limit)
125         .list()
126     })
127     .await?
128     {
129       Ok(posts) => posts,
130       Err(_e) => return Err(ApiError::err("couldnt_get_posts").into()),
131     };
132
133     Ok(GetPostsResponse { posts })
134   }
135 }