]> Untitled Git - lemmy.git/commitdiff
Adding report views.
authorDessalines <tyhou13@gmx.com>
Thu, 17 Dec 2020 03:03:03 +0000 (22:03 -0500)
committerDessalines <tyhou13@gmx.com>
Thu, 17 Dec 2020 03:03:03 +0000 (22:03 -0500)
16 files changed:
lemmy_api/src/comment.rs
lemmy_api/src/post.rs
lemmy_api/src/user.rs
lemmy_db/src/comment_report.rs [deleted file]
lemmy_db/src/lib.rs
lemmy_db/src/post_report.rs [deleted file]
lemmy_db/src/schema.rs
lemmy_db/src/source/comment_report.rs [new file with mode: 0644]
lemmy_db/src/source/mod.rs
lemmy_db/src/source/post_report.rs [new file with mode: 0644]
lemmy_db/src/source/user.rs
lemmy_db/src/views/comment_report_view.rs [new file with mode: 0644]
lemmy_db/src/views/mod.rs
lemmy_db/src/views/post_report_view.rs [new file with mode: 0644]
lemmy_structs/src/comment.rs
lemmy_structs/src/post.rs

index b39444efd0a0e247be8b33851707053b99fe96b6..689fe4b8abb0da3e47c801344046db7e23c80dad 100644 (file)
@@ -10,9 +10,15 @@ use crate::{
 use actix_web::web::Data;
 use lemmy_apub::{ApubLikeableType, ApubObjectType};
 use lemmy_db::{
-  comment_report::*,
-  source::{comment::*, moderator::*, post::*, user::*},
+  source::{
+    comment::*,
+    comment_report::{CommentReport, CommentReportForm},
+    moderator::*,
+    post::*,
+    user::*,
+  },
   views::{
+    comment_report_view::{CommentReportQueryBuilder, CommentReportView},
     comment_view::{CommentQueryBuilder, CommentView},
     site_view::SiteView,
   },
@@ -776,7 +782,7 @@ impl Perform for ResolveCommentReport {
     .await??;
 
     let user_id = user.id;
-    is_mod_or_admin(context.pool(), user_id, report.community_id).await?;
+    is_mod_or_admin(context.pool(), user_id, report.community.id).await?;
 
     let resolved = data.resolved;
     let resolve_fun = move |conn: &'_ _| {
@@ -800,7 +806,7 @@ impl Perform for ResolveCommentReport {
     context.chat_server().do_send(SendModRoomMessage {
       op: UserOperation::ResolveCommentReport,
       response: res.clone(),
-      community_id: report.community_id,
+      community_id: report.community.id,
       websocket_id,
     });
 
index 02da229fd912b884ab0c30db0b54fe57587cc506..22f95877a294ae5e4e7bc1cdf3c25f267ea411cd 100644 (file)
@@ -11,11 +11,15 @@ use actix_web::web::Data;
 use lemmy_apub::{ApubLikeableType, ApubObjectType};
 use lemmy_db::{
   naive_now,
-  post_report::*,
-  source::{moderator::*, post::*},
+  source::{
+    moderator::*,
+    post::*,
+    post_report::{PostReport, PostReportForm},
+  },
   views::{
     comment_view::CommentQueryBuilder,
     community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
+    post_report_view::{PostReportQueryBuilder, PostReportView},
     post_view::{PostQueryBuilder, PostView},
     site_view::SiteView,
   },
@@ -835,7 +839,7 @@ impl Perform for ResolvePostReport {
     .await??;
 
     let user_id = user.id;
-    is_mod_or_admin(context.pool(), user_id, report.community_id).await?;
+    is_mod_or_admin(context.pool(), user_id, report.community.id).await?;
 
     let resolved = data.resolved;
     let resolve_fun = move |conn: &'_ _| {
@@ -858,7 +862,7 @@ impl Perform for ResolvePostReport {
     context.chat_server().do_send(SendModRoomMessage {
       op: UserOperation::ResolvePostReport,
       response: res.clone(),
-      community_id: report.community_id,
+      community_id: report.community.id,
       websocket_id,
     });
 
index 327a1a42634f4f531da6db920ba7e4d627960f5e..f31e42e5a9cf12b095b32092dfa055275e601448 100644 (file)
@@ -15,10 +15,8 @@ use captcha::{gen, Difficulty};
 use chrono::Duration;
 use lemmy_apub::ApubObjectType;
 use lemmy_db::{
-  comment_report::CommentReportView,
   diesel_option_overwrite,
   naive_now,
-  post_report::PostReportView,
   source::{
     comment::*,
     community::*,
@@ -31,11 +29,13 @@ use lemmy_db::{
     user_mention::*,
   },
   views::{
+    comment_report_view::CommentReportView,
     comment_view::CommentQueryBuilder,
     community::{
       community_follower_view::CommunityFollowerView,
       community_moderator_view::CommunityModeratorView,
     },
+    post_report_view::PostReportView,
     post_view::PostQueryBuilder,
     private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView},
     site_view::SiteView,
diff --git a/lemmy_db/src/comment_report.rs b/lemmy_db/src/comment_report.rs
deleted file mode 100644 (file)
index 240b734..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-use diesel::{dsl::*, pg::Pg, result::Error, *};
-use serde::{Deserialize, Serialize};
-
-use crate::{
-  limit_and_offset,
-  naive_now,
-  schema::comment_report,
-  source::comment::Comment,
-  MaybeOptional,
-  Reportable,
-};
-
-table! {
-    comment_report_view (id) {
-      id -> Int4,
-      creator_id -> Int4,
-      comment_id -> Int4,
-      original_comment_text -> Text,
-      reason -> Text,
-      resolved -> Bool,
-      resolver_id -> Nullable<Int4>,
-      published -> Timestamp,
-      updated -> Nullable<Timestamp>,
-      post_id -> Int4,
-      current_comment_text -> Text,
-      community_id -> Int4,
-      creator_actor_id -> Text,
-      creator_name -> Varchar,
-      creator_preferred_username -> Nullable<Varchar>,
-      creator_avatar -> Nullable<Text>,
-      creator_local -> Bool,
-      comment_creator_id -> Int4,
-      comment_creator_actor_id -> Text,
-      comment_creator_name -> Varchar,
-      comment_creator_preferred_username -> Nullable<Varchar>,
-      comment_creator_avatar -> Nullable<Text>,
-      comment_creator_local -> Bool,
-      resolver_actor_id -> Nullable<Text>,
-      resolver_name -> Nullable<Varchar>,
-      resolver_preferred_username -> Nullable<Varchar>,
-      resolver_avatar -> Nullable<Text>,
-      resolver_local -> Nullable<Bool>,
-    }
-}
-
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Serialize)]
-#[belongs_to(Comment)]
-#[table_name = "comment_report"]
-pub struct CommentReport {
-  pub id: i32,
-  pub creator_id: i32,
-  pub comment_id: i32,
-  pub original_comment_text: String,
-  pub reason: String,
-  pub resolved: bool,
-  pub resolver_id: Option<i32>,
-  pub published: chrono::NaiveDateTime,
-  pub updated: Option<chrono::NaiveDateTime>,
-}
-
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "comment_report"]
-pub struct CommentReportForm {
-  pub creator_id: i32,
-  pub comment_id: i32,
-  pub original_comment_text: String,
-  pub reason: String,
-}
-
-impl Reportable<CommentReportForm> for CommentReport {
-  /// creates a comment report and returns it
-  ///
-  /// * `conn` - the postgres connection
-  /// * `comment_report_form` - the filled CommentReportForm to insert
-  fn report(conn: &PgConnection, comment_report_form: &CommentReportForm) -> Result<Self, Error> {
-    use crate::schema::comment_report::dsl::*;
-    insert_into(comment_report)
-      .values(comment_report_form)
-      .get_result::<Self>(conn)
-  }
-
-  /// resolve a comment report
-  ///
-  /// * `conn` - the postgres connection
-  /// * `report_id` - the id of the report to resolve
-  /// * `by_resolver_id` - the id of the user resolving the report
-  fn resolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
-    use crate::schema::comment_report::dsl::*;
-    update(comment_report.find(report_id))
-      .set((
-        resolved.eq(true),
-        resolver_id.eq(by_resolver_id),
-        updated.eq(naive_now()),
-      ))
-      .execute(conn)
-  }
-
-  /// unresolve a comment report
-  ///
-  /// * `conn` - the postgres connection
-  /// * `report_id` - the id of the report to unresolve
-  /// * `by_resolver_id` - the id of the user unresolving the report
-  fn unresolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
-    use crate::schema::comment_report::dsl::*;
-    update(comment_report.find(report_id))
-      .set((
-        resolved.eq(false),
-        resolver_id.eq(by_resolver_id),
-        updated.eq(naive_now()),
-      ))
-      .execute(conn)
-  }
-}
-
-#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone)]
-#[table_name = "comment_report_view"]
-pub struct CommentReportView {
-  pub id: i32,
-  pub creator_id: i32,
-  pub comment_id: i32,
-  pub original_comment_text: String,
-  pub reason: String,
-  pub resolved: bool,
-  pub resolver_id: Option<i32>,
-  pub published: chrono::NaiveDateTime,
-  pub updated: Option<chrono::NaiveDateTime>,
-  pub post_id: i32,
-  pub current_comment_text: String,
-  pub community_id: i32,
-  pub creator_actor_id: String,
-  pub creator_name: String,
-  pub creator_preferred_username: Option<String>,
-  pub creator_avatar: Option<String>,
-  pub creator_local: bool,
-  pub comment_creator_id: i32,
-  pub comment_creator_actor_id: String,
-  pub comment_creator_name: String,
-  pub comment_creator_preferred_username: Option<String>,
-  pub comment_creator_avatar: Option<String>,
-  pub comment_creator_local: bool,
-  pub resolver_actor_id: Option<String>,
-  pub resolver_name: Option<String>,
-  pub resolver_preferred_username: Option<String>,
-  pub resolver_avatar: Option<String>,
-  pub resolver_local: Option<bool>,
-}
-
-pub struct CommentReportQueryBuilder<'a> {
-  conn: &'a PgConnection,
-  query: comment_report_view::BoxedQuery<'a, Pg>,
-  for_community_ids: Option<Vec<i32>>,
-  page: Option<i64>,
-  limit: Option<i64>,
-  resolved: Option<bool>,
-}
-
-impl CommentReportView {
-  /// returns the CommentReportView for the provided report_id
-  ///
-  /// * `report_id` - the report id to obtain
-  pub fn read(conn: &PgConnection, report_id: i32) -> Result<Self, Error> {
-    use super::comment_report::comment_report_view::dsl::*;
-    comment_report_view.find(report_id).first::<Self>(conn)
-  }
-
-  /// returns the current unresolved comment report count for the supplied community ids
-  ///
-  /// * `community_ids` - a Vec<i32> of community_ids to get a count for
-  pub fn get_report_count(conn: &PgConnection, community_ids: &[i32]) -> Result<i64, Error> {
-    use super::comment_report::comment_report_view::dsl::*;
-    comment_report_view
-      .filter(resolved.eq(false).and(community_id.eq_any(community_ids)))
-      .select(count(id))
-      .first::<i64>(conn)
-  }
-}
-
-impl<'a> CommentReportQueryBuilder<'a> {
-  pub fn create(conn: &'a PgConnection) -> Self {
-    use super::comment_report::comment_report_view::dsl::*;
-
-    let query = comment_report_view.into_boxed();
-
-    CommentReportQueryBuilder {
-      conn,
-      query,
-      for_community_ids: None,
-      page: None,
-      limit: None,
-      resolved: Some(false),
-    }
-  }
-
-  pub fn community_ids<T: MaybeOptional<Vec<i32>>>(mut self, community_ids: T) -> Self {
-    self.for_community_ids = community_ids.get_optional();
-    self
-  }
-
-  pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
-    self.page = page.get_optional();
-    self
-  }
-
-  pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
-    self.limit = limit.get_optional();
-    self
-  }
-
-  pub fn resolved<T: MaybeOptional<bool>>(mut self, resolved: T) -> Self {
-    self.resolved = resolved.get_optional();
-    self
-  }
-
-  pub fn list(self) -> Result<Vec<CommentReportView>, Error> {
-    use super::comment_report::comment_report_view::dsl::*;
-
-    let mut query = self.query;
-
-    if let Some(comm_ids) = self.for_community_ids {
-      query = query.filter(community_id.eq_any(comm_ids));
-    }
-
-    if let Some(resolved_flag) = self.resolved {
-      query = query.filter(resolved.eq(resolved_flag));
-    }
-
-    let (limit, offset) = limit_and_offset(self.page, self.limit);
-
-    query
-      .order_by(published.asc())
-      .limit(limit)
-      .offset(offset)
-      .load::<CommentReportView>(self.conn)
-  }
-}
index 6b026f95de707f2ec8308ba4f4a0bdde71908189..387e38a2829471e219e5bee198cbc38703be0f90 100644 (file)
@@ -11,9 +11,6 @@ use regex::Regex;
 use serde::{Deserialize, Serialize};
 use std::{env, env::VarError};
 
-pub mod comment_report;
-pub mod post_report;
-
 pub mod aggregates;
 pub mod schema;
 pub mod source;
diff --git a/lemmy_db/src/post_report.rs b/lemmy_db/src/post_report.rs
deleted file mode 100644 (file)
index 230368c..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-use diesel::{dsl::*, pg::Pg, result::Error, *};
-use serde::{Deserialize, Serialize};
-
-use crate::{
-  limit_and_offset,
-  naive_now,
-  schema::post_report,
-  source::post::Post,
-  MaybeOptional,
-  Reportable,
-};
-
-table! {
-    post_report_view (id) {
-        id -> Int4,
-        creator_id -> Int4,
-        post_id -> Int4,
-        original_post_name -> Varchar,
-        original_post_url -> Nullable<Text>,
-        original_post_body -> Nullable<Text>,
-        reason -> Text,
-        resolved -> Bool,
-        resolver_id -> Nullable<Int4>,
-        published -> Timestamp,
-        updated -> Nullable<Timestamp>,
-        current_post_name -> Varchar,
-        current_post_url -> Nullable<Text>,
-        current_post_body -> Nullable<Text>,
-        community_id -> Int4,
-        creator_actor_id -> Text,
-        creator_name -> Varchar,
-        creator_preferred_username -> Nullable<Varchar>,
-        creator_avatar -> Nullable<Text>,
-        creator_local -> Bool,
-        post_creator_id -> Int4,
-        post_creator_actor_id -> Text,
-        post_creator_name -> Varchar,
-        post_creator_preferred_username -> Nullable<Varchar>,
-        post_creator_avatar -> Nullable<Text>,
-        post_creator_local -> Bool,
-        resolver_actor_id -> Nullable<Text>,
-        resolver_name -> Nullable<Varchar>,
-        resolver_preferred_username -> Nullable<Varchar>,
-        resolver_avatar -> Nullable<Text>,
-        resolver_local -> Nullable<Bool>,
-    }
-}
-
-#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug)]
-#[belongs_to(Post)]
-#[table_name = "post_report"]
-pub struct PostReport {
-  pub id: i32,
-  pub creator_id: i32,
-  pub post_id: i32,
-  pub original_post_name: String,
-  pub original_post_url: Option<String>,
-  pub original_post_body: Option<String>,
-  pub reason: String,
-  pub resolved: bool,
-  pub resolver_id: Option<i32>,
-  pub published: chrono::NaiveDateTime,
-  pub updated: Option<chrono::NaiveDateTime>,
-}
-
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "post_report"]
-pub struct PostReportForm {
-  pub creator_id: i32,
-  pub post_id: i32,
-  pub original_post_name: String,
-  pub original_post_url: Option<String>,
-  pub original_post_body: Option<String>,
-  pub reason: String,
-}
-
-impl Reportable<PostReportForm> for PostReport {
-  /// creates a post report and returns it
-  ///
-  /// * `conn` - the postgres connection
-  /// * `post_report_form` - the filled CommentReportForm to insert
-  fn report(conn: &PgConnection, post_report_form: &PostReportForm) -> Result<Self, Error> {
-    use crate::schema::post_report::dsl::*;
-    insert_into(post_report)
-      .values(post_report_form)
-      .get_result::<Self>(conn)
-  }
-
-  /// resolve a post report
-  ///
-  /// * `conn` - the postgres connection
-  /// * `report_id` - the id of the report to resolve
-  /// * `by_resolver_id` - the id of the user resolving the report
-  fn resolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
-    use crate::schema::post_report::dsl::*;
-    update(post_report.find(report_id))
-      .set((
-        resolved.eq(true),
-        resolver_id.eq(by_resolver_id),
-        updated.eq(naive_now()),
-      ))
-      .execute(conn)
-  }
-
-  /// resolve a post report
-  ///
-  /// * `conn` - the postgres connection
-  /// * `report_id` - the id of the report to unresolve
-  /// * `by_resolver_id` - the id of the user unresolving the report
-  fn unresolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
-    use crate::schema::post_report::dsl::*;
-    update(post_report.find(report_id))
-      .set((
-        resolved.eq(false),
-        resolver_id.eq(by_resolver_id),
-        updated.eq(naive_now()),
-      ))
-      .execute(conn)
-  }
-}
-
-#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone)]
-#[table_name = "post_report_view"]
-pub struct PostReportView {
-  pub id: i32,
-  pub creator_id: i32,
-  pub post_id: i32,
-  pub original_post_name: String,
-  pub original_post_url: Option<String>,
-  pub original_post_body: Option<String>,
-  pub reason: String,
-  pub resolved: bool,
-  pub resolver_id: Option<i32>,
-  pub published: chrono::NaiveDateTime,
-  pub updated: Option<chrono::NaiveDateTime>,
-  pub current_post_name: String,
-  pub current_post_url: Option<String>,
-  pub current_post_body: Option<String>,
-  pub community_id: i32,
-  pub creator_actor_id: String,
-  pub creator_name: String,
-  pub creator_preferred_username: Option<String>,
-  pub creator_avatar: Option<String>,
-  pub creator_local: bool,
-  pub post_creator_id: i32,
-  pub post_creator_actor_id: String,
-  pub post_creator_name: String,
-  pub post_creator_preferred_username: Option<String>,
-  pub post_creator_avatar: Option<String>,
-  pub post_creator_local: bool,
-  pub resolver_actor_id: Option<String>,
-  pub resolver_name: Option<String>,
-  pub resolver_preferred_username: Option<String>,
-  pub resolver_avatar: Option<String>,
-  pub resolver_local: Option<bool>,
-}
-
-impl PostReportView {
-  /// returns the PostReportView for the provided report_id
-  ///
-  /// * `report_id` - the report id to obtain
-  pub fn read(conn: &PgConnection, report_id: i32) -> Result<Self, Error> {
-    use super::post_report::post_report_view::dsl::*;
-    post_report_view.find(report_id).first::<Self>(conn)
-  }
-
-  /// returns the current unresolved post report count for the supplied community ids
-  ///
-  /// * `community_ids` - a Vec<i32> of community_ids to get a count for
-  pub fn get_report_count(conn: &PgConnection, community_ids: &[i32]) -> Result<i64, Error> {
-    use super::post_report::post_report_view::dsl::*;
-    post_report_view
-      .filter(resolved.eq(false).and(community_id.eq_any(community_ids)))
-      .select(count(id))
-      .first::<i64>(conn)
-  }
-}
-
-pub struct PostReportQueryBuilder<'a> {
-  conn: &'a PgConnection,
-  query: post_report_view::BoxedQuery<'a, Pg>,
-  for_community_ids: Option<Vec<i32>>,
-  page: Option<i64>,
-  limit: Option<i64>,
-  resolved: Option<bool>,
-}
-
-impl<'a> PostReportQueryBuilder<'a> {
-  pub fn create(conn: &'a PgConnection) -> Self {
-    use super::post_report::post_report_view::dsl::*;
-
-    let query = post_report_view.into_boxed();
-
-    PostReportQueryBuilder {
-      conn,
-      query,
-      for_community_ids: None,
-      page: None,
-      limit: None,
-      resolved: Some(false),
-    }
-  }
-
-  pub fn community_ids<T: MaybeOptional<Vec<i32>>>(mut self, community_ids: T) -> Self {
-    self.for_community_ids = community_ids.get_optional();
-    self
-  }
-
-  pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
-    self.page = page.get_optional();
-    self
-  }
-
-  pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
-    self.limit = limit.get_optional();
-    self
-  }
-
-  pub fn resolved<T: MaybeOptional<bool>>(mut self, resolved: T) -> Self {
-    self.resolved = resolved.get_optional();
-    self
-  }
-
-  pub fn list(self) -> Result<Vec<PostReportView>, Error> {
-    use super::post_report::post_report_view::dsl::*;
-
-    let mut query = self.query;
-
-    if let Some(comm_ids) = self.for_community_ids {
-      query = query.filter(community_id.eq_any(comm_ids));
-    }
-
-    if let Some(resolved_flag) = self.resolved {
-      query = query.filter(resolved.eq(resolved_flag));
-    }
-
-    let (limit, offset) = limit_and_offset(self.page, self.limit);
-
-    query
-      .order_by(published.asc())
-      .limit(limit)
-      .offset(offset)
-      .load::<PostReportView>(self.conn)
-  }
-}
index cbfce876180faa4f45be4d67f7db44218830e17f..75883df577b7a408748a6599b05ecbb9d96763e7 100644 (file)
@@ -615,9 +615,45 @@ table! {
     }
 }
 
+table! {
+    user_alias_2 (id) {
+        id -> Int4,
+        name -> Varchar,
+        preferred_username -> Nullable<Varchar>,
+        password_encrypted -> Text,
+        email -> Nullable<Text>,
+        avatar -> Nullable<Text>,
+        admin -> Bool,
+        banned -> Bool,
+        published -> Timestamp,
+        updated -> Nullable<Timestamp>,
+        show_nsfw -> Bool,
+        theme -> Varchar,
+        default_sort_type -> Int2,
+        default_listing_type -> Int2,
+        lang -> Varchar,
+        show_avatars -> Bool,
+        send_notifications_to_email -> Bool,
+        matrix_user_id -> Nullable<Text>,
+        actor_id -> Varchar,
+        bio -> Nullable<Text>,
+        local -> Bool,
+        private_key -> Nullable<Text>,
+        public_key -> Nullable<Text>,
+        last_refreshed_at -> Timestamp,
+        banner -> Nullable<Text>,
+        deleted -> Bool,
+    }
+}
+
 joinable!(comment_alias_1 -> user_alias_1 (creator_id));
 joinable!(comment -> comment_alias_1 (parent_id));
 joinable!(user_mention -> user_alias_1 (recipient_id));
+joinable!(post -> user_alias_1 (creator_id));
+joinable!(comment -> user_alias_1 (creator_id));
+
+joinable!(post_report -> user_alias_2 (resolver_id));
+joinable!(comment_report -> user_alias_2 (resolver_id));
 
 joinable!(comment -> post (post_id));
 joinable!(comment -> user_ (creator_id));
@@ -708,4 +744,5 @@ allow_tables_to_appear_in_same_query!(
   user_mention,
   comment_alias_1,
   user_alias_1,
+  user_alias_2,
 );
diff --git a/lemmy_db/src/source/comment_report.rs b/lemmy_db/src/source/comment_report.rs
new file mode 100644 (file)
index 0000000..a537599
--- /dev/null
@@ -0,0 +1,73 @@
+use diesel::{dsl::*, result::Error, *};
+use serde::{Deserialize, Serialize};
+
+use crate::{naive_now, schema::comment_report, source::comment::Comment, Reportable};
+
+#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone)]
+#[belongs_to(Comment)]
+#[table_name = "comment_report"]
+pub struct CommentReport {
+  pub id: i32,
+  pub creator_id: i32,
+  pub comment_id: i32,
+  pub original_comment_text: String,
+  pub reason: String,
+  pub resolved: bool,
+  pub resolver_id: Option<i32>,
+  pub published: chrono::NaiveDateTime,
+  pub updated: Option<chrono::NaiveDateTime>,
+}
+
+#[derive(Insertable, AsChangeset, Clone)]
+#[table_name = "comment_report"]
+pub struct CommentReportForm {
+  pub creator_id: i32,
+  pub comment_id: i32,
+  pub original_comment_text: String,
+  pub reason: String,
+}
+
+impl Reportable<CommentReportForm> for CommentReport {
+  /// creates a comment report and returns it
+  ///
+  /// * `conn` - the postgres connection
+  /// * `comment_report_form` - the filled CommentReportForm to insert
+  fn report(conn: &PgConnection, comment_report_form: &CommentReportForm) -> Result<Self, Error> {
+    use crate::schema::comment_report::dsl::*;
+    insert_into(comment_report)
+      .values(comment_report_form)
+      .get_result::<Self>(conn)
+  }
+
+  /// resolve a comment report
+  ///
+  /// * `conn` - the postgres connection
+  /// * `report_id` - the id of the report to resolve
+  /// * `by_resolver_id` - the id of the user resolving the report
+  fn resolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
+    use crate::schema::comment_report::dsl::*;
+    update(comment_report.find(report_id))
+      .set((
+        resolved.eq(true),
+        resolver_id.eq(by_resolver_id),
+        updated.eq(naive_now()),
+      ))
+      .execute(conn)
+  }
+
+  /// unresolve a comment report
+  ///
+  /// * `conn` - the postgres connection
+  /// * `report_id` - the id of the report to unresolve
+  /// * `by_resolver_id` - the id of the user unresolving the report
+  fn unresolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
+    use crate::schema::comment_report::dsl::*;
+    update(comment_report.find(report_id))
+      .set((
+        resolved.eq(false),
+        resolver_id.eq(by_resolver_id),
+        updated.eq(naive_now()),
+      ))
+      .execute(conn)
+  }
+}
index 2247cd889dbc00a7bae1c09c9d73580f2cad98a7..211194a44ffa92e91eeaf2a4d2aeb9ad2db6295e 100644 (file)
@@ -1,10 +1,12 @@
 pub mod activity;
 pub mod category;
 pub mod comment;
+pub mod comment_report;
 pub mod community;
 pub mod moderator;
 pub mod password_reset_request;
 pub mod post;
+pub mod post_report;
 pub mod private_message;
 pub mod site;
 pub mod user;
diff --git a/lemmy_db/src/source/post_report.rs b/lemmy_db/src/source/post_report.rs
new file mode 100644 (file)
index 0000000..6de82a2
--- /dev/null
@@ -0,0 +1,77 @@
+use diesel::{dsl::*, result::Error, *};
+use serde::{Deserialize, Serialize};
+
+use crate::{naive_now, schema::post_report, source::post::Post, Reportable};
+
+#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone)]
+#[belongs_to(Post)]
+#[table_name = "post_report"]
+pub struct PostReport {
+  pub id: i32,
+  pub creator_id: i32,
+  pub post_id: i32,
+  pub original_post_name: String,
+  pub original_post_url: Option<String>,
+  pub original_post_body: Option<String>,
+  pub reason: String,
+  pub resolved: bool,
+  pub resolver_id: Option<i32>,
+  pub published: chrono::NaiveDateTime,
+  pub updated: Option<chrono::NaiveDateTime>,
+}
+
+#[derive(Insertable, AsChangeset, Clone)]
+#[table_name = "post_report"]
+pub struct PostReportForm {
+  pub creator_id: i32,
+  pub post_id: i32,
+  pub original_post_name: String,
+  pub original_post_url: Option<String>,
+  pub original_post_body: Option<String>,
+  pub reason: String,
+}
+
+impl Reportable<PostReportForm> for PostReport {
+  /// creates a post report and returns it
+  ///
+  /// * `conn` - the postgres connection
+  /// * `post_report_form` - the filled CommentReportForm to insert
+  fn report(conn: &PgConnection, post_report_form: &PostReportForm) -> Result<Self, Error> {
+    use crate::schema::post_report::dsl::*;
+    insert_into(post_report)
+      .values(post_report_form)
+      .get_result::<Self>(conn)
+  }
+
+  /// resolve a post report
+  ///
+  /// * `conn` - the postgres connection
+  /// * `report_id` - the id of the report to resolve
+  /// * `by_resolver_id` - the id of the user resolving the report
+  fn resolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
+    use crate::schema::post_report::dsl::*;
+    update(post_report.find(report_id))
+      .set((
+        resolved.eq(true),
+        resolver_id.eq(by_resolver_id),
+        updated.eq(naive_now()),
+      ))
+      .execute(conn)
+  }
+
+  /// resolve a post report
+  ///
+  /// * `conn` - the postgres connection
+  /// * `report_id` - the id of the report to unresolve
+  /// * `by_resolver_id` - the id of the user unresolving the report
+  fn unresolve(conn: &PgConnection, report_id: i32, by_resolver_id: i32) -> Result<usize, Error> {
+    use crate::schema::post_report::dsl::*;
+    update(post_report.find(report_id))
+      .set((
+        resolved.eq(false),
+        resolver_id.eq(by_resolver_id),
+        updated.eq(naive_now()),
+      ))
+      .execute(conn)
+  }
+}
index 0bd68a50924c57fa2b4e38465ebd75debabf1810..601e6e8c680f261f56a89d06329bf0bee9355417 100644 (file)
@@ -1,7 +1,7 @@
 use crate::{
   is_email_regex,
   naive_now,
-  schema::{user_, user_::dsl::*, user_alias_1},
+  schema::{user_, user_::dsl::*, user_alias_1, user_alias_2},
   ApubObject,
   Crud,
 };
@@ -153,7 +153,7 @@ pub struct UserSafeAlias1 {
   pub deleted: bool,
 }
 
-mod safe_type_alias {
+mod safe_type_alias_1 {
   use crate::{schema::user_alias_1::columns::*, source::user::UserAlias1, ToSafe};
   type Columns = (
     id,
@@ -195,6 +195,98 @@ mod safe_type_alias {
   }
 }
 
+#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
+#[table_name = "user_alias_2"]
+pub struct UserAlias2 {
+  pub id: i32,
+  pub name: String,
+  pub preferred_username: Option<String>,
+  pub password_encrypted: String,
+  pub email: Option<String>,
+  pub avatar: Option<String>,
+  pub admin: bool,
+  pub banned: bool,
+  pub published: chrono::NaiveDateTime,
+  pub updated: Option<chrono::NaiveDateTime>,
+  pub show_nsfw: bool,
+  pub theme: String,
+  pub default_sort_type: i16,
+  pub default_listing_type: i16,
+  pub lang: String,
+  pub show_avatars: bool,
+  pub send_notifications_to_email: bool,
+  pub matrix_user_id: Option<String>,
+  pub actor_id: String,
+  pub bio: Option<String>,
+  pub local: bool,
+  pub private_key: Option<String>,
+  pub public_key: Option<String>,
+  pub last_refreshed_at: chrono::NaiveDateTime,
+  pub banner: Option<String>,
+  pub deleted: bool,
+}
+
+#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
+#[table_name = "user_alias_2"]
+pub struct UserSafeAlias2 {
+  pub id: i32,
+  pub name: String,
+  pub preferred_username: Option<String>,
+  pub avatar: Option<String>,
+  pub admin: bool,
+  pub banned: bool,
+  pub published: chrono::NaiveDateTime,
+  pub updated: Option<chrono::NaiveDateTime>,
+  pub matrix_user_id: Option<String>,
+  pub actor_id: String,
+  pub bio: Option<String>,
+  pub local: bool,
+  pub banner: Option<String>,
+  pub deleted: bool,
+}
+
+mod safe_type_alias_2 {
+  use crate::{schema::user_alias_2::columns::*, source::user::UserAlias2, ToSafe};
+  type Columns = (
+    id,
+    name,
+    preferred_username,
+    avatar,
+    admin,
+    banned,
+    published,
+    updated,
+    matrix_user_id,
+    actor_id,
+    bio,
+    local,
+    banner,
+    deleted,
+  );
+
+  impl ToSafe for UserAlias2 {
+    type SafeColumns = Columns;
+    fn safe_columns_tuple() -> Self::SafeColumns {
+      (
+        id,
+        name,
+        preferred_username,
+        avatar,
+        admin,
+        banned,
+        published,
+        updated,
+        matrix_user_id,
+        actor_id,
+        bio,
+        local,
+        banner,
+        deleted,
+      )
+    }
+  }
+}
+
 #[derive(Insertable, AsChangeset, Clone)]
 #[table_name = "user_"]
 pub struct UserForm {
diff --git a/lemmy_db/src/views/comment_report_view.rs b/lemmy_db/src/views/comment_report_view.rs
new file mode 100644 (file)
index 0000000..540bb75
--- /dev/null
@@ -0,0 +1,193 @@
+use crate::{
+  limit_and_offset,
+  schema::{comment, comment_report, community, post, user_, user_alias_1, user_alias_2},
+  source::{
+    comment::Comment,
+    comment_report::CommentReport,
+    community::{Community, CommunitySafe},
+    post::Post,
+    user::{UserAlias1, UserAlias2, UserSafe, UserSafeAlias1, UserSafeAlias2, User_},
+  },
+  views::ViewToVec,
+  MaybeOptional,
+  ToSafe,
+};
+use diesel::{result::Error, *};
+use serde::Serialize;
+
+#[derive(Debug, PartialEq, Serialize, Clone)]
+pub struct CommentReportView {
+  pub comment_report: CommentReport,
+  pub comment: Comment,
+  pub post: Post,
+  pub community: CommunitySafe,
+  pub creator: UserSafe,
+  pub comment_creator: UserSafeAlias1,
+  pub resolver: Option<UserSafeAlias2>,
+}
+
+type CommentReportViewTuple = (
+  CommentReport,
+  Comment,
+  Post,
+  CommunitySafe,
+  UserSafe,
+  UserSafeAlias1,
+  Option<UserSafeAlias2>,
+);
+
+impl CommentReportView {
+  /// returns the CommentReportView for the provided report_id
+  ///
+  /// * `report_id` - the report id to obtain
+  pub fn read(conn: &PgConnection, report_id: i32) -> Result<Self, Error> {
+    let (comment_report, comment, post, community, creator, comment_creator, resolver) =
+      comment_report::table
+        .find(report_id)
+        .inner_join(comment::table)
+        .inner_join(post::table.on(comment::post_id.eq(post::id)))
+        .inner_join(community::table.on(post::community_id.eq(community::id)))
+        .inner_join(user_::table.on(comment_report::creator_id.eq(user_::id)))
+        .inner_join(user_alias_1::table.on(post::creator_id.eq(user_alias_1::id)))
+        .left_join(
+          user_alias_2::table.on(comment_report::resolver_id.eq(user_alias_2::id.nullable())),
+        )
+        .select((
+          comment_report::all_columns,
+          comment::all_columns,
+          post::all_columns,
+          Community::safe_columns_tuple(),
+          User_::safe_columns_tuple(),
+          UserAlias1::safe_columns_tuple(),
+          UserAlias2::safe_columns_tuple().nullable(),
+        ))
+        .first::<CommentReportViewTuple>(conn)?;
+
+    Ok(Self {
+      comment_report,
+      comment,
+      post,
+      community,
+      creator,
+      comment_creator,
+      resolver,
+    })
+  }
+
+  /// returns the current unresolved post report count for the supplied community ids
+  ///
+  /// * `community_ids` - a Vec<i32> of community_ids to get a count for
+  /// TODO this eq_any is a bad way to do this, would be better to join to communitymoderator
+  /// for a user id
+  pub fn get_report_count(conn: &PgConnection, community_ids: &[i32]) -> Result<i64, Error> {
+    use diesel::dsl::*;
+    comment_report::table
+      .inner_join(comment::table)
+      .inner_join(post::table.on(comment::post_id.eq(post::id)))
+      .filter(
+        comment_report::resolved
+          .eq(false)
+          .and(post::community_id.eq_any(community_ids)),
+      )
+      .select(count(comment_report::id))
+      .first::<i64>(conn)
+  }
+}
+
+pub struct CommentReportQueryBuilder<'a> {
+  conn: &'a PgConnection,
+  community_ids: Option<Vec<i32>>, // TODO bad way to do this
+  page: Option<i64>,
+  limit: Option<i64>,
+  resolved: Option<bool>,
+}
+
+impl<'a> CommentReportQueryBuilder<'a> {
+  pub fn create(conn: &'a PgConnection) -> Self {
+    CommentReportQueryBuilder {
+      conn,
+      community_ids: None,
+      page: None,
+      limit: None,
+      resolved: Some(false),
+    }
+  }
+
+  pub fn community_ids<T: MaybeOptional<Vec<i32>>>(mut self, community_ids: T) -> Self {
+    self.community_ids = community_ids.get_optional();
+    self
+  }
+
+  pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
+    self.page = page.get_optional();
+    self
+  }
+
+  pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
+    self.limit = limit.get_optional();
+    self
+  }
+
+  pub fn resolved<T: MaybeOptional<bool>>(mut self, resolved: T) -> Self {
+    self.resolved = resolved.get_optional();
+    self
+  }
+
+  pub fn list(self) -> Result<Vec<CommentReportView>, Error> {
+    let mut query = comment_report::table
+      .inner_join(comment::table)
+      .inner_join(post::table.on(comment::post_id.eq(post::id)))
+      .inner_join(community::table.on(post::community_id.eq(community::id)))
+      .inner_join(user_::table.on(comment_report::creator_id.eq(user_::id)))
+      .inner_join(user_alias_1::table.on(post::creator_id.eq(user_alias_1::id)))
+      .left_join(
+        user_alias_2::table.on(comment_report::resolver_id.eq(user_alias_2::id.nullable())),
+      )
+      .select((
+        comment_report::all_columns,
+        comment::all_columns,
+        post::all_columns,
+        Community::safe_columns_tuple(),
+        User_::safe_columns_tuple(),
+        UserAlias1::safe_columns_tuple(),
+        UserAlias2::safe_columns_tuple().nullable(),
+      ))
+      .into_boxed();
+
+    if let Some(comm_ids) = self.community_ids {
+      query = query.filter(post::community_id.eq_any(comm_ids));
+    }
+
+    if let Some(resolved_flag) = self.resolved {
+      query = query.filter(comment_report::resolved.eq(resolved_flag));
+    }
+
+    let (limit, offset) = limit_and_offset(self.page, self.limit);
+
+    let res = query
+      .order_by(comment_report::published.asc())
+      .limit(limit)
+      .offset(offset)
+      .load::<CommentReportViewTuple>(self.conn)?;
+
+    Ok(CommentReportView::to_vec(res))
+  }
+}
+
+impl ViewToVec for CommentReportView {
+  type DbTuple = CommentReportViewTuple;
+  fn to_vec(posts: Vec<Self::DbTuple>) -> Vec<Self> {
+    posts
+      .iter()
+      .map(|a| Self {
+        comment_report: a.0.to_owned(),
+        comment: a.1.to_owned(),
+        post: a.2.to_owned(),
+        community: a.3.to_owned(),
+        creator: a.4.to_owned(),
+        comment_creator: a.5.to_owned(),
+        resolver: a.6.to_owned(),
+      })
+      .collect::<Vec<Self>>()
+  }
+}
index ee9a82f5b44fb46c5ec16c8181e30eed3ce94caa..3cac0bd3d8f250e827b74c3838ffad9b082a5f3b 100644 (file)
@@ -1,6 +1,8 @@
+pub mod comment_report_view;
 pub mod comment_view;
 pub mod community;
 pub mod moderator;
+pub mod post_report_view;
 pub mod post_view;
 pub mod private_message_view;
 pub mod site_view;
diff --git a/lemmy_db/src/views/post_report_view.rs b/lemmy_db/src/views/post_report_view.rs
new file mode 100644 (file)
index 0000000..d39adfd
--- /dev/null
@@ -0,0 +1,178 @@
+use crate::{
+  limit_and_offset,
+  schema::{community, post, post_report, user_, user_alias_1, user_alias_2},
+  source::{
+    community::{Community, CommunitySafe},
+    post::Post,
+    post_report::PostReport,
+    user::{UserAlias1, UserAlias2, UserSafe, UserSafeAlias1, UserSafeAlias2, User_},
+  },
+  views::ViewToVec,
+  MaybeOptional,
+  ToSafe,
+};
+use diesel::{result::Error, *};
+use serde::Serialize;
+
+#[derive(Debug, PartialEq, Serialize, Clone)]
+pub struct PostReportView {
+  pub post_report: PostReport,
+  pub post: Post,
+  pub community: CommunitySafe,
+  pub creator: UserSafe,
+  pub post_creator: UserSafeAlias1,
+  pub resolver: Option<UserSafeAlias2>,
+}
+
+type PostReportViewTuple = (
+  PostReport,
+  Post,
+  CommunitySafe,
+  UserSafe,
+  UserSafeAlias1,
+  Option<UserSafeAlias2>,
+);
+
+impl PostReportView {
+  /// returns the PostReportView for the provided report_id
+  ///
+  /// * `report_id` - the report id to obtain
+  pub fn read(conn: &PgConnection, report_id: i32) -> Result<Self, Error> {
+    let (post_report, post, community, creator, post_creator, resolver) = post_report::table
+      .find(report_id)
+      .inner_join(post::table)
+      .inner_join(community::table.on(post::community_id.eq(community::id)))
+      .inner_join(user_::table.on(post_report::creator_id.eq(user_::id)))
+      .inner_join(user_alias_1::table.on(post::creator_id.eq(user_alias_1::id)))
+      .left_join(user_alias_2::table.on(post_report::resolver_id.eq(user_alias_2::id.nullable())))
+      .select((
+        post_report::all_columns,
+        post::all_columns,
+        Community::safe_columns_tuple(),
+        User_::safe_columns_tuple(),
+        UserAlias1::safe_columns_tuple(),
+        UserAlias2::safe_columns_tuple().nullable(),
+      ))
+      .first::<PostReportViewTuple>(conn)?;
+
+    Ok(Self {
+      post_report,
+      post,
+      community,
+      creator,
+      post_creator,
+      resolver,
+    })
+  }
+
+  /// returns the current unresolved post report count for the supplied community ids
+  ///
+  /// * `community_ids` - a Vec<i32> of community_ids to get a count for
+  /// TODO this eq_any is a bad way to do this, would be better to join to communitymoderator
+  /// for a user id
+  pub fn get_report_count(conn: &PgConnection, community_ids: &[i32]) -> Result<i64, Error> {
+    use diesel::dsl::*;
+    post_report::table
+      .inner_join(post::table)
+      .filter(
+        post_report::resolved
+          .eq(false)
+          .and(post::community_id.eq_any(community_ids)),
+      )
+      .select(count(post_report::id))
+      .first::<i64>(conn)
+  }
+}
+
+pub struct PostReportQueryBuilder<'a> {
+  conn: &'a PgConnection,
+  community_ids: Option<Vec<i32>>, // TODO bad way to do this
+  page: Option<i64>,
+  limit: Option<i64>,
+  resolved: Option<bool>,
+}
+
+impl<'a> PostReportQueryBuilder<'a> {
+  pub fn create(conn: &'a PgConnection) -> Self {
+    PostReportQueryBuilder {
+      conn,
+      community_ids: None,
+      page: None,
+      limit: None,
+      resolved: Some(false),
+    }
+  }
+
+  pub fn community_ids<T: MaybeOptional<Vec<i32>>>(mut self, community_ids: T) -> Self {
+    self.community_ids = community_ids.get_optional();
+    self
+  }
+
+  pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
+    self.page = page.get_optional();
+    self
+  }
+
+  pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
+    self.limit = limit.get_optional();
+    self
+  }
+
+  pub fn resolved<T: MaybeOptional<bool>>(mut self, resolved: T) -> Self {
+    self.resolved = resolved.get_optional();
+    self
+  }
+
+  pub fn list(self) -> Result<Vec<PostReportView>, Error> {
+    let mut query = post_report::table
+      .inner_join(post::table)
+      .inner_join(community::table.on(post::community_id.eq(community::id)))
+      .inner_join(user_::table.on(post_report::creator_id.eq(user_::id)))
+      .inner_join(user_alias_1::table.on(post::creator_id.eq(user_alias_1::id)))
+      .left_join(user_alias_2::table.on(post_report::resolver_id.eq(user_alias_2::id.nullable())))
+      .select((
+        post_report::all_columns,
+        post::all_columns,
+        Community::safe_columns_tuple(),
+        User_::safe_columns_tuple(),
+        UserAlias1::safe_columns_tuple(),
+        UserAlias2::safe_columns_tuple().nullable(),
+      ))
+      .into_boxed();
+
+    if let Some(comm_ids) = self.community_ids {
+      query = query.filter(post::community_id.eq_any(comm_ids));
+    }
+
+    if let Some(resolved_flag) = self.resolved {
+      query = query.filter(post_report::resolved.eq(resolved_flag));
+    }
+
+    let (limit, offset) = limit_and_offset(self.page, self.limit);
+
+    let res = query
+      .order_by(post_report::published.asc())
+      .limit(limit)
+      .offset(offset)
+      .load::<PostReportViewTuple>(self.conn)?;
+
+    Ok(PostReportView::to_vec(res))
+  }
+}
+
+impl ViewToVec for PostReportView {
+  type DbTuple = PostReportViewTuple;
+  fn to_vec(posts: Vec<Self::DbTuple>) -> Vec<Self> {
+    posts
+      .iter()
+      .map(|a| Self {
+        post_report: a.0.to_owned(),
+        post: a.1.to_owned(),
+        community: a.2.to_owned(),
+        creator: a.3.to_owned(),
+        post_creator: a.4.to_owned(),
+        resolver: a.5.to_owned(),
+      })
+      .collect::<Vec<Self>>()
+  }
+}
index 277499f49747c2bab900e991e898a7367e2b0525..be10906aa0e28854d6fa42ae15068656ff82c74b 100644 (file)
@@ -1,4 +1,4 @@
-use lemmy_db::{comment_report::CommentReportView, views::comment_view::CommentView};
+use lemmy_db::views::{comment_report_view::CommentReportView, comment_view::CommentView};
 use serde::{Deserialize, Serialize};
 
 #[derive(Deserialize)]
@@ -111,7 +111,7 @@ pub struct ListCommentReports {
   pub auth: String,
 }
 
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Clone, Debug)]
 pub struct ListCommentReportsResponse {
   pub comments: Vec<CommentReportView>,
 }
index bf0af2f8afaf6c3e45563a046c48ca376bcd1f5a..fe6a059e2ecf3fac070686041738f80b5c2782b1 100644 (file)
@@ -1,10 +1,8 @@
-use lemmy_db::{
-  post_report::PostReportView,
-  views::{
-    comment_view::CommentView,
-    community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
-    post_view::PostView,
-  },
+use lemmy_db::views::{
+  comment_view::CommentView,
+  community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
+  post_report_view::PostReportView,
+  post_view::PostView,
 };
 use serde::{Deserialize, Serialize};
 
@@ -150,7 +148,7 @@ pub struct ListPostReports {
   pub auth: String,
 }
 
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Clone, Debug)]
 pub struct ListPostReportsResponse {
   pub posts: Vec<PostReportView>,
 }