4 #[derive(Serialize, Deserialize)]
5 pub struct CreatePost {
13 #[derive(Serialize, Deserialize, Clone)]
14 pub struct PostResponse {
20 #[derive(Serialize, Deserialize)]
26 #[derive(Serialize, Deserialize)]
27 pub struct GetPostResponse {
30 comments: Vec<CommentView>,
31 community: CommunityView,
32 moderators: Vec<CommunityModeratorView>,
33 admins: Vec<UserView>,
36 #[derive(Serialize, Deserialize)]
42 community_id: Option<i32>,
46 #[derive(Serialize, Deserialize)]
47 pub struct GetPostsResponse {
52 #[derive(Serialize, Deserialize)]
53 pub struct CreatePostLike {
59 #[derive(Serialize, Deserialize)]
60 pub struct CreatePostLikeResponse {
66 #[derive(Serialize, Deserialize)]
74 removed: Option<bool>,
75 deleted: Option<bool>,
77 reason: Option<String>,
81 #[derive(Serialize, Deserialize)]
88 impl Perform<PostResponse> for Oper<CreatePost> {
89 fn perform(&self) -> Result<PostResponse, Error> {
90 let data: &CreatePost = &self.data;
91 let conn = establish_connection();
94 let claims = match Claims::decode(&data.auth) {
95 Ok(claims) => claims.claims,
97 return Err(APIError::err(&self.op, "Not logged in."))?
101 if has_slurs(&data.name) ||
102 (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) {
103 return Err(APIError::err(&self.op, "No slurs"))?
106 let user_id = claims.id;
108 // Check for a community ban
109 if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() {
110 return Err(APIError::err(&self.op, "You have been banned from this community"))?
113 // Check for a site ban
114 if UserView::read(&conn, user_id)?.banned {
115 return Err(APIError::err(&self.op, "You have been banned from the site"))?
118 let post_form = PostForm {
119 name: data.name.to_owned(),
120 url: data.url.to_owned(),
121 body: data.body.to_owned(),
122 community_id: data.community_id,
130 let inserted_post = match Post::create(&conn, &post_form) {
133 return Err(APIError::err(&self.op, "Couldn't create Post"))?
137 // They like their own post by default
138 let like_form = PostLikeForm {
139 post_id: inserted_post.id,
144 // Only add the like if the score isnt 0
145 let _inserted_like = match PostLike::like(&conn, &like_form) {
148 return Err(APIError::err(&self.op, "Couldn't like post."))?
153 let post_view = match PostView::read(&conn, inserted_post.id, Some(user_id)) {
156 return Err(APIError::err(&self.op, "Couldn't find Post"))?
162 op: self.op.to_string(),
169 impl Perform<GetPostResponse> for Oper<GetPost> {
170 fn perform(&self) -> Result<GetPostResponse, Error> {
171 let data: &GetPost = &self.data;
172 let conn = establish_connection();
174 let user_id: Option<i32> = match &data.auth {
176 match Claims::decode(&auth) {
178 let user_id = claims.claims.id;
187 let post_view = match PostView::read(&conn, data.id, user_id) {
190 return Err(APIError::err(&self.op, "Couldn't find Post"))?
194 let comments = CommentView::list(&conn, &SortType::New, Some(data.id), None, None, user_id, false, None, Some(9999))?;
196 let community = CommunityView::read(&conn, post_view.community_id, user_id)?;
198 let moderators = CommunityModeratorView::for_community(&conn, post_view.community_id)?;
200 let admins = UserView::admins(&conn)?;
205 op: self.op.to_string(),
208 community: community,
209 moderators: moderators,
217 impl Perform<GetPostsResponse> for Oper<GetPosts> {
218 fn perform(&self) -> Result<GetPostsResponse, Error> {
219 let data: &GetPosts = &self.data;
220 let conn = establish_connection();
222 let user_id: Option<i32> = match &data.auth {
224 match Claims::decode(&auth) {
226 let user_id = claims.claims.id;
235 let type_ = PostListingType::from_str(&data.type_)?;
236 let sort = SortType::from_str(&data.sort)?;
238 let posts = match PostView::list(&conn,
251 return Err(APIError::err(&self.op, "Couldn't get posts"))?
258 op: self.op.to_string(),
265 impl Perform<CreatePostLikeResponse> for Oper<CreatePostLike> {
266 fn perform(&self) -> Result<CreatePostLikeResponse, Error> {
267 let data: &CreatePostLike = &self.data;
268 let conn = establish_connection();
270 let claims = match Claims::decode(&data.auth) {
271 Ok(claims) => claims.claims,
273 return Err(APIError::err(&self.op, "Not logged in."))?
277 let user_id = claims.id;
279 // Check for a community ban
280 let post = Post::read(&conn, data.post_id)?;
281 if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
282 return Err(APIError::err(&self.op, "You have been banned from this community"))?
285 // Check for a site ban
286 if UserView::read(&conn, user_id)?.banned {
287 return Err(APIError::err(&self.op, "You have been banned from the site"))?
290 let like_form = PostLikeForm {
291 post_id: data.post_id,
296 // Remove any likes first
297 PostLike::remove(&conn, &like_form)?;
299 // Only add the like if the score isnt 0
300 let do_add = &like_form.score != &0 && (&like_form.score == &1 || &like_form.score == &-1);
302 let _inserted_like = match PostLike::like(&conn, &like_form) {
305 return Err(APIError::err(&self.op, "Couldn't like post."))?
310 let post_view = match PostView::read(&conn, data.post_id, Some(user_id)) {
313 return Err(APIError::err(&self.op, "Couldn't find Post"))?
317 // just output the score
319 CreatePostLikeResponse {
320 op: self.op.to_string(),
327 impl Perform<PostResponse> for Oper<EditPost> {
328 fn perform(&self) -> Result<PostResponse, Error> {
329 let data: &EditPost = &self.data;
330 if has_slurs(&data.name) ||
331 (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) {
332 return Err(APIError::err(&self.op, "No slurs"))?
335 let conn = establish_connection();
337 let claims = match Claims::decode(&data.auth) {
338 Ok(claims) => claims.claims,
340 return Err(APIError::err(&self.op, "Not logged in."))?
344 let user_id = claims.id;
346 // Verify its the creator or a mod or admin
347 let mut editors: Vec<i32> = vec![data.creator_id];
349 &mut CommunityModeratorView::for_community(&conn, data.community_id)
356 &mut UserView::admins(&conn)
362 if !editors.contains(&user_id) {
363 return Err(APIError::err(&self.op, "Not allowed to edit post."))?
366 // Check for a community ban
367 if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() {
368 return Err(APIError::err(&self.op, "You have been banned from this community"))?
371 // Check for a site ban
372 if UserView::read(&conn, user_id)?.banned {
373 return Err(APIError::err(&self.op, "You have been banned from the site"))?
376 let post_form = PostForm {
377 name: data.name.to_owned(),
378 url: data.url.to_owned(),
379 body: data.body.to_owned(),
380 creator_id: data.creator_id.to_owned(),
381 community_id: data.community_id,
382 removed: data.removed.to_owned(),
383 deleted: data.deleted.to_owned(),
384 locked: data.locked.to_owned(),
385 updated: Some(naive_now())
388 let _updated_post = match Post::update(&conn, data.edit_id, &post_form) {
391 return Err(APIError::err(&self.op, "Couldn't update Post"))?
396 if let Some(removed) = data.removed.to_owned() {
397 let form = ModRemovePostForm {
398 mod_user_id: user_id,
399 post_id: data.edit_id,
400 removed: Some(removed),
401 reason: data.reason.to_owned(),
403 ModRemovePost::create(&conn, &form)?;
406 if let Some(locked) = data.locked.to_owned() {
407 let form = ModLockPostForm {
408 mod_user_id: user_id,
409 post_id: data.edit_id,
410 locked: Some(locked),
412 ModLockPost::create(&conn, &form)?;
415 let post_view = PostView::read(&conn, data.edit_id, Some(user_id))?;
419 op: self.op.to_string(),
426 impl Perform<PostResponse> for Oper<SavePost> {
427 fn perform(&self) -> Result<PostResponse, Error> {
428 let data: &SavePost = &self.data;
429 let conn = establish_connection();
431 let claims = match Claims::decode(&data.auth) {
432 Ok(claims) => claims.claims,
434 return Err(APIError::err(&self.op, "Not logged in."))?
438 let user_id = claims.id;
440 let post_saved_form = PostSavedForm {
441 post_id: data.post_id,
446 match PostSaved::save(&conn, &post_saved_form) {
449 return Err(APIError::err(&self.op, "Couldnt do post save"))?
453 match PostSaved::unsave(&conn, &post_saved_form) {
456 return Err(APIError::err(&self.op, "Couldnt do post save"))?
461 let post_view = PostView::read(&conn, data.post_id, Some(user_id))?;
465 op: self.op.to_string(),