]> Untitled Git - lemmy.git/blob - crates/api_crud/src/community/read.rs
54f27851032b3702d007cac12fb701c4c4a3c335
[lemmy.git] / crates / api_crud / src / community / read.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt_opt};
4 use lemmy_apub::{
5   fetcher::webfinger::webfinger_resolve,
6   objects::community::ApubCommunity,
7   EndpointType,
8 };
9 use lemmy_apub_lib::object_id::ObjectId;
10 use lemmy_db_schema::{
11   from_opt_str_to_opt_enum,
12   traits::DeleteableOrRemoveable,
13   ListingType,
14   SortType,
15 };
16 use lemmy_db_views_actor::{
17   community_moderator_view::CommunityModeratorView,
18   community_view::{CommunityQueryBuilder, CommunityView},
19 };
20 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
21 use lemmy_websocket::{messages::GetCommunityUsersOnline, LemmyContext};
22
23 #[async_trait::async_trait(?Send)]
24 impl PerformCrud for GetCommunity {
25   type Response = GetCommunityResponse;
26
27   async fn perform(
28     &self,
29     context: &Data<LemmyContext>,
30     _websocket_id: Option<ConnectionId>,
31   ) -> Result<GetCommunityResponse, LemmyError> {
32     let data: &GetCommunity = self;
33     let local_user_view =
34       get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
35     let person_id = local_user_view.map(|u| u.person.id);
36
37     let community_id = match data.id {
38       Some(id) => id,
39       None => {
40         let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
41         let community_actor_id =
42           webfinger_resolve::<ApubCommunity>(&name, EndpointType::Community, context, &mut 0)
43             .await?;
44
45         ObjectId::<ApubCommunity>::new(community_actor_id)
46           .dereference(context, &mut 0)
47           .await
48           .map_err(|e| ApiError::err("couldnt_find_community", e))?
49           .id
50       }
51     };
52
53     let mut community_view = blocking(context.pool(), move |conn| {
54       CommunityView::read(conn, community_id, person_id)
55     })
56     .await?
57     .map_err(|e| ApiError::err("couldnt_find_community", e))?;
58
59     // Blank out deleted or removed info for non-logged in users
60     if person_id.is_none() && (community_view.community.deleted || community_view.community.removed)
61     {
62       community_view.community = community_view.community.blank_out_deleted_or_removed_info();
63     }
64
65     let moderators: Vec<CommunityModeratorView> = blocking(context.pool(), move |conn| {
66       CommunityModeratorView::for_community(conn, community_id)
67     })
68     .await?
69     .map_err(|e| ApiError::err("couldnt_find_community", e))?;
70
71     let online = context
72       .chat_server()
73       .send(GetCommunityUsersOnline { community_id })
74       .await
75       .unwrap_or(1);
76
77     let res = GetCommunityResponse {
78       community_view,
79       moderators,
80       online,
81     };
82
83     // Return the jwt
84     Ok(res)
85   }
86 }
87
88 #[async_trait::async_trait(?Send)]
89 impl PerformCrud for ListCommunities {
90   type Response = ListCommunitiesResponse;
91
92   async fn perform(
93     &self,
94     context: &Data<LemmyContext>,
95     _websocket_id: Option<ConnectionId>,
96   ) -> Result<ListCommunitiesResponse, LemmyError> {
97     let data: &ListCommunities = self;
98     let local_user_view =
99       get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
100
101     let person_id = local_user_view.to_owned().map(|l| l.person.id);
102
103     // Don't show NSFW by default
104     let show_nsfw = match &local_user_view {
105       Some(uv) => uv.local_user.show_nsfw,
106       None => false,
107     };
108
109     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
110     let listing_type: Option<ListingType> = from_opt_str_to_opt_enum(&data.type_);
111
112     let page = data.page;
113     let limit = data.limit;
114     let mut communities = blocking(context.pool(), move |conn| {
115       CommunityQueryBuilder::create(conn)
116         .listing_type(listing_type)
117         .sort(sort)
118         .show_nsfw(show_nsfw)
119         .my_person_id(person_id)
120         .page(page)
121         .limit(limit)
122         .list()
123     })
124     .await??;
125
126     // Blank out deleted or removed info for non-logged in users
127     if person_id.is_none() {
128       for cv in communities
129         .iter_mut()
130         .filter(|cv| cv.community.deleted || cv.community.removed)
131       {
132         cv.community = cv.to_owned().community.blank_out_deleted_or_removed_info();
133       }
134     }
135
136     // Return the jwt
137     Ok(ListCommunitiesResponse { communities })
138   }
139 }