-
-
Notifications
You must be signed in to change notification settings - Fork 888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add community reports (only the database part) #4996
base: main
Are you sure you want to change the base?
Changes from 10 commits
e8344a1
cdc0be9
d778803
5660cb0
7df73eb
dc0d8d0
3529e2b
a05998c
0cc3657
d1f3d73
be4f8fa
8a578f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
use crate::{ | ||
newtypes::{CommunityId, CommunityReportId, PersonId}, | ||
schema::community_report::{ | ||
community_id, | ||
dsl::{community_report, resolved, resolver_id, updated}, | ||
}, | ||
source::community_report::{CommunityReport, CommunityReportForm}, | ||
traits::Reportable, | ||
utils::{get_conn, DbPool}, | ||
}; | ||
use chrono::Utc; | ||
use diesel::{ | ||
dsl::{insert_into, update}, | ||
result::Error, | ||
ExpressionMethods, | ||
QueryDsl, | ||
}; | ||
use diesel_async::RunQueryDsl; | ||
|
||
#[async_trait] | ||
impl Reportable for CommunityReport { | ||
type Form = CommunityReportForm; | ||
type IdType = CommunityReportId; | ||
type ObjectIdType = CommunityId; | ||
/// creates a community report and returns it | ||
/// | ||
/// * `conn` - the postgres connection | ||
/// * `community_report_form` - the filled CommunityReportForm to insert | ||
async fn report( | ||
pool: &mut DbPool<'_>, | ||
community_report_form: &CommunityReportForm, | ||
) -> Result<Self, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
insert_into(community_report) | ||
.values(community_report_form) | ||
.get_result::<Self>(conn) | ||
.await | ||
} | ||
|
||
/// resolve a community 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 | ||
async fn resolve( | ||
pool: &mut DbPool<'_>, | ||
report_id_: Self::IdType, | ||
by_resolver_id: PersonId, | ||
) -> Result<usize, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
update(community_report.find(report_id_)) | ||
.set(( | ||
resolved.eq(true), | ||
resolver_id.eq(by_resolver_id), | ||
updated.eq(Utc::now()), | ||
)) | ||
.execute(conn) | ||
.await | ||
} | ||
|
||
async fn resolve_all_for_object( | ||
pool: &mut DbPool<'_>, | ||
community_id_: CommunityId, | ||
by_resolver_id: PersonId, | ||
) -> Result<usize, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
update(community_report.filter(community_id.eq(community_id_))) | ||
.set(( | ||
resolved.eq(true), | ||
resolver_id.eq(by_resolver_id), | ||
updated.eq(Utc::now()), | ||
)) | ||
.execute(conn) | ||
.await | ||
} | ||
|
||
/// unresolve a community 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 | ||
async fn unresolve( | ||
pool: &mut DbPool<'_>, | ||
report_id_: Self::IdType, | ||
by_resolver_id: PersonId, | ||
) -> Result<usize, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
update(community_report.find(report_id_)) | ||
.set(( | ||
resolved.eq(false), | ||
resolver_id.eq(by_resolver_id), | ||
updated.eq(Utc::now()), | ||
)) | ||
.execute(conn) | ||
.await | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use crate::newtypes::{CommunityId, CommunityReportId, DbUrl, PersonId}; | ||
#[cfg(feature = "full")] | ||
use crate::schema::community_report; | ||
use chrono::{DateTime, Utc}; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_with::skip_serializing_none; | ||
#[cfg(feature = "full")] | ||
use ts_rs::TS; | ||
|
||
#[skip_serializing_none] | ||
#[derive(PartialEq, Eq, Serialize, Deserialize, Debug, Clone)] | ||
#[cfg_attr( | ||
feature = "full", | ||
derive(Queryable, Selectable, Associations, Identifiable, TS) | ||
)] | ||
#[cfg_attr( | ||
feature = "full", | ||
diesel(belongs_to(crate::source::community::Community)) | ||
)] | ||
#[cfg_attr(feature = "full", diesel(table_name = community_report))] | ||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] | ||
#[cfg_attr(feature = "full", ts(export))] | ||
/// A comment report. | ||
pub struct CommunityReport { | ||
pub id: CommunityReportId, | ||
pub creator_id: PersonId, | ||
pub community_id: CommunityId, | ||
pub original_community_name: String, | ||
pub original_community_title: String, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub original_community_description: Option<String>, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub original_community_sidebar: Option<String>, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub original_community_icon: Option<String>, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub original_community_banner: Option<String>, | ||
pub reason: String, | ||
pub resolved: bool, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub resolver_id: Option<PersonId>, | ||
pub published: DateTime<Utc>, | ||
#[cfg_attr(feature = "full", ts(optional))] | ||
pub updated: Option<DateTime<Utc>>, | ||
} | ||
|
||
#[derive(Clone)] | ||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] | ||
#[cfg_attr(feature = "full", diesel(table_name = community_report))] | ||
pub struct CommunityReportForm { | ||
pub creator_id: PersonId, | ||
pub community_id: CommunityId, | ||
pub original_community_name: String, | ||
pub original_community_title: String, | ||
pub original_community_description: Option<String>, | ||
pub original_community_sidebar: Option<String>, | ||
pub original_community_icon: Option<DbUrl>, | ||
pub original_community_banner: Option<DbUrl>, | ||
pub reason: String, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use crate::structs::CommunityReportView; | ||
use diesel::{result::Error, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl}; | ||
use diesel_async::RunQueryDsl; | ||
use lemmy_db_schema::{ | ||
aliases::{self}, | ||
newtypes::{CommunityReportId, PersonId}, | ||
schema::{community, community_actions, community_aggregates, community_report, person}, | ||
source::community::CommunityFollower, | ||
utils::{actions, get_conn, DbPool}, | ||
}; | ||
|
||
impl CommunityReportView { | ||
/// returns the CommunityReportView for the provided report_id | ||
/// | ||
/// * `report_id` - the report id to obtain | ||
pub async fn read( | ||
pool: &mut DbPool<'_>, | ||
report_id: CommunityReportId, | ||
my_person_id: PersonId, | ||
) -> Result<Self, Error> { | ||
let conn = &mut get_conn(pool).await?; | ||
|
||
community_report::table | ||
.find(report_id) | ||
.inner_join(community::table.inner_join(community_aggregates::table)) | ||
.left_join(actions( | ||
community_actions::table, | ||
Some(my_person_id), | ||
community_report::community_id, | ||
)) | ||
.inner_join( | ||
aliases::person1.on(community_report::creator_id.eq(aliases::person1.field(person::id))), | ||
) | ||
.left_join( | ||
aliases::person2 | ||
.on(community_report::resolver_id.eq(aliases::person2.field(person::id).nullable())), | ||
) | ||
.select(( | ||
community_report::all_columns, | ||
community::all_columns, | ||
aliases::person1.fields(person::all_columns), | ||
community_aggregates::all_columns, | ||
CommunityFollower::select_subscribed_type(), | ||
aliases::person2.fields(person::all_columns.nullable()), | ||
)) | ||
.first(conn) | ||
.await | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be removed, as now we have the EDIT: Oh I see below you did add it. In that case just remove this file, since everything is done through the combined reports endpoint now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if the icon and banner are totally necessary, but no reason not to have them I spose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, reports store the original content so the creator of the reported thing can't edit it to remove evidence of the offense. It's possible that a community's icon or banner is the reason for reporting, just like the url of a post.