Adding report views.
This commit is contained in:
parent
1cf520254d
commit
05c3e471ae
16 changed files with 684 additions and 505 deletions
|
@ -10,9 +10,15 @@ use crate::{
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use lemmy_apub::{ApubLikeableType, ApubObjectType};
|
use lemmy_apub::{ApubLikeableType, ApubObjectType};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment_report::*,
|
source::{
|
||||||
source::{comment::*, moderator::*, post::*, user::*},
|
comment::*,
|
||||||
|
comment_report::{CommentReport, CommentReportForm},
|
||||||
|
moderator::*,
|
||||||
|
post::*,
|
||||||
|
user::*,
|
||||||
|
},
|
||||||
views::{
|
views::{
|
||||||
|
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
|
||||||
comment_view::{CommentQueryBuilder, CommentView},
|
comment_view::{CommentQueryBuilder, CommentView},
|
||||||
site_view::SiteView,
|
site_view::SiteView,
|
||||||
},
|
},
|
||||||
|
@ -776,7 +782,7 @@ impl Perform for ResolveCommentReport {
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let user_id = user.id;
|
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 resolved = data.resolved;
|
||||||
let resolve_fun = move |conn: &'_ _| {
|
let resolve_fun = move |conn: &'_ _| {
|
||||||
|
@ -800,7 +806,7 @@ impl Perform for ResolveCommentReport {
|
||||||
context.chat_server().do_send(SendModRoomMessage {
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
op: UserOperation::ResolveCommentReport,
|
op: UserOperation::ResolveCommentReport,
|
||||||
response: res.clone(),
|
response: res.clone(),
|
||||||
community_id: report.community_id,
|
community_id: report.community.id,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,15 @@ use actix_web::web::Data;
|
||||||
use lemmy_apub::{ApubLikeableType, ApubObjectType};
|
use lemmy_apub::{ApubLikeableType, ApubObjectType};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
naive_now,
|
naive_now,
|
||||||
post_report::*,
|
source::{
|
||||||
source::{moderator::*, post::*},
|
moderator::*,
|
||||||
|
post::*,
|
||||||
|
post_report::{PostReport, PostReportForm},
|
||||||
|
},
|
||||||
views::{
|
views::{
|
||||||
comment_view::CommentQueryBuilder,
|
comment_view::CommentQueryBuilder,
|
||||||
community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
|
community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
|
||||||
|
post_report_view::{PostReportQueryBuilder, PostReportView},
|
||||||
post_view::{PostQueryBuilder, PostView},
|
post_view::{PostQueryBuilder, PostView},
|
||||||
site_view::SiteView,
|
site_view::SiteView,
|
||||||
},
|
},
|
||||||
|
@ -835,7 +839,7 @@ impl Perform for ResolvePostReport {
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let user_id = user.id;
|
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 resolved = data.resolved;
|
||||||
let resolve_fun = move |conn: &'_ _| {
|
let resolve_fun = move |conn: &'_ _| {
|
||||||
|
@ -858,7 +862,7 @@ impl Perform for ResolvePostReport {
|
||||||
context.chat_server().do_send(SendModRoomMessage {
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
op: UserOperation::ResolvePostReport,
|
op: UserOperation::ResolvePostReport,
|
||||||
response: res.clone(),
|
response: res.clone(),
|
||||||
community_id: report.community_id,
|
community_id: report.community.id,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,8 @@ use captcha::{gen, Difficulty};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use lemmy_apub::ApubObjectType;
|
use lemmy_apub::ApubObjectType;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment_report::CommentReportView,
|
|
||||||
diesel_option_overwrite,
|
diesel_option_overwrite,
|
||||||
naive_now,
|
naive_now,
|
||||||
post_report::PostReportView,
|
|
||||||
source::{
|
source::{
|
||||||
comment::*,
|
comment::*,
|
||||||
community::*,
|
community::*,
|
||||||
|
@ -31,11 +29,13 @@ use lemmy_db::{
|
||||||
user_mention::*,
|
user_mention::*,
|
||||||
},
|
},
|
||||||
views::{
|
views::{
|
||||||
|
comment_report_view::CommentReportView,
|
||||||
comment_view::CommentQueryBuilder,
|
comment_view::CommentQueryBuilder,
|
||||||
community::{
|
community::{
|
||||||
community_follower_view::CommunityFollowerView,
|
community_follower_view::CommunityFollowerView,
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
},
|
},
|
||||||
|
post_report_view::PostReportView,
|
||||||
post_view::PostQueryBuilder,
|
post_view::PostQueryBuilder,
|
||||||
private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView},
|
private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView},
|
||||||
site_view::SiteView,
|
site_view::SiteView,
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,9 +11,6 @@ use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{env, env::VarError};
|
use std::{env, env::VarError};
|
||||||
|
|
||||||
pub mod comment_report;
|
|
||||||
pub mod post_report;
|
|
||||||
|
|
||||||
pub mod aggregates;
|
pub mod aggregates;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod source;
|
pub mod source;
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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_alias_1 -> user_alias_1 (creator_id));
|
||||||
joinable!(comment -> comment_alias_1 (parent_id));
|
joinable!(comment -> comment_alias_1 (parent_id));
|
||||||
joinable!(user_mention -> user_alias_1 (recipient_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 -> post (post_id));
|
||||||
joinable!(comment -> user_ (creator_id));
|
joinable!(comment -> user_ (creator_id));
|
||||||
|
@ -708,4 +744,5 @@ allow_tables_to_appear_in_same_query!(
|
||||||
user_mention,
|
user_mention,
|
||||||
comment_alias_1,
|
comment_alias_1,
|
||||||
user_alias_1,
|
user_alias_1,
|
||||||
|
user_alias_2,
|
||||||
);
|
);
|
||||||
|
|
73
lemmy_db/src/source/comment_report.rs
Normal file
73
lemmy_db/src/source/comment_report.rs
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
pub mod activity;
|
pub mod activity;
|
||||||
pub mod category;
|
pub mod category;
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
|
pub mod comment_report;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
pub mod moderator;
|
pub mod moderator;
|
||||||
pub mod password_reset_request;
|
pub mod password_reset_request;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
|
pub mod post_report;
|
||||||
pub mod private_message;
|
pub mod private_message;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
77
lemmy_db/src/source/post_report.rs
Normal file
77
lemmy_db/src/source/post_report.rs
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
is_email_regex,
|
is_email_regex,
|
||||||
naive_now,
|
naive_now,
|
||||||
schema::{user_, user_::dsl::*, user_alias_1},
|
schema::{user_, user_::dsl::*, user_alias_1, user_alias_2},
|
||||||
ApubObject,
|
ApubObject,
|
||||||
Crud,
|
Crud,
|
||||||
};
|
};
|
||||||
|
@ -153,7 +153,7 @@ pub struct UserSafeAlias1 {
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod safe_type_alias {
|
mod safe_type_alias_1 {
|
||||||
use crate::{schema::user_alias_1::columns::*, source::user::UserAlias1, ToSafe};
|
use crate::{schema::user_alias_1::columns::*, source::user::UserAlias1, ToSafe};
|
||||||
type Columns = (
|
type Columns = (
|
||||||
id,
|
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)]
|
#[derive(Insertable, AsChangeset, Clone)]
|
||||||
#[table_name = "user_"]
|
#[table_name = "user_"]
|
||||||
pub struct UserForm {
|
pub struct UserForm {
|
||||||
|
|
193
lemmy_db/src/views/comment_report_view.rs
Normal file
193
lemmy_db/src/views/comment_report_view.rs
Normal file
|
@ -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>>()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
|
pub mod comment_report_view;
|
||||||
pub mod comment_view;
|
pub mod comment_view;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
pub mod moderator;
|
pub mod moderator;
|
||||||
|
pub mod post_report_view;
|
||||||
pub mod post_view;
|
pub mod post_view;
|
||||||
pub mod private_message_view;
|
pub mod private_message_view;
|
||||||
pub mod site_view;
|
pub mod site_view;
|
||||||
|
|
178
lemmy_db/src/views/post_report_view.rs
Normal file
178
lemmy_db/src/views/post_report_view.rs
Normal file
|
@ -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>>()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -111,7 +111,7 @@ pub struct ListCommentReports {
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Clone, Debug)]
|
||||||
pub struct ListCommentReportsResponse {
|
pub struct ListCommentReportsResponse {
|
||||||
pub comments: Vec<CommentReportView>,
|
pub comments: Vec<CommentReportView>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use lemmy_db::{
|
use lemmy_db::views::{
|
||||||
post_report::PostReportView,
|
|
||||||
views::{
|
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
|
community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
|
||||||
|
post_report_view::PostReportView,
|
||||||
post_view::PostView,
|
post_view::PostView,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -150,7 +148,7 @@ pub struct ListPostReports {
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Clone, Debug)]
|
||||||
pub struct ListPostReportsResponse {
|
pub struct ListPostReportsResponse {
|
||||||
pub posts: Vec<PostReportView>,
|
pub posts: Vec<PostReportView>,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue