mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-09-02 19:23:49 +00:00
Adding ban_expires_at
to views (#5924)
* Refactoring queries. * Adding ban_expires_at for views. * Adding unit tests for expires_at * Added ban_expires_at for local_user_view * Fixing millis -> micros * Renaming creator_community_ban field.
This commit is contained in:
parent
b7a9eb05da
commit
98995b4ebf
43 changed files with 981 additions and 573 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -3407,6 +3407,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_comment"
|
name = "lemmy_db_views_comment"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"diesel_ltree",
|
"diesel_ltree",
|
||||||
|
@ -3523,6 +3524,7 @@ name = "lemmy_db_views_local_user"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"i-love-jesus",
|
"i-love-jesus",
|
||||||
|
@ -3559,6 +3561,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_notification"
|
name = "lemmy_db_views_notification"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"i-love-jesus",
|
"i-love-jesus",
|
||||||
|
@ -3577,6 +3580,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_person"
|
name = "lemmy_db_views_person"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"i-love-jesus",
|
"i-love-jesus",
|
||||||
|
@ -3596,6 +3600,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_person_content_combined"
|
name = "lemmy_db_views_person_content_combined"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"derive-new",
|
"derive-new",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
|
@ -3618,6 +3623,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_person_liked_combined"
|
name = "lemmy_db_views_person_liked_combined"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"i-love-jesus",
|
"i-love-jesus",
|
||||||
|
@ -3639,6 +3645,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_person_saved_combined"
|
name = "lemmy_db_views_person_saved_combined"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"i-love-jesus",
|
"i-love-jesus",
|
||||||
|
@ -3749,6 +3756,7 @@ dependencies = [
|
||||||
name = "lemmy_db_views_search_combined"
|
name = "lemmy_db_views_search_combined"
|
||||||
version = "1.0.0-alpha.7"
|
version = "1.0.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"i-love-jesus",
|
"i-love-jesus",
|
||||||
|
|
|
@ -167,6 +167,7 @@ pub async fn register(
|
||||||
person,
|
person,
|
||||||
local_user,
|
local_user,
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.scope_boxed()
|
.scope_boxed()
|
||||||
|
@ -410,6 +411,7 @@ pub async fn authenticate_with_oauth(
|
||||||
person,
|
person,
|
||||||
local_user,
|
local_user,
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.scope_boxed()
|
.scope_boxed()
|
||||||
|
|
|
@ -510,6 +510,8 @@ pub mod functions {
|
||||||
}
|
}
|
||||||
|
|
||||||
define_sql_function!(#[sql_name = "coalesce"] fn coalesce_2_nullable<T: diesel::sql_types::SqlType + diesel::sql_types::SingleValue>(x: diesel::sql_types::Nullable<T>, y: diesel::sql_types::Nullable<T>) -> diesel::sql_types::Nullable<T>);
|
define_sql_function!(#[sql_name = "coalesce"] fn coalesce_2_nullable<T: diesel::sql_types::SqlType + diesel::sql_types::SingleValue>(x: diesel::sql_types::Nullable<T>, y: diesel::sql_types::Nullable<T>) -> diesel::sql_types::Nullable<T>);
|
||||||
|
|
||||||
|
define_sql_function!(#[sql_name = "coalesce"] fn coalesce_3_nullable<T: diesel::sql_types::SqlType + diesel::sql_types::SingleValue>(x: diesel::sql_types::Nullable<T>, y: diesel::sql_types::Nullable<T>, z: diesel::sql_types::Nullable<T>) -> diesel::sql_types::Nullable<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DELETED_REPLACEMENT_TEXT: &str = "*Permanently Deleted*";
|
pub const DELETED_REPLACEMENT_TEXT: &str = "*Permanently Deleted*";
|
||||||
|
|
|
@ -1,460 +0,0 @@
|
||||||
use crate::{
|
|
||||||
aliases::{
|
|
||||||
creator_community_actions,
|
|
||||||
creator_community_instance_actions,
|
|
||||||
creator_home_instance_actions,
|
|
||||||
creator_local_instance_actions,
|
|
||||||
creator_local_user,
|
|
||||||
my_instance_persons_actions,
|
|
||||||
person1,
|
|
||||||
person2,
|
|
||||||
},
|
|
||||||
newtypes::{InstanceId, PersonId},
|
|
||||||
MyInstancePersonsActionsAllColumnsTuple,
|
|
||||||
Person1AliasAllColumnsTuple,
|
|
||||||
Person2AliasAllColumnsTuple,
|
|
||||||
};
|
|
||||||
use diesel::{
|
|
||||||
dsl::{case_when, exists, not},
|
|
||||||
expression::SqlLiteral,
|
|
||||||
helper_types::{Eq, NotEq, Nullable},
|
|
||||||
sql_types::Json,
|
|
||||||
BoolExpressionMethods,
|
|
||||||
ExpressionMethods,
|
|
||||||
JoinOnDsl,
|
|
||||||
NullableExpressionMethods,
|
|
||||||
PgExpressionMethods,
|
|
||||||
QueryDsl,
|
|
||||||
};
|
|
||||||
use lemmy_db_schema_file::{
|
|
||||||
enums::{CommunityFollowerState, CommunityVisibility},
|
|
||||||
schema::{
|
|
||||||
comment,
|
|
||||||
comment_actions,
|
|
||||||
community,
|
|
||||||
community_actions,
|
|
||||||
image_details,
|
|
||||||
instance_actions,
|
|
||||||
local_site,
|
|
||||||
local_user,
|
|
||||||
multi_community,
|
|
||||||
multi_community_entry,
|
|
||||||
person,
|
|
||||||
person_actions,
|
|
||||||
post,
|
|
||||||
post_actions,
|
|
||||||
post_tag,
|
|
||||||
tag,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Hide all content from blocked communities and persons. Content from blocked instances is also
|
|
||||||
/// hidden, unless the user followed the community explicitly.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn filter_blocked() -> _ {
|
|
||||||
instance_actions::blocked_communities_at
|
|
||||||
.is_null()
|
|
||||||
.or(community_actions::followed_at.is_not_null())
|
|
||||||
.and(community_actions::blocked_at.is_null())
|
|
||||||
.and(person_actions::blocked_at.is_null())
|
|
||||||
.and(
|
|
||||||
my_instance_persons_actions
|
|
||||||
.field(instance_actions::blocked_persons_at)
|
|
||||||
.is_null(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks that the creator_local_user is an admin.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_is_admin() -> _ {
|
|
||||||
creator_local_user
|
|
||||||
.field(local_user::admin)
|
|
||||||
.nullable()
|
|
||||||
.is_not_distinct_from(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks that the local_user is an admin.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn local_user_is_admin() -> _ {
|
|
||||||
local_user::admin.nullable().is_not_distinct_from(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks to see if the comment creator is an admin.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn comment_creator_is_admin() -> _ {
|
|
||||||
exists(
|
|
||||||
creator_local_user.filter(
|
|
||||||
comment::creator_id
|
|
||||||
.eq(creator_local_user.field(local_user::person_id))
|
|
||||||
.and(creator_local_user.field(local_user::admin).eq(true)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn post_creator_is_admin() -> _ {
|
|
||||||
exists(
|
|
||||||
creator_local_user.filter(
|
|
||||||
post::creator_id
|
|
||||||
.eq(creator_local_user.field(local_user::person_id))
|
|
||||||
.and(creator_local_user.field(local_user::admin).eq(true)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_is_moderator() -> _ {
|
|
||||||
creator_community_actions
|
|
||||||
.field(community_actions::became_moderator_at)
|
|
||||||
.nullable()
|
|
||||||
.is_not_null()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_banned_from_community() -> _ {
|
|
||||||
creator_community_actions
|
|
||||||
.field(community_actions::received_ban_at)
|
|
||||||
.nullable()
|
|
||||||
.is_not_null()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_home_banned() -> _ {
|
|
||||||
creator_home_instance_actions
|
|
||||||
.field(instance_actions::received_ban_at)
|
|
||||||
.nullable()
|
|
||||||
.is_not_null()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
/// Checks to see if a user is site banned from any of these places:
|
|
||||||
/// - Their own instance
|
|
||||||
/// - The local instance
|
|
||||||
pub fn creator_banned() -> _ {
|
|
||||||
let local_ban = creator_local_instance_actions
|
|
||||||
.field(instance_actions::received_ban_at)
|
|
||||||
.nullable()
|
|
||||||
.is_not_null();
|
|
||||||
local_ban.or(creator_home_banned())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similar to creator_banned(), but also checks if creator was banned from instance where the
|
|
||||||
/// community is hosted.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_banned_within_community() -> _ {
|
|
||||||
let community_ban = creator_community_instance_actions
|
|
||||||
.field(instance_actions::received_ban_at)
|
|
||||||
.nullable()
|
|
||||||
.is_not_null();
|
|
||||||
creator_banned().or(community_ban)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_local_user_admin_join() -> _ {
|
|
||||||
creator_local_user.on(
|
|
||||||
person::id
|
|
||||||
.eq(creator_local_user.field(local_user::person_id))
|
|
||||||
.and(creator_local_user.field(local_user::admin).eq(true)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
fn am_higher_mod() -> _ {
|
|
||||||
let i_became_moderator = community_actions::became_moderator_at.nullable();
|
|
||||||
|
|
||||||
let creator_became_moderator = creator_community_actions
|
|
||||||
.field(community_actions::became_moderator_at)
|
|
||||||
.nullable();
|
|
||||||
|
|
||||||
i_became_moderator.is_not_null().and(
|
|
||||||
creator_became_moderator
|
|
||||||
.ge(i_became_moderator)
|
|
||||||
.is_distinct_from(false),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks to see if you can mod an item.
|
|
||||||
///
|
|
||||||
/// Caveat: Since admin status isn't federated or ordered, it can't know whether
|
|
||||||
/// item creator is a federated admin, or a higher admin.
|
|
||||||
/// The back-end will reject an action for admin that is higher via
|
|
||||||
/// LocalUser::is_higher_mod_or_admin_check
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn local_user_can_mod() -> _ {
|
|
||||||
local_user_is_admin().or(not(creator_is_admin()).and(am_higher_mod()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks to see if you can mod a post.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn local_user_can_mod_post() -> _ {
|
|
||||||
local_user_is_admin().or(not(post_creator_is_admin()).and(am_higher_mod()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks to see if you can mod a comment.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn local_user_can_mod_comment() -> _ {
|
|
||||||
local_user_is_admin().or(not(comment_creator_is_admin()).and(am_higher_mod()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A special type of can_mod for communities, which dont have creators.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn local_user_community_can_mod() -> _ {
|
|
||||||
let am_admin = local_user::admin.nullable();
|
|
||||||
let am_moderator = community_actions::became_moderator_at
|
|
||||||
.nullable()
|
|
||||||
.is_not_null();
|
|
||||||
am_admin.or(am_moderator).is_not_distinct_from(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Selects the comment columns, but gives an empty string for content when
|
|
||||||
/// deleted or removed, and you're not a mod/admin.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn comment_select_remove_deletes() -> _ {
|
|
||||||
let deleted_or_removed = comment::deleted.or(comment::removed);
|
|
||||||
|
|
||||||
// You can only view the content if it hasn't been removed, or you can mod.
|
|
||||||
let can_view_content = not(deleted_or_removed).or(local_user_can_mod_comment());
|
|
||||||
let content = case_when(can_view_content, comment::content).otherwise("");
|
|
||||||
|
|
||||||
(
|
|
||||||
comment::id,
|
|
||||||
comment::creator_id,
|
|
||||||
comment::post_id,
|
|
||||||
content,
|
|
||||||
comment::removed,
|
|
||||||
comment::published_at,
|
|
||||||
comment::updated_at,
|
|
||||||
comment::deleted,
|
|
||||||
comment::ap_id,
|
|
||||||
comment::local,
|
|
||||||
comment::path,
|
|
||||||
comment::distinguished,
|
|
||||||
comment::language_id,
|
|
||||||
comment::score,
|
|
||||||
comment::upvotes,
|
|
||||||
comment::downvotes,
|
|
||||||
comment::child_count,
|
|
||||||
comment::hot_rank,
|
|
||||||
comment::controversy_rank,
|
|
||||||
comment::report_count,
|
|
||||||
comment::unresolved_report_count,
|
|
||||||
comment::federation_pending,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
// Gets the post tags set on a specific post
|
|
||||||
pub fn post_tags_fragment() -> _ {
|
|
||||||
let sel: SqlLiteral<Json> = diesel::dsl::sql::<diesel::sql_types::Json>("json_agg(tag.*)");
|
|
||||||
post_tag::table
|
|
||||||
.inner_join(tag::table)
|
|
||||||
.select(sel)
|
|
||||||
.filter(post_tag::post_id.eq(post::id))
|
|
||||||
.filter(tag::deleted.eq(false))
|
|
||||||
.single_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
/// Gets the post tags available within a specific community
|
|
||||||
pub fn community_post_tags_fragment() -> _ {
|
|
||||||
let sel: SqlLiteral<Json> = diesel::dsl::sql::<diesel::sql_types::Json>("json_agg(tag.*)");
|
|
||||||
tag::table
|
|
||||||
.select(sel)
|
|
||||||
.filter(tag::community_id.eq(community::id))
|
|
||||||
.filter(tag::deleted.eq(false))
|
|
||||||
.single_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The select for the person1 alias.
|
|
||||||
pub fn person1_select() -> Person1AliasAllColumnsTuple {
|
|
||||||
person1.fields(person::all_columns)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The select for the person2 alias.
|
|
||||||
pub fn person2_select() -> Person2AliasAllColumnsTuple {
|
|
||||||
person2.fields(person::all_columns)
|
|
||||||
}
|
|
||||||
|
|
||||||
type IsSubscribedType =
|
|
||||||
Eq<lemmy_db_schema_file::schema::community_actions::follow_state, Option<CommunityFollowerState>>;
|
|
||||||
|
|
||||||
pub fn filter_is_subscribed() -> IsSubscribedType {
|
|
||||||
community_actions::follow_state.eq(Some(CommunityFollowerState::Accepted))
|
|
||||||
}
|
|
||||||
|
|
||||||
type IsNotUnlistedType =
|
|
||||||
NotEq<lemmy_db_schema_file::schema::community::visibility, CommunityVisibility>;
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn filter_not_unlisted_or_is_subscribed() -> _ {
|
|
||||||
let not_unlisted: IsNotUnlistedType = community::visibility.ne(CommunityVisibility::Unlisted);
|
|
||||||
let is_subscribed: IsSubscribedType = filter_is_subscribed();
|
|
||||||
not_unlisted.or(is_subscribed)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn community_join() -> _ {
|
|
||||||
community::table.on(post::community_id.eq(community::id))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_home_instance_actions_join() -> _ {
|
|
||||||
creator_home_instance_actions.on(
|
|
||||||
creator_home_instance_actions
|
|
||||||
.field(instance_actions::instance_id)
|
|
||||||
.eq(person::instance_id)
|
|
||||||
.and(
|
|
||||||
creator_home_instance_actions
|
|
||||||
.field(instance_actions::person_id)
|
|
||||||
.eq(person::id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_community_instance_actions_join() -> _ {
|
|
||||||
creator_community_instance_actions.on(
|
|
||||||
creator_home_instance_actions
|
|
||||||
.field(instance_actions::instance_id)
|
|
||||||
.eq(community::instance_id)
|
|
||||||
.and(
|
|
||||||
creator_community_instance_actions
|
|
||||||
.field(instance_actions::person_id)
|
|
||||||
.eq(person::id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// join with instance actions for local instance
|
|
||||||
///
|
|
||||||
/// Requires annotation for return type, see https://docs.diesel.rs/2.2.x/diesel/dsl/attr.auto_type.html#annotating-types
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_local_instance_actions_join(local_instance_id: InstanceId) -> _ {
|
|
||||||
creator_local_instance_actions.on(
|
|
||||||
creator_local_instance_actions
|
|
||||||
.field(instance_actions::instance_id)
|
|
||||||
.eq(local_instance_id)
|
|
||||||
.and(
|
|
||||||
creator_local_instance_actions
|
|
||||||
.field(instance_actions::person_id)
|
|
||||||
.eq(person::id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Your instance actions for the community's instance.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_instance_communities_actions_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
instance_actions::table.on(
|
|
||||||
instance_actions::instance_id
|
|
||||||
.eq(community::instance_id)
|
|
||||||
.and(instance_actions::person_id.nullable().eq(my_person_id)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Your instance actions for the person's instance.
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_instance_persons_actions_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
instance_actions::table.on(
|
|
||||||
instance_actions::instance_id
|
|
||||||
.eq(person::instance_id)
|
|
||||||
.and(instance_actions::person_id.nullable().eq(my_person_id)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The select for the my_instance_persons_actions alias
|
|
||||||
pub fn my_instance_persons_actions_select() -> Nullable<MyInstancePersonsActionsAllColumnsTuple> {
|
|
||||||
my_instance_persons_actions
|
|
||||||
.fields(instance_actions::all_columns)
|
|
||||||
.nullable()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Your instance actions for the person's instance.
|
|
||||||
/// A dupe of the above function, but aliased
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_instance_persons_actions_join_1(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
my_instance_persons_actions.on(
|
|
||||||
my_instance_persons_actions
|
|
||||||
.field(instance_actions::instance_id)
|
|
||||||
.eq(person::instance_id)
|
|
||||||
.and(
|
|
||||||
my_instance_persons_actions
|
|
||||||
.field(instance_actions::person_id)
|
|
||||||
.nullable()
|
|
||||||
.eq(my_person_id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn image_details_join() -> _ {
|
|
||||||
image_details::table.on(post::thumbnail_url.eq(image_details::link.nullable()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_community_actions_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
community_actions::table.on(
|
|
||||||
community_actions::community_id
|
|
||||||
.eq(community::id)
|
|
||||||
.and(community_actions::person_id.nullable().eq(my_person_id)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_post_actions_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
post_actions::table.on(
|
|
||||||
post_actions::post_id
|
|
||||||
.eq(post::id)
|
|
||||||
.and(post_actions::person_id.nullable().eq(my_person_id)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_comment_actions_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
comment_actions::table.on(
|
|
||||||
comment_actions::comment_id
|
|
||||||
.eq(comment::id)
|
|
||||||
.and(comment_actions::person_id.nullable().eq(my_person_id)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_person_actions_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
person_actions::table.on(
|
|
||||||
person_actions::target_id
|
|
||||||
.eq(person::id)
|
|
||||||
.and(person_actions::person_id.nullable().eq(my_person_id)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn my_local_user_admin_join(my_person_id: Option<PersonId>) -> _ {
|
|
||||||
local_user::table.on(
|
|
||||||
local_user::person_id
|
|
||||||
.nullable()
|
|
||||||
.eq(my_person_id)
|
|
||||||
.and(local_user::admin.eq(true)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn creator_community_actions_join() -> _ {
|
|
||||||
creator_community_actions.on(
|
|
||||||
creator_community_actions
|
|
||||||
.field(community_actions::community_id)
|
|
||||||
.eq(community::id)
|
|
||||||
.and(
|
|
||||||
creator_community_actions
|
|
||||||
.field(community_actions::person_id)
|
|
||||||
.eq(person::id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[diesel::dsl::auto_type]
|
|
||||||
pub fn suggested_communities() -> _ {
|
|
||||||
community::id.eq_any(
|
|
||||||
local_site::table
|
|
||||||
.left_join(multi_community::table.inner_join(multi_community_entry::table))
|
|
||||||
.filter(multi_community_entry::community_id.is_not_null())
|
|
||||||
.select(multi_community_entry::community_id.assume_not_null()),
|
|
||||||
)
|
|
||||||
}
|
|
63
crates/db_schema/src/utils/queries/filters.rs
Normal file
63
crates/db_schema/src/utils/queries/filters.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::aliases::my_instance_persons_actions;
|
||||||
|
use diesel::{
|
||||||
|
helper_types::{Eq, NotEq},
|
||||||
|
BoolExpressionMethods,
|
||||||
|
ExpressionMethods,
|
||||||
|
NullableExpressionMethods,
|
||||||
|
QueryDsl,
|
||||||
|
};
|
||||||
|
use lemmy_db_schema_file::{
|
||||||
|
enums::{CommunityFollowerState, CommunityVisibility},
|
||||||
|
schema::{
|
||||||
|
community,
|
||||||
|
community_actions,
|
||||||
|
instance_actions,
|
||||||
|
local_site,
|
||||||
|
multi_community,
|
||||||
|
multi_community_entry,
|
||||||
|
person_actions,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Hide all content from blocked communities and persons. Content from blocked instances is also
|
||||||
|
/// hidden, unless the user followed the community explicitly.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn filter_blocked() -> _ {
|
||||||
|
instance_actions::blocked_communities_at
|
||||||
|
.is_null()
|
||||||
|
.or(community_actions::followed_at.is_not_null())
|
||||||
|
.and(community_actions::blocked_at.is_null())
|
||||||
|
.and(person_actions::blocked_at.is_null())
|
||||||
|
.and(
|
||||||
|
my_instance_persons_actions
|
||||||
|
.field(instance_actions::blocked_persons_at)
|
||||||
|
.is_null(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type IsSubscribedType =
|
||||||
|
Eq<lemmy_db_schema_file::schema::community_actions::follow_state, Option<CommunityFollowerState>>;
|
||||||
|
|
||||||
|
pub fn filter_is_subscribed() -> IsSubscribedType {
|
||||||
|
community_actions::follow_state.eq(Some(CommunityFollowerState::Accepted))
|
||||||
|
}
|
||||||
|
|
||||||
|
type IsNotUnlistedType =
|
||||||
|
NotEq<lemmy_db_schema_file::schema::community::visibility, CommunityVisibility>;
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn filter_not_unlisted_or_is_subscribed() -> _ {
|
||||||
|
let not_unlisted: IsNotUnlistedType = community::visibility.ne(CommunityVisibility::Unlisted);
|
||||||
|
let is_subscribed: IsSubscribedType = filter_is_subscribed();
|
||||||
|
not_unlisted.or(is_subscribed)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn filter_suggested_communities() -> _ {
|
||||||
|
community::id.eq_any(
|
||||||
|
local_site::table
|
||||||
|
.left_join(multi_community::table.inner_join(multi_community_entry::table))
|
||||||
|
.filter(multi_community_entry::community_id.is_not_null())
|
||||||
|
.select(multi_community_entry::community_id.assume_not_null()),
|
||||||
|
)
|
||||||
|
}
|
184
crates/db_schema/src/utils/queries/joins.rs
Normal file
184
crates/db_schema/src/utils/queries/joins.rs
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
use crate::{
|
||||||
|
aliases::{
|
||||||
|
creator_community_actions,
|
||||||
|
creator_community_instance_actions,
|
||||||
|
creator_home_instance_actions,
|
||||||
|
creator_local_instance_actions,
|
||||||
|
creator_local_user,
|
||||||
|
my_instance_persons_actions,
|
||||||
|
},
|
||||||
|
newtypes::{InstanceId, PersonId},
|
||||||
|
};
|
||||||
|
use diesel::{BoolExpressionMethods, ExpressionMethods, JoinOnDsl, NullableExpressionMethods};
|
||||||
|
use lemmy_db_schema_file::schema::{
|
||||||
|
comment,
|
||||||
|
comment_actions,
|
||||||
|
community,
|
||||||
|
community_actions,
|
||||||
|
image_details,
|
||||||
|
instance_actions,
|
||||||
|
local_user,
|
||||||
|
person,
|
||||||
|
person_actions,
|
||||||
|
post,
|
||||||
|
post_actions,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_local_user_admin_join() -> _ {
|
||||||
|
creator_local_user.on(
|
||||||
|
person::id
|
||||||
|
.eq(creator_local_user.field(local_user::person_id))
|
||||||
|
.and(creator_local_user.field(local_user::admin).eq(true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn community_join() -> _ {
|
||||||
|
community::table.on(post::community_id.eq(community::id))
|
||||||
|
}
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_home_instance_actions_join() -> _ {
|
||||||
|
creator_home_instance_actions.on(
|
||||||
|
creator_home_instance_actions
|
||||||
|
.field(instance_actions::instance_id)
|
||||||
|
.eq(person::instance_id)
|
||||||
|
.and(
|
||||||
|
creator_home_instance_actions
|
||||||
|
.field(instance_actions::person_id)
|
||||||
|
.eq(person::id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_community_instance_actions_join() -> _ {
|
||||||
|
creator_community_instance_actions.on(
|
||||||
|
creator_home_instance_actions
|
||||||
|
.field(instance_actions::instance_id)
|
||||||
|
.eq(community::instance_id)
|
||||||
|
.and(
|
||||||
|
creator_community_instance_actions
|
||||||
|
.field(instance_actions::person_id)
|
||||||
|
.eq(person::id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// join with instance actions for local instance
|
||||||
|
///
|
||||||
|
/// Requires annotation for return type, see https://docs.diesel.rs/2.2.x/diesel/dsl/attr.auto_type.html#annotating-types
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_local_instance_actions_join(local_instance_id: InstanceId) -> _ {
|
||||||
|
creator_local_instance_actions.on(
|
||||||
|
creator_local_instance_actions
|
||||||
|
.field(instance_actions::instance_id)
|
||||||
|
.eq(local_instance_id)
|
||||||
|
.and(
|
||||||
|
creator_local_instance_actions
|
||||||
|
.field(instance_actions::person_id)
|
||||||
|
.eq(person::id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Your instance actions for the community's instance.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_instance_communities_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
instance_actions::table.on(
|
||||||
|
instance_actions::instance_id
|
||||||
|
.eq(community::instance_id)
|
||||||
|
.and(instance_actions::person_id.nullable().eq(my_person_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Your instance actions for the person's instance.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_instance_persons_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
instance_actions::table.on(
|
||||||
|
instance_actions::instance_id
|
||||||
|
.eq(person::instance_id)
|
||||||
|
.and(instance_actions::person_id.nullable().eq(my_person_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Your instance actions for the person's instance.
|
||||||
|
/// A dupe of the above function, but aliased
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_instance_persons_actions_join_1(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
my_instance_persons_actions.on(
|
||||||
|
my_instance_persons_actions
|
||||||
|
.field(instance_actions::instance_id)
|
||||||
|
.eq(person::instance_id)
|
||||||
|
.and(
|
||||||
|
my_instance_persons_actions
|
||||||
|
.field(instance_actions::person_id)
|
||||||
|
.nullable()
|
||||||
|
.eq(my_person_id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn image_details_join() -> _ {
|
||||||
|
image_details::table.on(post::thumbnail_url.eq(image_details::link.nullable()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_community_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
community_actions::table.on(
|
||||||
|
community_actions::community_id
|
||||||
|
.eq(community::id)
|
||||||
|
.and(community_actions::person_id.nullable().eq(my_person_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_post_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
post_actions::table.on(
|
||||||
|
post_actions::post_id
|
||||||
|
.eq(post::id)
|
||||||
|
.and(post_actions::person_id.nullable().eq(my_person_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_comment_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
comment_actions::table.on(
|
||||||
|
comment_actions::comment_id
|
||||||
|
.eq(comment::id)
|
||||||
|
.and(comment_actions::person_id.nullable().eq(my_person_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_person_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
person_actions::table.on(
|
||||||
|
person_actions::target_id
|
||||||
|
.eq(person::id)
|
||||||
|
.and(person_actions::person_id.nullable().eq(my_person_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn my_local_user_admin_join(my_person_id: Option<PersonId>) -> _ {
|
||||||
|
local_user::table.on(
|
||||||
|
local_user::person_id
|
||||||
|
.nullable()
|
||||||
|
.eq(my_person_id)
|
||||||
|
.and(local_user::admin.eq(true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_community_actions_join() -> _ {
|
||||||
|
creator_community_actions.on(
|
||||||
|
creator_community_actions
|
||||||
|
.field(community_actions::community_id)
|
||||||
|
.eq(community::id)
|
||||||
|
.and(
|
||||||
|
creator_community_actions
|
||||||
|
.field(community_actions::person_id)
|
||||||
|
.eq(person::id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
3
crates/db_schema/src/utils/queries/mod.rs
Normal file
3
crates/db_schema/src/utils/queries/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod filters;
|
||||||
|
pub mod joins;
|
||||||
|
pub mod selects;
|
320
crates/db_schema/src/utils/queries/selects.rs
Normal file
320
crates/db_schema/src/utils/queries/selects.rs
Normal file
|
@ -0,0 +1,320 @@
|
||||||
|
use crate::{
|
||||||
|
aliases::{
|
||||||
|
creator_community_actions,
|
||||||
|
creator_community_instance_actions,
|
||||||
|
creator_home_instance_actions,
|
||||||
|
creator_local_instance_actions,
|
||||||
|
creator_local_user,
|
||||||
|
my_instance_persons_actions,
|
||||||
|
person1,
|
||||||
|
person2,
|
||||||
|
CreatorCommunityInstanceActions,
|
||||||
|
CreatorHomeInstanceActions,
|
||||||
|
CreatorLocalInstanceActions,
|
||||||
|
},
|
||||||
|
utils::functions::{coalesce_2_nullable, coalesce_3_nullable},
|
||||||
|
MyInstancePersonsActionsAllColumnsTuple,
|
||||||
|
Person1AliasAllColumnsTuple,
|
||||||
|
Person2AliasAllColumnsTuple,
|
||||||
|
};
|
||||||
|
use diesel::{
|
||||||
|
dsl::{case_when, exists, not},
|
||||||
|
expression::SqlLiteral,
|
||||||
|
helper_types::Nullable,
|
||||||
|
query_source::AliasedField,
|
||||||
|
sql_types::{Json, Timestamptz},
|
||||||
|
BoolExpressionMethods,
|
||||||
|
ExpressionMethods,
|
||||||
|
NullableExpressionMethods,
|
||||||
|
PgExpressionMethods,
|
||||||
|
QueryDsl,
|
||||||
|
};
|
||||||
|
use lemmy_db_schema_file::schema::{
|
||||||
|
comment,
|
||||||
|
community,
|
||||||
|
community_actions,
|
||||||
|
instance_actions,
|
||||||
|
local_user,
|
||||||
|
person,
|
||||||
|
post,
|
||||||
|
post_tag,
|
||||||
|
tag,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Checks that the creator_local_user is an admin.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_is_admin() -> _ {
|
||||||
|
creator_local_user
|
||||||
|
.field(local_user::admin)
|
||||||
|
.nullable()
|
||||||
|
.is_not_distinct_from(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks that the local_user is an admin.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn local_user_is_admin() -> _ {
|
||||||
|
local_user::admin.nullable().is_not_distinct_from(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks to see if the comment creator is an admin.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn comment_creator_is_admin() -> _ {
|
||||||
|
exists(
|
||||||
|
creator_local_user.filter(
|
||||||
|
comment::creator_id
|
||||||
|
.eq(creator_local_user.field(local_user::person_id))
|
||||||
|
.and(creator_local_user.field(local_user::admin).eq(true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn post_creator_is_admin() -> _ {
|
||||||
|
exists(
|
||||||
|
creator_local_user.filter(
|
||||||
|
post::creator_id
|
||||||
|
.eq(creator_local_user.field(local_user::person_id))
|
||||||
|
.and(creator_local_user.field(local_user::admin).eq(true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_is_moderator() -> _ {
|
||||||
|
creator_community_actions
|
||||||
|
.field(community_actions::became_moderator_at)
|
||||||
|
.nullable()
|
||||||
|
.is_not_null()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_banned_from_community() -> _ {
|
||||||
|
creator_community_actions
|
||||||
|
.field(community_actions::received_ban_at)
|
||||||
|
.nullable()
|
||||||
|
.is_not_null()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_ban_expires_from_community() -> _ {
|
||||||
|
creator_community_actions
|
||||||
|
.field(community_actions::ban_expires_at)
|
||||||
|
.nullable()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
/// Checks to see if a creator is banned from the local instance.
|
||||||
|
fn creator_local_banned() -> _ {
|
||||||
|
creator_local_instance_actions
|
||||||
|
.field(instance_actions::received_ban_at)
|
||||||
|
.nullable()
|
||||||
|
.is_not_null()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
fn creator_local_ban_expires() -> _ {
|
||||||
|
creator_local_instance_actions
|
||||||
|
.field(instance_actions::ban_expires_at)
|
||||||
|
.nullable()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
/// Checks to see if a creator is banned from their community's instance
|
||||||
|
fn creator_community_instance_banned() -> _ {
|
||||||
|
creator_community_instance_actions
|
||||||
|
.field(instance_actions::received_ban_at)
|
||||||
|
.nullable()
|
||||||
|
.is_not_null()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
fn creator_community_instance_ban_expires() -> _ {
|
||||||
|
creator_community_instance_actions
|
||||||
|
.field(instance_actions::ban_expires_at)
|
||||||
|
.nullable()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
/// Checks to see if a creator is banned from their home instance
|
||||||
|
pub fn creator_home_banned() -> _ {
|
||||||
|
creator_home_instance_actions
|
||||||
|
.field(instance_actions::received_ban_at)
|
||||||
|
.nullable()
|
||||||
|
.is_not_null()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
/// Checks to see if a creator is banned from their home instance
|
||||||
|
pub fn creator_home_ban_expires() -> _ {
|
||||||
|
creator_home_instance_actions
|
||||||
|
.field(instance_actions::ban_expires_at)
|
||||||
|
.nullable()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
/// Checks to see if a user is site banned from any of these places:
|
||||||
|
/// - Their own instance
|
||||||
|
/// - The local instance
|
||||||
|
pub fn creator_local_home_banned() -> _ {
|
||||||
|
creator_local_banned().or(creator_home_banned())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CreatorLocalHomeBanExpiresType = coalesce_2_nullable<
|
||||||
|
Timestamptz,
|
||||||
|
Nullable<AliasedField<CreatorLocalInstanceActions, instance_actions::ban_expires_at>>,
|
||||||
|
Nullable<AliasedField<CreatorHomeInstanceActions, instance_actions::ban_expires_at>>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
pub fn creator_local_home_ban_expires() -> CreatorLocalHomeBanExpiresType {
|
||||||
|
coalesce_2_nullable(creator_local_ban_expires(), creator_home_ban_expires())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks to see if a user is site banned from any of these places:
|
||||||
|
/// - The local instance
|
||||||
|
/// - Their own instance
|
||||||
|
/// - The community instance.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn creator_local_home_community_banned() -> _ {
|
||||||
|
creator_local_banned()
|
||||||
|
.or(creator_home_banned())
|
||||||
|
.or(creator_community_instance_banned())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CreatorLocalHomeCommunityBanExpiresType = coalesce_3_nullable<
|
||||||
|
Timestamptz,
|
||||||
|
Nullable<AliasedField<CreatorLocalInstanceActions, instance_actions::ban_expires_at>>,
|
||||||
|
Nullable<AliasedField<CreatorHomeInstanceActions, instance_actions::ban_expires_at>>,
|
||||||
|
Nullable<AliasedField<CreatorCommunityInstanceActions, instance_actions::ban_expires_at>>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
pub fn creator_local_home_community_ban_expires() -> CreatorLocalHomeCommunityBanExpiresType {
|
||||||
|
coalesce_3_nullable(
|
||||||
|
creator_local_ban_expires(),
|
||||||
|
creator_home_ban_expires(),
|
||||||
|
creator_community_instance_ban_expires(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
fn am_higher_mod() -> _ {
|
||||||
|
let i_became_moderator = community_actions::became_moderator_at.nullable();
|
||||||
|
|
||||||
|
let creator_became_moderator = creator_community_actions
|
||||||
|
.field(community_actions::became_moderator_at)
|
||||||
|
.nullable();
|
||||||
|
|
||||||
|
i_became_moderator.is_not_null().and(
|
||||||
|
creator_became_moderator
|
||||||
|
.ge(i_became_moderator)
|
||||||
|
.is_distinct_from(false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks to see if you can mod an item.
|
||||||
|
///
|
||||||
|
/// Caveat: Since admin status isn't federated or ordered, it can't know whether
|
||||||
|
/// item creator is a federated admin, or a higher admin.
|
||||||
|
/// The back-end will reject an action for admin that is higher via
|
||||||
|
/// LocalUser::is_higher_mod_or_admin_check
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn local_user_can_mod() -> _ {
|
||||||
|
local_user_is_admin().or(not(creator_is_admin()).and(am_higher_mod()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks to see if you can mod a post.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn local_user_can_mod_post() -> _ {
|
||||||
|
local_user_is_admin().or(not(post_creator_is_admin()).and(am_higher_mod()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks to see if you can mod a comment.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn local_user_can_mod_comment() -> _ {
|
||||||
|
local_user_is_admin().or(not(comment_creator_is_admin()).and(am_higher_mod()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A special type of can_mod for communities, which dont have creators.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn local_user_community_can_mod() -> _ {
|
||||||
|
let am_admin = local_user::admin.nullable();
|
||||||
|
let am_moderator = community_actions::became_moderator_at
|
||||||
|
.nullable()
|
||||||
|
.is_not_null();
|
||||||
|
am_admin.or(am_moderator).is_not_distinct_from(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Selects the comment columns, but gives an empty string for content when
|
||||||
|
/// deleted or removed, and you're not a mod/admin.
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
pub fn comment_select_remove_deletes() -> _ {
|
||||||
|
let deleted_or_removed = comment::deleted.or(comment::removed);
|
||||||
|
|
||||||
|
// You can only view the content if it hasn't been removed, or you can mod.
|
||||||
|
let can_view_content = not(deleted_or_removed).or(local_user_can_mod_comment());
|
||||||
|
let content = case_when(can_view_content, comment::content).otherwise("");
|
||||||
|
|
||||||
|
(
|
||||||
|
comment::id,
|
||||||
|
comment::creator_id,
|
||||||
|
comment::post_id,
|
||||||
|
content,
|
||||||
|
comment::removed,
|
||||||
|
comment::published_at,
|
||||||
|
comment::updated_at,
|
||||||
|
comment::deleted,
|
||||||
|
comment::ap_id,
|
||||||
|
comment::local,
|
||||||
|
comment::path,
|
||||||
|
comment::distinguished,
|
||||||
|
comment::language_id,
|
||||||
|
comment::score,
|
||||||
|
comment::upvotes,
|
||||||
|
comment::downvotes,
|
||||||
|
comment::child_count,
|
||||||
|
comment::hot_rank,
|
||||||
|
comment::controversy_rank,
|
||||||
|
comment::report_count,
|
||||||
|
comment::unresolved_report_count,
|
||||||
|
comment::federation_pending,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
// Gets the post tags set on a specific post
|
||||||
|
pub fn post_tags_fragment() -> _ {
|
||||||
|
let sel: SqlLiteral<Json> = diesel::dsl::sql::<diesel::sql_types::Json>("json_agg(tag.*)");
|
||||||
|
post_tag::table
|
||||||
|
.inner_join(tag::table)
|
||||||
|
.select(sel)
|
||||||
|
.filter(post_tag::post_id.eq(post::id))
|
||||||
|
.filter(tag::deleted.eq(false))
|
||||||
|
.single_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[diesel::dsl::auto_type]
|
||||||
|
/// Gets the post tags available within a specific community
|
||||||
|
pub fn community_post_tags_fragment() -> _ {
|
||||||
|
let sel: SqlLiteral<Json> = diesel::dsl::sql::<diesel::sql_types::Json>("json_agg(tag.*)");
|
||||||
|
tag::table
|
||||||
|
.select(sel)
|
||||||
|
.filter(tag::community_id.eq(community::id))
|
||||||
|
.filter(tag::deleted.eq(false))
|
||||||
|
.single_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The select for the person1 alias.
|
||||||
|
pub fn person1_select() -> Person1AliasAllColumnsTuple {
|
||||||
|
person1.fields(person::all_columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The select for the person2 alias.
|
||||||
|
pub fn person2_select() -> Person2AliasAllColumnsTuple {
|
||||||
|
person2.fields(person::all_columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The select for the my_instance_persons_actions alias
|
||||||
|
pub fn my_instance_persons_actions_select() -> Nullable<MyInstancePersonsActionsAllColumnsTuple> {
|
||||||
|
my_instance_persons_actions
|
||||||
|
.fields(instance_actions::all_columns)
|
||||||
|
.nullable()
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ serde = { workspace = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
lemmy_db_views_local_user = { workspace = true }
|
lemmy_db_views_local_user = { workspace = true }
|
||||||
|
|
|
@ -26,18 +26,19 @@ use lemmy_db_schema::{
|
||||||
now,
|
now,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::{
|
||||||
creator_community_actions_join,
|
filters::{filter_blocked, filter_suggested_communities},
|
||||||
creator_community_instance_actions_join,
|
joins::{
|
||||||
creator_home_instance_actions_join,
|
creator_community_actions_join,
|
||||||
creator_local_instance_actions_join,
|
creator_community_instance_actions_join,
|
||||||
filter_blocked,
|
creator_home_instance_actions_join,
|
||||||
my_comment_actions_join,
|
creator_local_instance_actions_join,
|
||||||
my_community_actions_join,
|
my_comment_actions_join,
|
||||||
my_instance_communities_actions_join,
|
my_community_actions_join,
|
||||||
my_instance_persons_actions_join_1,
|
my_instance_communities_actions_join,
|
||||||
my_local_user_admin_join,
|
my_instance_persons_actions_join_1,
|
||||||
my_person_actions_join,
|
my_local_user_admin_join,
|
||||||
suggested_communities,
|
my_person_actions_join,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
seconds_to_pg_interval,
|
seconds_to_pg_interval,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
@ -202,7 +203,7 @@ impl CommentQuery<'_> {
|
||||||
ListingType::ModeratorView => {
|
ListingType::ModeratorView => {
|
||||||
query.filter(community_actions::became_moderator_at.is_not_null())
|
query.filter(community_actions::became_moderator_at.is_not_null())
|
||||||
}
|
}
|
||||||
ListingType::Suggested => query.filter(suggested_communities()),
|
ListingType::Suggested => query.filter(filter_suggested_communities()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if !o.local_user.show_bot_accounts() {
|
if !o.local_user.show_bot_accounts() {
|
||||||
|
@ -463,6 +464,7 @@ mod tests {
|
||||||
local_user: inserted_timmy_local_user.clone(),
|
local_user: inserted_timmy_local_user.clone(),
|
||||||
person: inserted_timmy_person.clone(),
|
person: inserted_timmy_person.clone(),
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
let site_form = SiteInsertForm::new("test site".to_string(), inserted_instance.id);
|
let site_form = SiteInsertForm::new("test site".to_string(), inserted_instance.id);
|
||||||
let site = Site::create(pool, &site_form).await?;
|
let site = Site::create(pool, &site_form).await?;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
comment::{Comment, CommentActions},
|
comment::{Comment, CommentActions},
|
||||||
community::{Community, CommunityActions},
|
community::{Community, CommunityActions},
|
||||||
|
@ -10,14 +11,17 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
comment_creator_is_admin,
|
comment_creator_is_admin,
|
||||||
comment_select_remove_deletes,
|
comment_select_remove_deletes,
|
||||||
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_banned_within_community,
|
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_community_ban_expires,
|
||||||
|
creator_local_home_community_banned,
|
||||||
local_user_can_mod_comment,
|
local_user_can_mod_comment,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeCommunityBanExpiresType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,10 +75,17 @@ pub struct CommentView {
|
||||||
pub can_mod: bool,
|
pub can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned_within_community()
|
select_expression = creator_local_home_community_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeCommunityBanExpiresType,
|
||||||
|
select_expression = creator_local_home_community_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -87,6 +98,12 @@ pub struct CommentView {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
|
|
|
@ -17,12 +17,16 @@ use lemmy_db_schema::{
|
||||||
now,
|
now,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::{
|
||||||
filter_is_subscribed,
|
filters::{
|
||||||
filter_not_unlisted_or_is_subscribed,
|
filter_is_subscribed,
|
||||||
my_community_actions_join,
|
filter_not_unlisted_or_is_subscribed,
|
||||||
my_instance_communities_actions_join,
|
filter_suggested_communities,
|
||||||
my_local_user_admin_join,
|
},
|
||||||
suggested_communities,
|
joins::{
|
||||||
|
my_community_actions_join,
|
||||||
|
my_instance_communities_actions_join,
|
||||||
|
my_local_user_admin_join,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
seconds_to_pg_interval,
|
seconds_to_pg_interval,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
@ -144,7 +148,7 @@ impl CommunityQuery<'_> {
|
||||||
ListingType::ModeratorView => {
|
ListingType::ModeratorView => {
|
||||||
query.filter(community_actions::became_moderator_at.is_not_null())
|
query.filter(community_actions::became_moderator_at.is_not_null())
|
||||||
}
|
}
|
||||||
ListingType::Suggested => query.filter(suggested_communities()),
|
ListingType::Suggested => query.filter(filter_suggested_communities()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,10 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{community_post_tags_fragment, local_user_community_can_mod},
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
|
community_post_tags_fragment,
|
||||||
|
local_user_community_can_mod,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
|
|
@ -38,6 +38,7 @@ serde_with = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
actix-web = { workspace = true, optional = true }
|
actix-web = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
now,
|
now,
|
||||||
paginate,
|
paginate,
|
||||||
queries::creator_home_instance_actions_join,
|
queries::joins::creator_home_instance_actions_join,
|
||||||
DbPool,
|
DbPool,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::source::{local_user::LocalUser, person::Person};
|
use lemmy_db_schema::source::{local_user::LocalUser, person::Person};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::creator_home_banned,
|
lemmy_db_schema::utils::queries::selects::{creator_home_ban_expires, creator_home_banned},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
@ -27,4 +28,10 @@ pub struct LocalUserView {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_home_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,11 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{filter_is_subscribed, filter_not_unlisted_or_is_subscribed, suggested_communities},
|
queries::filters::{
|
||||||
|
filter_is_subscribed,
|
||||||
|
filter_not_unlisted_or_is_subscribed,
|
||||||
|
filter_suggested_communities,
|
||||||
|
},
|
||||||
DbPool,
|
DbPool,
|
||||||
},
|
},
|
||||||
ModlogActionType,
|
ModlogActionType,
|
||||||
|
@ -380,7 +384,7 @@ impl ModlogCombinedQuery<'_> {
|
||||||
ListingType::ModeratorView => {
|
ListingType::ModeratorView => {
|
||||||
query.filter(community_actions::became_moderator_at.is_not_null())
|
query.filter(community_actions::became_moderator_at.is_not_null())
|
||||||
}
|
}
|
||||||
ListingType::Suggested => query.filter(suggested_communities()),
|
ListingType::Suggested => query.filter(filter_suggested_communities()),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sorting by published
|
// Sorting by published
|
||||||
|
|
|
@ -33,7 +33,7 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{dsl::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
diesel::{dsl::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
||||||
lemmy_db_schema::{utils::queries::person1_select, Person1AliasAllColumnsTuple},
|
lemmy_db_schema::{utils::queries::selects::person1_select, Person1AliasAllColumnsTuple},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
|
|
@ -39,5 +39,6 @@ serde = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -23,20 +23,22 @@ use lemmy_db_schema::{
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::{
|
||||||
community_join,
|
filters::filter_blocked,
|
||||||
creator_community_actions_join,
|
joins::{
|
||||||
creator_home_instance_actions_join,
|
community_join,
|
||||||
creator_local_instance_actions_join,
|
creator_community_actions_join,
|
||||||
creator_local_user_admin_join,
|
creator_home_instance_actions_join,
|
||||||
filter_blocked,
|
creator_local_instance_actions_join,
|
||||||
image_details_join,
|
creator_local_user_admin_join,
|
||||||
my_comment_actions_join,
|
image_details_join,
|
||||||
my_community_actions_join,
|
my_comment_actions_join,
|
||||||
my_instance_communities_actions_join,
|
my_community_actions_join,
|
||||||
my_instance_persons_actions_join_1,
|
my_instance_communities_actions_join,
|
||||||
my_local_user_admin_join,
|
my_instance_persons_actions_join_1,
|
||||||
my_person_actions_join,
|
my_local_user_admin_join,
|
||||||
my_post_actions_join,
|
my_person_actions_join,
|
||||||
|
my_post_actions_join,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
DbPool,
|
DbPool,
|
||||||
},
|
},
|
||||||
|
@ -294,8 +296,10 @@ fn map_to_enum(v: NotificationViewInternal) -> Option<NotificationView> {
|
||||||
post_tags: v.post_tags,
|
post_tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
})
|
})
|
||||||
} else if let (Some(post), Some(community)) = (v.post, v.community) {
|
} else if let (Some(post), Some(community)) = (v.post, v.community) {
|
||||||
NotificationData::Post(PostView {
|
NotificationData::Post(PostView {
|
||||||
|
@ -310,8 +314,10 @@ fn map_to_enum(v: NotificationViewInternal) -> Option<NotificationView> {
|
||||||
tags: v.post_tags,
|
tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
})
|
})
|
||||||
} else if let Some(private_message) = v.private_message {
|
} else if let Some(private_message) = v.private_message {
|
||||||
NotificationData::PrivateMessage(PrivateMessageView {
|
NotificationData::PrivateMessage(PrivateMessageView {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::PaginationCursor,
|
newtypes::PaginationCursor,
|
||||||
source::{
|
source::{
|
||||||
|
@ -21,14 +22,17 @@ use serde_with::skip_serializing_none;
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::{
|
lemmy_db_schema::{
|
||||||
utils::queries::{
|
utils::queries::selects::{
|
||||||
creator_banned,
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_is_admin,
|
creator_is_admin,
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_ban_expires,
|
||||||
|
creator_local_home_banned,
|
||||||
local_user_can_mod,
|
local_user_can_mod,
|
||||||
person1_select,
|
person1_select,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeBanExpiresType,
|
||||||
},
|
},
|
||||||
Person1AliasAllColumnsTuple,
|
Person1AliasAllColumnsTuple,
|
||||||
},
|
},
|
||||||
|
@ -91,10 +95,17 @@ struct NotificationViewInternal {
|
||||||
can_mod: bool,
|
can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned()
|
select_expression = creator_local_home_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
creator_banned: bool,
|
creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeBanExpiresType,
|
||||||
|
select_expression = creator_local_home_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -107,6 +118,12 @@ struct NotificationViewInternal {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
creator_banned_from_community: bool,
|
creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
|
|
@ -42,6 +42,7 @@ serde = { workspace = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -10,7 +10,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::joins::{
|
||||||
creator_home_instance_actions_join,
|
creator_home_instance_actions_join,
|
||||||
creator_local_instance_actions_join,
|
creator_local_instance_actions_join,
|
||||||
my_person_actions_join,
|
my_person_actions_join,
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::source::person::{Person, PersonActions};
|
use lemmy_db_schema::source::person::{Person, PersonActions};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{helper_types::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
diesel::{helper_types::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::{functions::coalesce, queries::creator_banned},
|
lemmy_db_schema::utils::{
|
||||||
|
functions::coalesce,
|
||||||
|
queries::selects::{
|
||||||
|
creator_local_home_ban_expires,
|
||||||
|
creator_local_home_banned,
|
||||||
|
CreatorLocalHomeBanExpiresType,
|
||||||
|
},
|
||||||
|
},
|
||||||
lemmy_db_schema_file::schema::local_user,
|
lemmy_db_schema_file::schema::local_user,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,8 +39,15 @@ pub struct PersonView {
|
||||||
pub person_actions: Option<PersonActions>,
|
pub person_actions: Option<PersonActions>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned()
|
select_expression = creator_local_home_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeBanExpiresType,
|
||||||
|
select_expression = creator_local_home_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
derive-new = { workspace = true }
|
derive-new = { workspace = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
|
|
|
@ -24,7 +24,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::joins::{
|
||||||
community_join,
|
community_join,
|
||||||
creator_community_actions_join,
|
creator_community_actions_join,
|
||||||
creator_home_instance_actions_join,
|
creator_home_instance_actions_join,
|
||||||
|
@ -240,8 +240,10 @@ impl InternalToCombinedView for PersonContentCombinedViewInternal {
|
||||||
post_tags: v.post_tags,
|
post_tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Some(PersonContentCombinedView::Post(PostView {
|
Some(PersonContentCombinedView::Post(PostView {
|
||||||
|
@ -256,8 +258,10 @@ impl InternalToCombinedView for PersonContentCombinedViewInternal {
|
||||||
tags: v.post_tags,
|
tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::{PaginationCursor, PersonId},
|
newtypes::{PaginationCursor, PersonId},
|
||||||
source::{
|
source::{
|
||||||
|
@ -18,13 +19,16 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
creator_banned,
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_is_admin,
|
creator_is_admin,
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_ban_expires,
|
||||||
|
creator_local_home_banned,
|
||||||
local_user_can_mod,
|
local_user_can_mod,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeBanExpiresType,
|
||||||
},
|
},
|
||||||
|
|
||||||
lemmy_db_views_local_user::LocalUserView,
|
lemmy_db_views_local_user::LocalUserView,
|
||||||
|
@ -78,10 +82,17 @@ pub(crate) struct PersonContentCombinedViewInternal {
|
||||||
pub can_mod: bool,
|
pub can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned()
|
select_expression = creator_local_home_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeBanExpiresType,
|
||||||
|
select_expression = creator_local_home_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -94,6 +105,12 @@ pub(crate) struct PersonContentCombinedViewInternal {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
|
|
@ -46,6 +46,7 @@ serde = { workspace = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::joins::{
|
||||||
community_join,
|
community_join,
|
||||||
creator_community_actions_join,
|
creator_community_actions_join,
|
||||||
creator_community_instance_actions_join,
|
creator_community_instance_actions_join,
|
||||||
|
@ -230,8 +230,10 @@ impl InternalToCombinedView for PersonLikedCombinedViewInternal {
|
||||||
post_tags: v.post_tags,
|
post_tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Some(PersonLikedCombinedView::Post(PostView {
|
Some(PersonLikedCombinedView::Post(PostView {
|
||||||
|
@ -246,8 +248,10 @@ impl InternalToCombinedView for PersonLikedCombinedViewInternal {
|
||||||
tags: v.post_tags,
|
tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +300,7 @@ mod tests {
|
||||||
local_user: timmy_local_user,
|
local_user: timmy_local_user,
|
||||||
person: timmy.clone(),
|
person: timmy.clone(),
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let sara_form = PersonInsertForm::test_form(instance.id, "sara_pcv");
|
let sara_form = PersonInsertForm::test_form(instance.id, "sara_pcv");
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::PaginationCursor,
|
newtypes::PaginationCursor,
|
||||||
source::{
|
source::{
|
||||||
|
@ -19,13 +20,16 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_banned_within_community,
|
|
||||||
creator_is_admin,
|
creator_is_admin,
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_community_ban_expires,
|
||||||
|
creator_local_home_community_banned,
|
||||||
local_user_can_mod,
|
local_user_can_mod,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeCommunityBanExpiresType,
|
||||||
},
|
},
|
||||||
lemmy_db_views_local_user::LocalUserView,
|
lemmy_db_views_local_user::LocalUserView,
|
||||||
};
|
};
|
||||||
|
@ -78,10 +82,17 @@ pub(crate) struct PersonLikedCombinedViewInternal {
|
||||||
pub can_mod: bool,
|
pub can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned_within_community()
|
select_expression = creator_local_home_community_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeCommunityBanExpiresType,
|
||||||
|
select_expression = creator_local_home_community_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -94,6 +105,12 @@ pub(crate) struct PersonLikedCombinedViewInternal {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
|
|
@ -46,6 +46,7 @@ serde = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::joins::{
|
||||||
community_join,
|
community_join,
|
||||||
creator_community_actions_join,
|
creator_community_actions_join,
|
||||||
creator_community_instance_actions_join,
|
creator_community_instance_actions_join,
|
||||||
|
@ -219,8 +219,10 @@ impl InternalToCombinedView for PersonSavedCombinedViewInternal {
|
||||||
post_tags: v.post_tags,
|
post_tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Some(PersonSavedCombinedView::Post(PostView {
|
Some(PersonSavedCombinedView::Post(PostView {
|
||||||
|
@ -235,8 +237,10 @@ impl InternalToCombinedView for PersonSavedCombinedViewInternal {
|
||||||
tags: v.post_tags,
|
tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,6 +288,7 @@ mod tests {
|
||||||
local_user: timmy_local_user,
|
local_user: timmy_local_user,
|
||||||
person: timmy.clone(),
|
person: timmy.clone(),
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let sara_form = PersonInsertForm::test_form(instance.id, "sara_pcv");
|
let sara_form = PersonInsertForm::test_form(instance.id, "sara_pcv");
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::PaginationCursor,
|
newtypes::PaginationCursor,
|
||||||
source::{
|
source::{
|
||||||
|
@ -18,13 +19,16 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_banned_within_community,
|
|
||||||
creator_is_admin,
|
creator_is_admin,
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_community_ban_expires,
|
||||||
|
creator_local_home_community_banned,
|
||||||
local_user_can_mod,
|
local_user_can_mod,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeCommunityBanExpiresType,
|
||||||
},
|
},
|
||||||
|
|
||||||
lemmy_db_views_local_user::LocalUserView,
|
lemmy_db_views_local_user::LocalUserView,
|
||||||
|
@ -78,10 +82,17 @@ pub(crate) struct PersonSavedCombinedViewInternal {
|
||||||
pub can_mod: bool,
|
pub can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned_within_community()
|
select_expression = creator_local_home_community_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeCommunityBanExpiresType,
|
||||||
|
select_expression = creator_local_home_community_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -94,6 +105,12 @@ pub(crate) struct PersonSavedCombinedViewInternal {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
|
|
@ -32,21 +32,25 @@ use lemmy_db_schema::{
|
||||||
now,
|
now,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::{
|
||||||
creator_community_actions_join,
|
filters::{
|
||||||
creator_community_instance_actions_join,
|
filter_blocked,
|
||||||
creator_home_instance_actions_join,
|
filter_is_subscribed,
|
||||||
creator_local_instance_actions_join,
|
filter_not_unlisted_or_is_subscribed,
|
||||||
filter_blocked,
|
filter_suggested_communities,
|
||||||
filter_is_subscribed,
|
},
|
||||||
filter_not_unlisted_or_is_subscribed,
|
joins::{
|
||||||
image_details_join,
|
creator_community_actions_join,
|
||||||
my_community_actions_join,
|
creator_community_instance_actions_join,
|
||||||
my_instance_communities_actions_join,
|
creator_home_instance_actions_join,
|
||||||
my_instance_persons_actions_join_1,
|
creator_local_instance_actions_join,
|
||||||
my_local_user_admin_join,
|
image_details_join,
|
||||||
my_person_actions_join,
|
my_community_actions_join,
|
||||||
my_post_actions_join,
|
my_instance_communities_actions_join,
|
||||||
suggested_communities,
|
my_instance_persons_actions_join_1,
|
||||||
|
my_local_user_admin_join,
|
||||||
|
my_person_actions_join,
|
||||||
|
my_post_actions_join,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
seconds_to_pg_interval,
|
seconds_to_pg_interval,
|
||||||
Commented,
|
Commented,
|
||||||
|
@ -400,7 +404,7 @@ impl PostQuery<'_> {
|
||||||
ListingType::ModeratorView => {
|
ListingType::ModeratorView => {
|
||||||
query = query.filter(community_actions::became_moderator_at.is_not_null());
|
query = query.filter(community_actions::became_moderator_at.is_not_null());
|
||||||
}
|
}
|
||||||
ListingType::Suggested => query = query.filter(suggested_communities()),
|
ListingType::Suggested => query = query.filter(filter_suggested_communities()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !o.show_nsfw.unwrap_or(o.local_user.show_nsfw(site)) {
|
if !o.show_nsfw.unwrap_or(o.local_user.show_nsfw(site)) {
|
||||||
|
@ -568,7 +572,7 @@ mod tests {
|
||||||
impls::{PostQuery, PostSortType},
|
impls::{PostQuery, PostSortType},
|
||||||
PostView,
|
PostView,
|
||||||
};
|
};
|
||||||
use chrono::Utc;
|
use chrono::{DateTime, Days, Utc};
|
||||||
use diesel_async::SimpleAsyncConnection;
|
use diesel_async::SimpleAsyncConnection;
|
||||||
use diesel_uplete::UpleteCount;
|
use diesel_uplete::UpleteCount;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
@ -791,17 +795,20 @@ mod tests {
|
||||||
local_user: inserted_tegan_local_user,
|
local_user: inserted_tegan_local_user,
|
||||||
person: inserted_tegan_person,
|
person: inserted_tegan_person,
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
let john = LocalUserView {
|
let john = LocalUserView {
|
||||||
local_user: inserted_john_local_user,
|
local_user: inserted_john_local_user,
|
||||||
person: inserted_john_person,
|
person: inserted_john_person,
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bot = LocalUserView {
|
let bot = LocalUserView {
|
||||||
local_user: inserted_bot_local_user,
|
local_user: inserted_bot_local_user,
|
||||||
person: inserted_bot_person,
|
person: inserted_bot_person,
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Data {
|
Ok(Data {
|
||||||
|
@ -2076,10 +2083,17 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use microseconds for date checks
|
||||||
|
///
|
||||||
|
/// Necessary because postgres uses micros, but rust uses nanos
|
||||||
|
fn micros(dt: DateTime<Utc>) -> i64 {
|
||||||
|
dt.timestamp_micros()
|
||||||
|
}
|
||||||
|
|
||||||
#[test_context(Data)]
|
#[test_context(Data)]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn post_listing_local_user_banned(data: &mut Data) -> LemmyResult<()> {
|
async fn post_listing_creator_banned(data: &mut Data) -> LemmyResult<()> {
|
||||||
let pool = &data.pool();
|
let pool = &data.pool();
|
||||||
let pool = &mut pool.into();
|
let pool = &mut pool.into();
|
||||||
|
|
||||||
|
@ -2097,9 +2111,11 @@ mod tests {
|
||||||
};
|
};
|
||||||
let banned_post = Post::create(pool, &post_form).await?;
|
let banned_post = Post::create(pool, &post_form).await?;
|
||||||
|
|
||||||
|
let expires_at = Utc::now().checked_add_days(Days::new(1));
|
||||||
|
|
||||||
InstanceActions::ban(
|
InstanceActions::ban(
|
||||||
pool,
|
pool,
|
||||||
&InstanceBanForm::new(banned_person.id, data.instance.id, None),
|
&InstanceBanForm::new(banned_person.id, data.instance.id, expires_at),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -2115,7 +2131,66 @@ mod tests {
|
||||||
|
|
||||||
assert!(post_view.creator_banned);
|
assert!(post_view.creator_banned);
|
||||||
|
|
||||||
assert!(post_view.creator_banned);
|
// Make sure the expires at is correct
|
||||||
|
assert_eq!(
|
||||||
|
expires_at.map(micros),
|
||||||
|
post_view.creator_ban_expires_at.map(micros)
|
||||||
|
);
|
||||||
|
|
||||||
|
Person::delete(pool, banned_person.id).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_context(Data)]
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn post_listing_creator_community_banned(data: &mut Data) -> LemmyResult<()> {
|
||||||
|
let pool = &data.pool();
|
||||||
|
let pool = &mut pool.into();
|
||||||
|
|
||||||
|
let banned_person_form = PersonInsertForm::test_form(data.instance.id, "jarvis");
|
||||||
|
|
||||||
|
let banned_person = Person::create(pool, &banned_person_form).await?;
|
||||||
|
|
||||||
|
let post_form = PostInsertForm {
|
||||||
|
language_id: Some(LanguageId(1)),
|
||||||
|
..PostInsertForm::new(
|
||||||
|
"banned jarvis post".to_string(),
|
||||||
|
banned_person.id,
|
||||||
|
data.community.id,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let banned_post = Post::create(pool, &post_form).await?;
|
||||||
|
|
||||||
|
let expires_at = Utc::now().checked_add_days(Days::new(1));
|
||||||
|
|
||||||
|
CommunityActions::ban(
|
||||||
|
pool,
|
||||||
|
&CommunityPersonBanForm {
|
||||||
|
ban_expires_at: Some(expires_at),
|
||||||
|
..CommunityPersonBanForm::new(data.community.id, banned_person.id)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Let john read their post
|
||||||
|
let post_view = PostView::read(
|
||||||
|
pool,
|
||||||
|
banned_post.id,
|
||||||
|
Some(&data.john.local_user),
|
||||||
|
data.instance.id,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
assert!(post_view.creator_banned_from_community);
|
||||||
|
assert!(!post_view.creator_banned);
|
||||||
|
|
||||||
|
// Make sure the expires at is correct
|
||||||
|
assert_eq!(
|
||||||
|
expires_at.map(micros),
|
||||||
|
post_view.creator_community_ban_expires_at.map(micros)
|
||||||
|
);
|
||||||
|
|
||||||
Person::delete(pool, banned_person.id).await?;
|
Person::delete(pool, banned_person.id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
community::{Community, CommunityActions},
|
community::{Community, CommunityActions},
|
||||||
images::ImageDetails,
|
images::ImageDetails,
|
||||||
|
@ -12,13 +13,16 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_banned_within_community,
|
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_ban_expires,
|
||||||
|
creator_local_home_community_banned,
|
||||||
local_user_can_mod_post,
|
local_user_can_mod_post,
|
||||||
post_creator_is_admin,
|
post_creator_is_admin,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeBanExpiresType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,10 +71,17 @@ pub struct PostView {
|
||||||
pub can_mod: bool,
|
pub can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned_within_community()
|
select_expression = creator_local_home_community_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeBanExpiresType,
|
||||||
|
select_expression = creator_local_home_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -83,4 +94,10 @@ pub struct PostView {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::person1_select,
|
lemmy_db_schema::utils::queries::selects::person1_select,
|
||||||
lemmy_db_schema::Person1AliasAllColumnsTuple,
|
lemmy_db_schema::Person1AliasAllColumnsTuple,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{helper_types::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
diesel::{helper_types::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
||||||
lemmy_db_schema::{utils::queries::person1_select, Person1AliasAllColumnsTuple},
|
lemmy_db_schema::{utils::queries::selects::person1_select, Person1AliasAllColumnsTuple},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
|
|
@ -41,7 +41,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::joins::{
|
||||||
creator_community_instance_actions_join,
|
creator_community_instance_actions_join,
|
||||||
creator_home_instance_actions_join,
|
creator_home_instance_actions_join,
|
||||||
creator_local_instance_actions_join,
|
creator_local_instance_actions_join,
|
||||||
|
@ -622,6 +622,7 @@ mod tests {
|
||||||
local_user: timmy_local_user,
|
local_user: timmy_local_user,
|
||||||
person: inserted_timmy.clone(),
|
person: inserted_timmy.clone(),
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make an admin, to be able to see private message reports.
|
// Make an admin, to be able to see private message reports.
|
||||||
|
@ -633,6 +634,7 @@ mod tests {
|
||||||
local_user: admin_local_user,
|
local_user: admin_local_user,
|
||||||
person: inserted_admin.clone(),
|
person: inserted_admin.clone(),
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let sara_form = PersonInsertForm::test_form(inserted_instance.id, "sara_rcv");
|
let sara_form = PersonInsertForm::test_form(inserted_instance.id, "sara_rcv");
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
combined::report::ReportCombined,
|
combined::report::ReportCombined,
|
||||||
comment::{Comment, CommentActions},
|
comment::{Comment, CommentActions},
|
||||||
|
@ -15,13 +16,16 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{dsl::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
diesel::{dsl::Nullable, NullableExpressionMethods, Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
|
creator_ban_expires_from_community,
|
||||||
creator_banned_from_community,
|
creator_banned_from_community,
|
||||||
creator_banned_within_community,
|
|
||||||
creator_is_moderator,
|
creator_is_moderator,
|
||||||
|
creator_local_home_community_ban_expires,
|
||||||
|
creator_local_home_community_banned,
|
||||||
local_user_is_admin,
|
local_user_is_admin,
|
||||||
person1_select,
|
person1_select,
|
||||||
person2_select,
|
person2_select,
|
||||||
|
CreatorLocalHomeCommunityBanExpiresType,
|
||||||
},
|
},
|
||||||
lemmy_db_schema::{Person1AliasAllColumnsTuple, Person2AliasAllColumnsTuple},
|
lemmy_db_schema::{Person1AliasAllColumnsTuple, Person2AliasAllColumnsTuple},
|
||||||
lemmy_db_views_local_user::LocalUserView,
|
lemmy_db_views_local_user::LocalUserView,
|
||||||
|
@ -82,16 +86,29 @@ pub struct ReportCombinedViewInternal {
|
||||||
pub creator_is_moderator: bool,
|
pub creator_is_moderator: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned_within_community()
|
select_expression = creator_local_home_community_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeCommunityBanExpiresType,
|
||||||
|
select_expression = creator_local_home_community_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned_from_community()
|
select_expression = creator_banned_from_community()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full", diesel(embed))]
|
#[cfg_attr(feature = "full", diesel(embed))]
|
||||||
pub community: Option<Community>,
|
pub community: Option<Community>,
|
||||||
#[cfg_attr(feature = "full", diesel(embed))]
|
#[cfg_attr(feature = "full", diesel(embed))]
|
||||||
|
|
|
@ -53,6 +53,7 @@ serde = { workspace = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
i-love-jesus = { workspace = true, optional = true }
|
i-love-jesus = { workspace = true, optional = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
|
|
|
@ -34,19 +34,23 @@ use lemmy_db_schema::{
|
||||||
now,
|
now,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::{
|
||||||
creator_community_actions_join,
|
filters::{
|
||||||
creator_home_instance_actions_join,
|
filter_is_subscribed,
|
||||||
creator_local_instance_actions_join,
|
filter_not_unlisted_or_is_subscribed,
|
||||||
creator_local_user_admin_join,
|
filter_suggested_communities,
|
||||||
filter_is_subscribed,
|
},
|
||||||
filter_not_unlisted_or_is_subscribed,
|
joins::{
|
||||||
image_details_join,
|
creator_community_actions_join,
|
||||||
my_comment_actions_join,
|
creator_home_instance_actions_join,
|
||||||
my_community_actions_join,
|
creator_local_instance_actions_join,
|
||||||
my_local_user_admin_join,
|
creator_local_user_admin_join,
|
||||||
my_person_actions_join,
|
image_details_join,
|
||||||
my_post_actions_join,
|
my_comment_actions_join,
|
||||||
suggested_communities,
|
my_community_actions_join,
|
||||||
|
my_local_user_admin_join,
|
||||||
|
my_person_actions_join,
|
||||||
|
my_post_actions_join,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
seconds_to_pg_interval,
|
seconds_to_pg_interval,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
@ -338,7 +342,7 @@ impl SearchCombinedQuery {
|
||||||
ListingType::ModeratorView => {
|
ListingType::ModeratorView => {
|
||||||
query.filter(community_actions::became_moderator_at.is_not_null())
|
query.filter(community_actions::became_moderator_at.is_not_null())
|
||||||
}
|
}
|
||||||
ListingType::Suggested => query.filter(suggested_communities()),
|
ListingType::Suggested => query.filter(filter_suggested_communities()),
|
||||||
};
|
};
|
||||||
// Filter by the time range
|
// Filter by the time range
|
||||||
if let Some(time_range_seconds) = self.time_range_seconds {
|
if let Some(time_range_seconds) = self.time_range_seconds {
|
||||||
|
@ -430,8 +434,10 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
|
||||||
post_tags: v.post_tags,
|
post_tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
} else if let (Some(post), Some(creator), Some(community)) =
|
} else if let (Some(post), Some(creator), Some(community)) =
|
||||||
(v.post, v.item_creator.clone(), v.community.clone())
|
(v.post, v.item_creator.clone(), v.community.clone())
|
||||||
|
@ -448,8 +454,10 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
|
||||||
tags: v.post_tags,
|
tags: v.post_tags,
|
||||||
can_mod: v.can_mod,
|
can_mod: v.can_mod,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
creator_is_moderator: v.creator_is_moderator,
|
creator_is_moderator: v.creator_is_moderator,
|
||||||
creator_banned_from_community: v.creator_banned_from_community,
|
creator_banned_from_community: v.creator_banned_from_community,
|
||||||
|
creator_community_ban_expires_at: v.creator_community_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
} else if let Some(community) = v.community {
|
} else if let Some(community) = v.community {
|
||||||
Some(SearchCombinedView::Community(CommunityView {
|
Some(SearchCombinedView::Community(CommunityView {
|
||||||
|
@ -469,6 +477,7 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
|
||||||
is_admin: v.item_creator_is_admin,
|
is_admin: v.item_creator_is_admin,
|
||||||
person_actions: v.person_actions,
|
person_actions: v.person_actions,
|
||||||
creator_banned: v.creator_banned,
|
creator_banned: v.creator_banned,
|
||||||
|
creator_ban_expires_at: v.creator_ban_expires_at,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -536,6 +545,7 @@ mod tests {
|
||||||
local_user: timmy_local_user,
|
local_user: timmy_local_user,
|
||||||
person: timmy.clone(),
|
person: timmy.clone(),
|
||||||
banned: false,
|
banned: false,
|
||||||
|
ban_expires_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_form = CommunityInsertForm {
|
let community_form = CommunityInsertForm {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::{CommunityId, PaginationCursor, PersonId},
|
newtypes::{CommunityId, PaginationCursor, PersonId},
|
||||||
source::{
|
source::{
|
||||||
|
@ -23,14 +24,18 @@ use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use {
|
use {
|
||||||
diesel::{Queryable, Selectable},
|
diesel::{Queryable, Selectable},
|
||||||
lemmy_db_schema::utils::queries::{
|
lemmy_db_schema::utils::queries::selects::{
|
||||||
community_post_tags_fragment,
|
community_post_tags_fragment,
|
||||||
creator_banned,
|
creator_ban_expires_from_community,
|
||||||
|
creator_banned_from_community,
|
||||||
creator_is_admin,
|
creator_is_admin,
|
||||||
|
creator_is_moderator,
|
||||||
|
creator_local_home_ban_expires,
|
||||||
|
creator_local_home_banned,
|
||||||
local_user_can_mod,
|
local_user_can_mod,
|
||||||
post_tags_fragment,
|
post_tags_fragment,
|
||||||
|
CreatorLocalHomeBanExpiresType,
|
||||||
},
|
},
|
||||||
lemmy_db_schema::utils::queries::{creator_banned_from_community, creator_is_moderator},
|
|
||||||
lemmy_db_views_local_user::LocalUserView,
|
lemmy_db_views_local_user::LocalUserView,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,10 +97,17 @@ pub(crate) struct SearchCombinedViewInternal {
|
||||||
pub can_mod: bool,
|
pub can_mod: bool,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_banned()
|
select_expression = creator_local_home_banned()
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned: bool,
|
pub creator_banned: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression_type = CreatorLocalHomeBanExpiresType,
|
||||||
|
select_expression = creator_local_home_ban_expires()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
#[cfg_attr(feature = "full",
|
#[cfg_attr(feature = "full",
|
||||||
diesel(
|
diesel(
|
||||||
select_expression = creator_is_moderator()
|
select_expression = creator_is_moderator()
|
||||||
|
@ -108,6 +120,12 @@ pub(crate) struct SearchCombinedViewInternal {
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
|
#[cfg_attr(feature = "full",
|
||||||
|
diesel(
|
||||||
|
select_expression = creator_ban_expires_from_community()
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub creator_community_ban_expires_at: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
|
|
@ -17,9 +17,8 @@ use lemmy_db_schema::{
|
||||||
limit_fetch,
|
limit_fetch,
|
||||||
paginate,
|
paginate,
|
||||||
queries::{
|
queries::{
|
||||||
creator_banned,
|
joins::{creator_home_instance_actions_join, creator_local_instance_actions_join},
|
||||||
creator_home_instance_actions_join,
|
selects::creator_local_home_banned,
|
||||||
creator_local_instance_actions_join,
|
|
||||||
},
|
},
|
||||||
DbPool,
|
DbPool,
|
||||||
},
|
},
|
||||||
|
@ -89,7 +88,7 @@ impl VoteView {
|
||||||
.filter(post_actions::like_score.is_not_null())
|
.filter(post_actions::like_score.is_not_null())
|
||||||
.select((
|
.select((
|
||||||
person::all_columns,
|
person::all_columns,
|
||||||
creator_banned(),
|
creator_local_home_banned(),
|
||||||
creator_community_actions
|
creator_community_actions
|
||||||
.field(community_actions::received_ban_at)
|
.field(community_actions::received_ban_at)
|
||||||
.nullable()
|
.nullable()
|
||||||
|
@ -163,7 +162,7 @@ impl VoteView {
|
||||||
.filter(comment_actions::like_score.is_not_null())
|
.filter(comment_actions::like_score.is_not_null())
|
||||||
.select((
|
.select((
|
||||||
person::all_columns,
|
person::all_columns,
|
||||||
creator_banned(),
|
creator_local_home_banned(),
|
||||||
creator_community_actions
|
creator_community_actions
|
||||||
.field(community_actions::received_ban_at)
|
.field(community_actions::received_ban_at)
|
||||||
.nullable()
|
.nullable()
|
||||||
|
|
Loading…
Reference in a new issue