]> Untitled Git - lemmy.git/blob - server/src/api/site.rs
Spanish translations
[lemmy.git] / server / src / api / site.rs
1 use super::*;
2 use std::str::FromStr;
3
4 #[derive(Serialize, Deserialize)]
5 pub struct ListCategories;
6
7 #[derive(Serialize, Deserialize)]
8 pub struct ListCategoriesResponse {
9   op: String,
10   categories: Vec<Category>,
11 }
12
13 #[derive(Serialize, Deserialize)]
14 pub struct Search {
15   q: String,
16   type_: String,
17   community_id: Option<i32>,
18   sort: String,
19   page: Option<i64>,
20   limit: Option<i64>,
21 }
22
23 #[derive(Serialize, Deserialize)]
24 pub struct SearchResponse {
25   op: String,
26   type_: String,
27   comments: Vec<CommentView>,
28   posts: Vec<PostView>,
29   communities: Vec<CommunityView>,
30   users: Vec<UserView>,
31 }
32
33 #[derive(Serialize, Deserialize)]
34 pub struct GetModlog {
35   mod_user_id: Option<i32>,
36   community_id: Option<i32>,
37   page: Option<i64>,
38   limit: Option<i64>,
39 }
40
41 #[derive(Serialize, Deserialize)]
42 pub struct GetModlogResponse {
43   op: String,
44   removed_posts: Vec<ModRemovePostView>,
45   locked_posts: Vec<ModLockPostView>,
46   stickied_posts: Vec<ModStickyPostView>,
47   removed_comments: Vec<ModRemoveCommentView>,
48   removed_communities: Vec<ModRemoveCommunityView>,
49   banned_from_community: Vec<ModBanFromCommunityView>,
50   banned: Vec<ModBanView>,
51   added_to_community: Vec<ModAddCommunityView>,
52   added: Vec<ModAddView>,
53 }
54
55 #[derive(Serialize, Deserialize)]
56 pub struct CreateSite {
57   name: String,
58   description: Option<String>,
59   auth: String,
60 }
61
62 #[derive(Serialize, Deserialize)]
63 pub struct EditSite {
64   name: String,
65   description: Option<String>,
66   auth: String,
67 }
68
69 #[derive(Serialize, Deserialize)]
70 pub struct GetSite;
71
72 #[derive(Serialize, Deserialize)]
73 pub struct SiteResponse {
74   op: String,
75   site: SiteView,
76 }
77
78 #[derive(Serialize, Deserialize)]
79 pub struct GetSiteResponse {
80   op: String,
81   site: Option<SiteView>,
82   admins: Vec<UserView>,
83   banned: Vec<UserView>,
84   pub online: usize,
85 }
86
87 #[derive(Serialize, Deserialize)]
88 pub struct TransferSite {
89   user_id: i32,
90   auth: String,
91 }
92
93 impl Perform<ListCategoriesResponse> for Oper<ListCategories> {
94   fn perform(&self) -> Result<ListCategoriesResponse, Error> {
95     let _data: &ListCategories = &self.data;
96     let conn = establish_connection();
97
98     let categories: Vec<Category> = Category::list_all(&conn)?;
99
100     // Return the jwt
101     Ok(ListCategoriesResponse {
102       op: self.op.to_string(),
103       categories: categories,
104     })
105   }
106 }
107
108 impl Perform<GetModlogResponse> for Oper<GetModlog> {
109   fn perform(&self) -> Result<GetModlogResponse, Error> {
110     let data: &GetModlog = &self.data;
111     let conn = establish_connection();
112
113     let removed_posts = ModRemovePostView::list(
114       &conn,
115       data.community_id,
116       data.mod_user_id,
117       data.page,
118       data.limit,
119     )?;
120     let locked_posts = ModLockPostView::list(
121       &conn,
122       data.community_id,
123       data.mod_user_id,
124       data.page,
125       data.limit,
126     )?;
127     let stickied_posts = ModStickyPostView::list(
128       &conn,
129       data.community_id,
130       data.mod_user_id,
131       data.page,
132       data.limit,
133     )?;
134     let removed_comments = ModRemoveCommentView::list(
135       &conn,
136       data.community_id,
137       data.mod_user_id,
138       data.page,
139       data.limit,
140     )?;
141     let banned_from_community = ModBanFromCommunityView::list(
142       &conn,
143       data.community_id,
144       data.mod_user_id,
145       data.page,
146       data.limit,
147     )?;
148     let added_to_community = ModAddCommunityView::list(
149       &conn,
150       data.community_id,
151       data.mod_user_id,
152       data.page,
153       data.limit,
154     )?;
155
156     // These arrays are only for the full modlog, when a community isn't given
157     let mut removed_communities = Vec::new();
158     let mut banned = Vec::new();
159     let mut added = Vec::new();
160
161     if data.community_id.is_none() {
162       removed_communities =
163         ModRemoveCommunityView::list(&conn, data.mod_user_id, data.page, data.limit)?;
164       banned = ModBanView::list(&conn, data.mod_user_id, data.page, data.limit)?;
165       added = ModAddView::list(&conn, data.mod_user_id, data.page, data.limit)?;
166     }
167
168     // Return the jwt
169     Ok(GetModlogResponse {
170       op: self.op.to_string(),
171       removed_posts: removed_posts,
172       locked_posts: locked_posts,
173       stickied_posts: stickied_posts,
174       removed_comments: removed_comments,
175       removed_communities: removed_communities,
176       banned_from_community: banned_from_community,
177       banned: banned,
178       added_to_community: added_to_community,
179       added: added,
180     })
181   }
182 }
183
184 impl Perform<SiteResponse> for Oper<CreateSite> {
185   fn perform(&self) -> Result<SiteResponse, Error> {
186     let data: &CreateSite = &self.data;
187     let conn = establish_connection();
188
189     let claims = match Claims::decode(&data.auth) {
190       Ok(claims) => claims.claims,
191       Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
192     };
193
194     if has_slurs(&data.name)
195       || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
196     {
197       return Err(APIError::err(&self.op, "no_slurs"))?;
198     }
199
200     let user_id = claims.id;
201
202     // Make sure user is an admin
203     if !UserView::read(&conn, user_id)?.admin {
204       return Err(APIError::err(&self.op, "not_an_admin"))?;
205     }
206
207     let site_form = SiteForm {
208       name: data.name.to_owned(),
209       description: data.description.to_owned(),
210       creator_id: user_id,
211       updated: None,
212     };
213
214     match Site::create(&conn, &site_form) {
215       Ok(site) => site,
216       Err(_e) => return Err(APIError::err(&self.op, "site_already_exists"))?,
217     };
218
219     let site_view = SiteView::read(&conn)?;
220
221     Ok(SiteResponse {
222       op: self.op.to_string(),
223       site: site_view,
224     })
225   }
226 }
227
228 impl Perform<SiteResponse> for Oper<EditSite> {
229   fn perform(&self) -> Result<SiteResponse, Error> {
230     let data: &EditSite = &self.data;
231     let conn = establish_connection();
232
233     let claims = match Claims::decode(&data.auth) {
234       Ok(claims) => claims.claims,
235       Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
236     };
237
238     if has_slurs(&data.name)
239       || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
240     {
241       return Err(APIError::err(&self.op, "no_slurs"))?;
242     }
243
244     let user_id = claims.id;
245
246     // Make sure user is an admin
247     if UserView::read(&conn, user_id)?.admin == false {
248       return Err(APIError::err(&self.op, "not_an_admin"))?;
249     }
250
251     let found_site = Site::read(&conn, 1)?;
252
253     let site_form = SiteForm {
254       name: data.name.to_owned(),
255       description: data.description.to_owned(),
256       creator_id: found_site.creator_id,
257       updated: Some(naive_now()),
258     };
259
260     match Site::update(&conn, 1, &site_form) {
261       Ok(site) => site,
262       Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_site"))?,
263     };
264
265     let site_view = SiteView::read(&conn)?;
266
267     Ok(SiteResponse {
268       op: self.op.to_string(),
269       site: site_view,
270     })
271   }
272 }
273
274 impl Perform<GetSiteResponse> for Oper<GetSite> {
275   fn perform(&self) -> Result<GetSiteResponse, Error> {
276     let _data: &GetSite = &self.data;
277     let conn = establish_connection();
278
279     // It can return a null site in order to redirect
280     let site_view = match Site::read(&conn, 1) {
281       Ok(_site) => Some(SiteView::read(&conn)?),
282       Err(_e) => None,
283     };
284
285     let mut admins = UserView::admins(&conn)?;
286     if site_view.is_some() {
287       let site_creator_id = site_view.to_owned().unwrap().creator_id;
288       let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
289       let creator_user = admins.remove(creator_index);
290       admins.insert(0, creator_user);
291     }
292
293     let banned = UserView::banned(&conn)?;
294
295     Ok(GetSiteResponse {
296       op: self.op.to_string(),
297       site: site_view,
298       admins: admins,
299       banned: banned,
300       online: 0,
301     })
302   }
303 }
304
305 impl Perform<SearchResponse> for Oper<Search> {
306   fn perform(&self) -> Result<SearchResponse, Error> {
307     let data: &Search = &self.data;
308     let conn = establish_connection();
309
310     let sort = SortType::from_str(&data.sort)?;
311     let type_ = SearchType::from_str(&data.type_)?;
312
313     let mut posts = Vec::new();
314     let mut comments = Vec::new();
315     let mut communities = Vec::new();
316     let mut users = Vec::new();
317
318     // TODO no clean / non-nsfw searching rn
319
320     match type_ {
321       SearchType::Posts => {
322         posts = PostView::list(
323           &conn,
324           PostListingType::All,
325           &sort,
326           data.community_id,
327           None,
328           Some(data.q.to_owned()),
329           None,
330           None,
331           true,
332           false,
333           false,
334           data.page,
335           data.limit,
336         )?;
337       }
338       SearchType::Comments => {
339         comments = CommentView::list(
340           &conn,
341           &sort,
342           None,
343           None,
344           Some(data.q.to_owned()),
345           None,
346           false,
347           data.page,
348           data.limit,
349         )?;
350       }
351       SearchType::Communities => {
352         communities = CommunityView::list(
353           &conn,
354           &sort,
355           None,
356           true,
357           Some(data.q.to_owned()),
358           data.page,
359           data.limit,
360         )?;
361       }
362       SearchType::Users => {
363         users = UserView::list(&conn, &sort, Some(data.q.to_owned()), data.page, data.limit)?;
364       }
365       SearchType::All => {
366         posts = PostView::list(
367           &conn,
368           PostListingType::All,
369           &sort,
370           data.community_id,
371           None,
372           Some(data.q.to_owned()),
373           None,
374           None,
375           true,
376           false,
377           false,
378           data.page,
379           data.limit,
380         )?;
381         comments = CommentView::list(
382           &conn,
383           &sort,
384           None,
385           None,
386           Some(data.q.to_owned()),
387           None,
388           false,
389           data.page,
390           data.limit,
391         )?;
392         communities = CommunityView::list(
393           &conn,
394           &sort,
395           None,
396           true,
397           Some(data.q.to_owned()),
398           data.page,
399           data.limit,
400         )?;
401         users = UserView::list(&conn, &sort, Some(data.q.to_owned()), data.page, data.limit)?;
402       }
403       SearchType::Url => {
404         posts = PostView::list(
405           &conn,
406           PostListingType::All,
407           &sort,
408           data.community_id,
409           None,
410           None,
411           Some(data.q.to_owned()),
412           None,
413           true,
414           false,
415           false,
416           data.page,
417           data.limit,
418         )?;
419       }
420     };
421
422     // Return the jwt
423     Ok(SearchResponse {
424       op: self.op.to_string(),
425       type_: data.type_.to_owned(),
426       comments: comments,
427       posts: posts,
428       communities: communities,
429       users: users,
430     })
431   }
432 }
433
434 impl Perform<GetSiteResponse> for Oper<TransferSite> {
435   fn perform(&self) -> Result<GetSiteResponse, Error> {
436     let data: &TransferSite = &self.data;
437     let conn = establish_connection();
438
439     let claims = match Claims::decode(&data.auth) {
440       Ok(claims) => claims.claims,
441       Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
442     };
443
444     let user_id = claims.id;
445
446     let read_site = Site::read(&conn, 1)?;
447
448     // Make sure user is the creator
449     if read_site.creator_id != user_id {
450       return Err(APIError::err(&self.op, "not_an_admin"))?;
451     }
452
453     let site_form = SiteForm {
454       name: read_site.name,
455       description: read_site.description,
456       creator_id: data.user_id,
457       updated: Some(naive_now()),
458     };
459
460     match Site::update(&conn, 1, &site_form) {
461       Ok(site) => site,
462       Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_site"))?,
463     };
464
465     // Mod tables
466     let form = ModAddForm {
467       mod_user_id: user_id,
468       other_user_id: data.user_id,
469       removed: Some(false),
470     };
471
472     ModAdd::create(&conn, &form)?;
473
474     let site_view = SiteView::read(&conn)?;
475
476     let mut admins = UserView::admins(&conn)?;
477     let creator_index = admins
478       .iter()
479       .position(|r| r.id == site_view.creator_id)
480       .unwrap();
481     let creator_user = admins.remove(creator_index);
482     admins.insert(0, creator_user);
483
484     let banned = UserView::banned(&conn)?;
485
486     Ok(GetSiteResponse {
487       op: self.op.to_string(),
488       site: Some(site_view),
489       admins: admins,
490       banned: banned,
491       online: 0,
492     })
493   }
494 }