]> Untitled Git - lemmy.git/commitdiff
Mark accounts as bot nutomic (#1565)
authorNutomic <me@nutomic.com>
Wed, 21 Apr 2021 21:41:14 +0000 (21:41 +0000)
committerGitHub <noreply@github.com>
Wed, 21 Apr 2021 21:41:14 +0000 (17:41 -0400)
* Mark account as bot. Fixes #1357

* Fix clippy

* Federate bot status using actor `type` field

* fix clippy

Co-authored-by: Dessalines <tyhou13@gmx.com>
20 files changed:
crates/api/src/local_user.rs
crates/api/src/site.rs
crates/api_common/src/lib.rs
crates/api_common/src/person.rs
crates/api_crud/src/comment/read.rs
crates/api_crud/src/post/read.rs
crates/api_crud/src/user/create.rs
crates/api_crud/src/user/read.rs
crates/apub/src/lib.rs
crates/apub/src/objects/person.rs
crates/db_queries/src/source/local_user.rs
crates/db_queries/src/source/person.rs
crates/db_schema/src/schema.rs
crates/db_schema/src/source/local_user.rs
crates/db_schema/src/source/person.rs
crates/db_views/src/comment_view.rs
crates/db_views/src/post_view.rs
crates/routes/src/feeds.rs
migrations/2021-03-31-105915_add_bot_account/down.sql [new file with mode: 0644]
migrations/2021-03-31-105915_add_bot_account/up.sql [new file with mode: 0644]

index 241e3405f4e4543cbf3c10f53f3be08cfbce550d..b273b58208c888b56dc98b9322e92ec67b248709 100644 (file)
@@ -169,6 +169,7 @@ impl Perform for SaveUserSettings {
     let bio = diesel_option_overwrite(&data.bio);
     let display_name = diesel_option_overwrite(&data.display_name);
     let matrix_user_id = diesel_option_overwrite(&data.matrix_user_id);
+    let bot_account = data.bot_account;
 
     if let Some(Some(bio)) = &bio {
       if bio.chars().count() > 300 {
@@ -213,6 +214,7 @@ impl Perform for SaveUserSettings {
       last_refreshed_at: None,
       shared_inbox_url: None,
       matrix_user_id,
+      bot_account,
     };
 
     let person_res = blocking(context.pool(), move |conn| {
@@ -231,6 +233,7 @@ impl Perform for SaveUserSettings {
       email,
       password_encrypted,
       show_nsfw: data.show_nsfw,
+      show_bot_accounts: data.show_bot_accounts,
       show_scores: data.show_scores,
       theme: data.theme.to_owned(),
       default_sort_type,
@@ -465,11 +468,14 @@ impl Perform for GetReplies {
     let limit = data.limit;
     let unread_only = data.unread_only;
     let person_id = local_user_view.person.id;
+    let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
+
     let replies = blocking(context.pool(), move |conn| {
       CommentQueryBuilder::create(conn)
         .sort(&sort)
         .unread_only(unread_only)
         .recipient_id(person_id)
+        .show_bot_accounts(show_bot_accounts)
         .my_person_id(person_id)
         .page(page)
         .limit(limit)
index cc61b520688e9e02af8c3d17b75dc2d086f9ba71..aae400ca7464188a48ef8778567280ac4b5cc140 100644 (file)
@@ -9,6 +9,8 @@ use lemmy_api_common::{
   get_local_user_view_from_jwt_opt,
   is_admin,
   site::*,
+  user_show_bot_accounts,
+  user_show_nsfw,
 };
 use lemmy_apub::fetcher::search::search_by_apub_id;
 use lemmy_db_queries::{source::site::Site_, Crud, SearchType, SortType};
@@ -136,6 +138,10 @@ impl Perform for Search {
     }
 
     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+
+    let show_nsfw = user_show_nsfw(&local_user_view);
+    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
+
     let person_id = local_user_view.map(|u| u.person.id);
 
     let type_ = SearchType::from_str(&data.type_)?;
@@ -158,7 +164,8 @@ impl Perform for Search {
         posts = blocking(context.pool(), move |conn| {
           PostQueryBuilder::create(conn)
             .sort(&sort)
-            .show_nsfw(true)
+            .show_nsfw(show_nsfw)
+            .show_bot_accounts(show_bot_accounts)
             .community_id(community_id)
             .community_name(community_name)
             .my_person_id(person_id)
@@ -174,6 +181,7 @@ impl Perform for Search {
           CommentQueryBuilder::create(&conn)
             .sort(&sort)
             .search_term(q)
+            .show_bot_accounts(show_bot_accounts)
             .my_person_id(person_id)
             .page(page)
             .limit(limit)
@@ -208,7 +216,8 @@ impl Perform for Search {
         posts = blocking(context.pool(), move |conn| {
           PostQueryBuilder::create(conn)
             .sort(&sort)
-            .show_nsfw(true)
+            .show_nsfw(show_nsfw)
+            .show_bot_accounts(show_bot_accounts)
             .community_id(community_id)
             .community_name(community_name)
             .my_person_id(person_id)
@@ -226,6 +235,7 @@ impl Perform for Search {
           CommentQueryBuilder::create(conn)
             .sort(&sort)
             .search_term(q)
+            .show_bot_accounts(show_bot_accounts)
             .my_person_id(person_id)
             .page(page)
             .limit(limit)
@@ -264,7 +274,8 @@ impl Perform for Search {
         posts = blocking(context.pool(), move |conn| {
           PostQueryBuilder::create(conn)
             .sort(&sort)
-            .show_nsfw(true)
+            .show_nsfw(show_nsfw)
+            .show_bot_accounts(show_bot_accounts)
             .my_person_id(person_id)
             .community_id(community_id)
             .community_name(community_name)
index dca09b97e8a473f04da5d41c0d7325d4a4b8dc93..1a644b7d4d775745de63bb1d14fe1c604b9e54cb 100644 (file)
@@ -236,6 +236,22 @@ pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
   Ok(())
 }
 
+/// A helper method for showing the bot account
+pub fn user_show_bot_accounts(local_user_view: &Option<LocalUserView>) -> bool {
+  match local_user_view {
+    Some(uv) => uv.to_owned().local_user.show_bot_accounts,
+    None => true,
+  }
+}
+
+/// A helper method for showing nsfw
+pub fn user_show_nsfw(local_user_view: &Option<LocalUserView>) -> bool {
+  match &local_user_view {
+    Some(uv) => uv.local_user.show_nsfw,
+    None => false,
+  }
+}
+
 pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result<Post, LemmyError> {
   blocking(pool, move |conn| Post::read(conn, post_id))
     .await?
index fc061a35bc565e51ef4c5ed5e61a294f4a3229c6..5473a482017459fd124fae95b956459a5e159d8b 100644 (file)
@@ -60,6 +60,8 @@ pub struct SaveUserSettings {
   pub matrix_user_id: Option<String>,
   pub show_avatars: Option<bool>,
   pub send_notifications_to_email: Option<bool>,
+  pub bot_account: Option<bool>,
+  pub show_bot_accounts: Option<bool>,
   pub auth: String,
 }
 
index 17f3a57d106c31d6efe052efb54b7b7da53f801f..4d144382089688aa2b1a2eeb137941b4dad884b1 100644 (file)
@@ -1,6 +1,11 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
-use lemmy_api_common::{blocking, comment::*, get_local_user_view_from_jwt_opt};
+use lemmy_api_common::{
+  blocking,
+  comment::*,
+  get_local_user_view_from_jwt_opt,
+  user_show_bot_accounts,
+};
 use lemmy_db_queries::{ListingType, SortType};
 use lemmy_db_views::comment_view::CommentQueryBuilder;
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
@@ -18,6 +23,8 @@ impl PerformCrud for GetComments {
   ) -> Result<GetCommentsResponse, LemmyError> {
     let data: &GetComments = &self;
     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+
+    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
     let person_id = local_user_view.map(|u| u.person.id);
 
     let type_ = ListingType::from_str(&data.type_)?;
@@ -36,6 +43,7 @@ impl PerformCrud for GetComments {
         .community_id(community_id)
         .community_name(community_name)
         .my_person_id(person_id)
+        .show_bot_accounts(show_bot_accounts)
         .page(page)
         .limit(limit)
         .list()
index 32388910180521b4ea594c3428588e19eb555577..d2231d24b5e2cfe5ad6838a186ded5f74a807538 100644 (file)
@@ -1,6 +1,12 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
-use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, post::*};
+use lemmy_api_common::{
+  blocking,
+  get_local_user_view_from_jwt_opt,
+  post::*,
+  user_show_bot_accounts,
+  user_show_nsfw,
+};
 use lemmy_db_queries::{ListingType, SortType};
 use lemmy_db_views::{
   comment_view::CommentQueryBuilder,
@@ -25,6 +31,9 @@ impl PerformCrud for GetPost {
   ) -> Result<GetPostResponse, LemmyError> {
     let data: &GetPost = &self;
     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
+
+    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
+
     let person_id = local_user_view.map(|u| u.person.id);
 
     let id = data.id;
@@ -38,6 +47,7 @@ impl PerformCrud for GetPost {
     let comments = blocking(context.pool(), move |conn| {
       CommentQueryBuilder::create(conn)
         .my_person_id(person_id)
+        .show_bot_accounts(show_bot_accounts)
         .post_id(id)
         .limit(9999)
         .list()
@@ -88,10 +98,8 @@ impl PerformCrud for GetPosts {
 
     let person_id = local_user_view.to_owned().map(|l| l.person.id);
 
-    let show_nsfw = match &local_user_view {
-      Some(uv) => uv.local_user.show_nsfw,
-      None => false,
-    };
+    let show_nsfw = user_show_nsfw(&local_user_view);
+    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
 
     let type_ = ListingType::from_str(&data.type_)?;
     let sort = SortType::from_str(&data.sort)?;
@@ -107,6 +115,7 @@ impl PerformCrud for GetPosts {
         .listing_type(&type_)
         .sort(&sort)
         .show_nsfw(show_nsfw)
+        .show_bot_accounts(show_bot_accounts)
         .community_id(community_id)
         .community_name(community_name)
         .saved_only(saved_only)
index be9fdbed9aaa5cd6e6c8e9983f1902b8bf4427aa..0975555617d7d4f64d6102e5ccd1fe8c1a7c031c 100644 (file)
@@ -123,6 +123,7 @@ impl PerformCrud for Register {
       email: Some(data.email.to_owned()),
       password_encrypted: data.password.to_owned(),
       show_nsfw: Some(data.show_nsfw),
+      show_bot_accounts: Some(true),
       theme: Some("browser".into()),
       default_sort_type: Some(SortType::Active as i16),
       default_listing_type: Some(ListingType::Subscribed as i16),
index 710bccb755aa74c90b8f9306192d7b2e9c0b35e9..24ac2f61e3610ea2d55543a756a7d3b74510c743 100644 (file)
@@ -1,6 +1,12 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
-use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*};
+use lemmy_api_common::{
+  blocking,
+  get_local_user_view_from_jwt_opt,
+  person::*,
+  user_show_bot_accounts,
+  user_show_nsfw,
+};
 use lemmy_db_queries::{source::person::Person_, SortType};
 use lemmy_db_schema::source::person::*;
 use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
@@ -25,10 +31,8 @@ impl PerformCrud for GetPersonDetails {
     let data: &GetPersonDetails = &self;
     let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
 
-    let show_nsfw = match &local_user_view {
-      Some(uv) => uv.local_user.show_nsfw,
-      None => false,
-    };
+    let show_nsfw = user_show_nsfw(&local_user_view);
+    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
 
     let sort = SortType::from_str(&data.sort)?;
 
@@ -67,6 +71,7 @@ impl PerformCrud for GetPersonDetails {
       let mut posts_query = PostQueryBuilder::create(conn)
         .sort(&sort)
         .show_nsfw(show_nsfw)
+        .show_bot_accounts(show_bot_accounts)
         .saved_only(saved_only)
         .community_id(community_id)
         .my_person_id(person_id)
@@ -75,6 +80,7 @@ impl PerformCrud for GetPersonDetails {
 
       let mut comments_query = CommentQueryBuilder::create(conn)
         .my_person_id(person_id)
+        .show_bot_accounts(show_bot_accounts)
         .sort(&sort)
         .saved_only(saved_only)
         .community_id(community_id)
index 394de73bbc943de32e0caa91243f3ca1414e9a40..fe63d4d58d9b0ee487ee647636f86e6f881d9c9e 100644 (file)
@@ -50,11 +50,18 @@ use url::{ParseError, Url};
 pub type GroupExt =
   Ext2<actor::ApActor<ApObject<actor::Group>>, GroupExtension, PublicKeyExtension>;
 /// Activitystreams type for person
-type PersonExt = Ext2<actor::ApActor<ApObject<actor::Person>>, PersonExtension, PublicKeyExtension>;
+type PersonExt =
+  Ext2<actor::ApActor<ApObject<actor::Actor<UserTypes>>>, PersonExtension, PublicKeyExtension>;
 /// Activitystreams type for post
 pub type PageExt = Ext1<ApObject<Page>, PageExtension>;
 pub type NoteExt = ApObject<Note>;
 
+#[derive(Clone, Copy, Debug, serde::Deserialize, serde::Serialize, PartialEq)]
+pub enum UserTypes {
+  Person,
+  Service,
+}
+
 pub static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json";
 
 /// Checks if the ID is allowed for sending or receiving.
index 34146dc25ea97bcc87a685b3dcf62b7bf4fa2b57..a508f4e088e872bb785dce1a3f659514a9527500 100644 (file)
@@ -10,11 +10,12 @@ use crate::{
   },
   ActorType,
   PersonExt,
+  UserTypes,
 };
 use activitystreams::{
-  actor::{ApActor, Endpoints, Person},
-  object::{ApObject, Image, Tombstone},
-  prelude::*,
+  actor::{Actor, ApActor, ApActorExt, Endpoints},
+  base::{BaseExt, ExtendsExt},
+  object::{ApObject, Image, Object, ObjectExt, Tombstone},
 };
 use activitystreams_ext::Ext2;
 use anyhow::Context;
@@ -38,7 +39,16 @@ impl ToApub for DbPerson {
   type ApubType = PersonExt;
 
   async fn to_apub(&self, _pool: &DbPool) -> Result<PersonExt, LemmyError> {
-    let mut person = ApObject::new(Person::new());
+    let object = Object::<UserTypes>::new_none_type();
+    let mut actor = Actor(object);
+    let kind = if self.bot_account {
+      UserTypes::Service
+    } else {
+      UserTypes::Person
+    };
+    actor.set_kind(kind);
+    let mut person = ApObject::new(actor);
+
     person
       .set_many_contexts(lemmy_context()?)
       .set_id(self.actor_id.to_owned().into_inner())
@@ -193,6 +203,7 @@ impl FromApubToForm<PersonExt> for PersonForm {
       bio: Some(bio),
       local: Some(false),
       admin: Some(false),
+      bot_account: Some(person.inner.is_kind(&UserTypes::Service)),
       private_key: None,
       public_key: Some(Some(person.ext_two.public_key.to_owned().public_key_pem)),
       last_refreshed_at: Some(naive_now()),
index d1fad2e8523ff8c8566c49ee0ff6497a29ff2bd8..43a5c7727565fd60a66833a116569c777915f159 100644 (file)
@@ -24,6 +24,7 @@ mod safe_settings_type {
     show_avatars,
     send_notifications_to_email,
     validator_time,
+    show_bot_accounts,
     show_scores,
   );
 
@@ -44,6 +45,7 @@ mod safe_settings_type {
         show_avatars,
         send_notifications_to_email,
         validator_time,
+        show_bot_accounts,
         show_scores,
       )
     }
index 2d332bd01eccd5d866283263ccb59ff66157603c..4624ae191826a43f0ef5344c6dc6c269b99a48b8 100644 (file)
@@ -29,6 +29,7 @@ mod safe_type {
     shared_inbox_url,
     matrix_user_id,
     admin,
+    bot_account,
   );
 
   impl ToSafe for Person {
@@ -51,6 +52,7 @@ mod safe_type {
         shared_inbox_url,
         matrix_user_id,
         admin,
+        bot_account,
       )
     }
   }
@@ -77,6 +79,7 @@ mod safe_type_alias_1 {
     shared_inbox_url,
     matrix_user_id,
     admin,
+    bot_account,
   );
 
   impl ToSafe for PersonAlias1 {
@@ -99,6 +102,7 @@ mod safe_type_alias_1 {
         shared_inbox_url,
         matrix_user_id,
         admin,
+        bot_account,
       )
     }
   }
@@ -125,6 +129,7 @@ mod safe_type_alias_2 {
     shared_inbox_url,
     matrix_user_id,
     admin,
+    bot_account,
   );
 
   impl ToSafe for PersonAlias2 {
@@ -147,6 +152,7 @@ mod safe_type_alias_2 {
         shared_inbox_url,
         matrix_user_id,
         admin,
+        bot_account,
       )
     }
   }
@@ -274,6 +280,7 @@ mod tests {
       actor_id: inserted_person.actor_id.to_owned(),
       bio: None,
       local: true,
+      bot_account: false,
       admin: false,
       private_key: None,
       public_key: None,
index 9b05d29ab0364cea80bb7e8664d9cf6ee35126f5..f92e43f72d5efba3f09040e1c1e277650ea37218 100644 (file)
@@ -153,6 +153,7 @@ table! {
         show_avatars -> Bool,
         send_notifications_to_email -> Bool,
         validator_time -> Timestamp,
+        show_bot_accounts -> Bool,
         show_scores -> Bool,
     }
 }
@@ -287,6 +288,7 @@ table! {
         shared_inbox_url -> Nullable<Varchar>,
         matrix_user_id -> Nullable<Text>,
         admin -> Bool,
+        bot_account -> Bool,
     }
 }
 
@@ -488,6 +490,7 @@ table! {
         shared_inbox_url -> Nullable<Varchar>,
         matrix_user_id -> Nullable<Text>,
         admin -> Bool,
+        bot_account -> Bool,
     }
 }
 
@@ -512,6 +515,7 @@ table! {
         shared_inbox_url -> Nullable<Varchar>,
         matrix_user_id -> Nullable<Text>,
         admin -> Bool,
+        bot_account -> Bool,
     }
 }
 
index 0a7181fdbef57d36bade01a67d46c8808d9e1dd4..64afb49a425b5e2c34eec5ed618120aac0a08b48 100644 (file)
@@ -16,6 +16,7 @@ pub struct LocalUser {
   pub show_avatars: bool,
   pub send_notifications_to_email: bool,
   pub validator_time: chrono::NaiveDateTime,
+  pub show_bot_accounts: bool,
   pub show_scores: bool,
 }
 
@@ -33,6 +34,7 @@ pub struct LocalUserForm {
   pub lang: Option<String>,
   pub show_avatars: Option<bool>,
   pub send_notifications_to_email: Option<bool>,
+  pub show_bot_accounts: Option<bool>,
   pub show_scores: Option<bool>,
 }
 
@@ -51,5 +53,6 @@ pub struct LocalUserSettings {
   pub show_avatars: bool,
   pub send_notifications_to_email: bool,
   pub validator_time: chrono::NaiveDateTime,
+  pub show_bot_accounts: bool,
   pub show_scores: bool,
 }
index be1ce268f7d5bc4f4bc525ca4851cb2c1850b480..965378616b139133044874a40cf62013314d7d8b 100644 (file)
@@ -27,6 +27,7 @@ pub struct Person {
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
   pub admin: bool,
+  pub bot_account: bool,
 }
 
 /// A safe representation of person, without the sensitive info
@@ -49,6 +50,7 @@ pub struct PersonSafe {
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
   pub admin: bool,
+  pub bot_account: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -73,6 +75,7 @@ pub struct PersonAlias1 {
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
   pub admin: bool,
+  pub bot_account: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -94,6 +97,7 @@ pub struct PersonSafeAlias1 {
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
   pub admin: bool,
+  pub bot_account: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -118,6 +122,7 @@ pub struct PersonAlias2 {
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
   pub admin: bool,
+  pub bot_account: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -139,6 +144,7 @@ pub struct PersonSafeAlias2 {
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
   pub admin: bool,
+  pub bot_account: bool,
 }
 
 #[derive(Insertable, AsChangeset, Clone, Default)]
@@ -162,4 +168,5 @@ pub struct PersonForm {
   pub shared_inbox_url: Option<Option<DbUrl>>,
   pub matrix_user_id: Option<Option<String>>,
   pub admin: Option<bool>,
+  pub bot_account: Option<bool>,
 }
index fd2debf2c050d7f1c0c425a57e71e55cdce2c822..b85b1c77a654d38a544458e1d9890f989ab88d78 100644 (file)
@@ -183,6 +183,7 @@ pub struct CommentQueryBuilder<'a> {
   search_term: Option<String>,
   saved_only: bool,
   unread_only: bool,
+  show_bot_accounts: bool,
   page: Option<i64>,
   limit: Option<i64>,
 }
@@ -202,6 +203,7 @@ impl<'a> CommentQueryBuilder<'a> {
       search_term: None,
       saved_only: false,
       unread_only: false,
+      show_bot_accounts: true,
       page: None,
       limit: None,
     }
@@ -262,6 +264,11 @@ impl<'a> CommentQueryBuilder<'a> {
     self
   }
 
+  pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self {
+    self.show_bot_accounts = show_bot_accounts;
+    self
+  }
+
   pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
     self.page = page.get_optional();
     self
@@ -380,6 +387,10 @@ impl<'a> CommentQueryBuilder<'a> {
       query = query.filter(comment_saved::id.is_not_null());
     }
 
+    if !self.show_bot_accounts {
+      query = query.filter(person::bot_account.eq(false));
+    };
+
     query = match self.sort {
       SortType::Hot | SortType::Active => query
         .order_by(hot_rank(comment_aggregates::score, comment_aggregates::published).desc())
@@ -526,6 +537,7 @@ mod tests {
         banned: false,
         deleted: false,
         admin: false,
+        bot_account: false,
         bio: None,
         banner: None,
         updated: None,
index a6843416eed1fa731a1226dc09932f92d285d8be..8248bfd292d19c585b360088250f1a764ba39fce 100644 (file)
@@ -164,6 +164,7 @@ pub struct PostQueryBuilder<'a> {
   search_term: Option<String>,
   url_search: Option<String>,
   show_nsfw: bool,
+  show_bot_accounts: bool,
   saved_only: bool,
   unread_only: bool,
   page: Option<i64>,
@@ -183,6 +184,7 @@ impl<'a> PostQueryBuilder<'a> {
       search_term: None,
       url_search: None,
       show_nsfw: true,
+      show_bot_accounts: true,
       saved_only: false,
       unread_only: false,
       page: None,
@@ -235,6 +237,11 @@ impl<'a> PostQueryBuilder<'a> {
     self
   }
 
+  pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self {
+    self.show_bot_accounts = show_bot_accounts;
+    self
+  }
+
   pub fn saved_only(mut self, saved_only: bool) -> Self {
     self.saved_only = saved_only;
     self
@@ -351,6 +358,10 @@ impl<'a> PostQueryBuilder<'a> {
         .filter(community::nsfw.eq(false));
     };
 
+    if !self.show_bot_accounts {
+      query = query.filter(person::bot_account.eq(false));
+    };
+
     // TODO  These two might be wrong
     if self.saved_only {
       query = query.filter(post_saved::id.is_not_null());
@@ -451,6 +462,7 @@ mod tests {
     let person_name = "tegan".to_string();
     let community_name = "test_community_3".to_string();
     let post_name = "test post 3".to_string();
+    let bot_post_name = "test bot post".to_string();
 
     let new_person = PersonForm {
       name: person_name.to_owned(),
@@ -459,6 +471,14 @@ mod tests {
 
     let inserted_person = Person::create(&conn, &new_person).unwrap();
 
+    let new_bot = PersonForm {
+      name: person_name.to_owned(),
+      bot_account: Some(true),
+      ..PersonForm::default()
+    };
+
+    let inserted_bot = Person::create(&conn, &new_bot).unwrap();
+
     let new_community = CommunityForm {
       name: community_name.to_owned(),
       title: "nada".to_owned(),
@@ -476,6 +496,15 @@ mod tests {
 
     let inserted_post = Post::create(&conn, &new_post).unwrap();
 
+    let new_bot_post = PostForm {
+      name: bot_post_name,
+      creator_id: inserted_bot.id,
+      community_id: inserted_community.id,
+      ..PostForm::default()
+    };
+
+    let _inserted_bot_post = Post::create(&conn, &new_bot_post).unwrap();
+
     let post_like_form = PostLikeForm {
       post_id: inserted_post.id,
       person_id: inserted_person.id,
@@ -495,6 +524,7 @@ mod tests {
     let read_post_listings_with_person = PostQueryBuilder::create(&conn)
       .listing_type(&ListingType::Community)
       .sort(&SortType::New)
+      .show_bot_accounts(false)
       .community_id(inserted_community.id)
       .my_person_id(inserted_person.id)
       .list()
@@ -546,6 +576,7 @@ mod tests {
         actor_id: inserted_person.actor_id.to_owned(),
         local: true,
         admin: false,
+        bot_account: false,
         banned: false,
         deleted: false,
         bio: None,
@@ -596,6 +627,7 @@ mod tests {
     let num_deleted = Post::delete(&conn, inserted_post.id).unwrap();
     Community::delete(&conn, inserted_community.id).unwrap();
     Person::delete(&conn, inserted_person.id).unwrap();
+    Person::delete(&conn, inserted_bot.id).unwrap();
 
     // The with user
     assert_eq!(
@@ -606,18 +638,20 @@ mod tests {
       expected_post_listing_with_user,
       read_post_listing_with_person
     );
+
+    // Should be only one person, IE the bot post should be missing
     assert_eq!(1, read_post_listings_with_person.len());
 
     // Without the user
     assert_eq!(
       expected_post_listing_no_person,
-      read_post_listings_no_person[0]
+      read_post_listings_no_person[1]
     );
     assert_eq!(expected_post_listing_no_person, read_post_listing_no_person);
-    assert_eq!(1, read_post_listings_no_person.len());
 
-    // assert_eq!(expected_post, inserted_post);
-    // assert_eq!(expected_post, updated_post);
+    // Should be 2 posts, with the bot post
+    assert_eq!(2, read_post_listings_no_person.len());
+
     assert_eq!(expected_post_like, inserted_post_like);
     assert_eq!(1, like_removed);
     assert_eq!(1, num_deleted);
index 9181a129bb65c579979a8a270deba8e23f924731..21263fd610e1aa69639e7150ba468b571bf6d714 100644 (file)
@@ -228,11 +228,14 @@ fn get_feed_front(
 ) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(&conn)?;
   let local_user_id = LocalUserId(Claims::decode(&jwt)?.claims.sub);
-  let person_id = LocalUser::read(&conn, local_user_id)?.person_id;
+  let local_user = LocalUser::read(&conn, local_user_id)?;
+  let person_id = local_user.person_id;
+  let show_bot_accounts = local_user.show_bot_accounts;
 
   let posts = PostQueryBuilder::create(&conn)
     .listing_type(&ListingType::Subscribed)
     .my_person_id(person_id)
+    .show_bot_accounts(show_bot_accounts)
     .sort(sort_type)
     .list()?;
 
@@ -255,13 +258,16 @@ fn get_feed_front(
 fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result<ChannelBuilder, LemmyError> {
   let site_view = SiteView::read(&conn)?;
   let local_user_id = LocalUserId(Claims::decode(&jwt)?.claims.sub);
-  let person_id = LocalUser::read(&conn, local_user_id)?.person_id;
+  let local_user = LocalUser::read(&conn, local_user_id)?;
+  let person_id = local_user.person_id;
+  let show_bot_accounts = local_user.show_bot_accounts;
 
   let sort = SortType::New;
 
   let replies = CommentQueryBuilder::create(&conn)
     .recipient_id(person_id)
     .my_person_id(person_id)
+    .show_bot_accounts(show_bot_accounts)
     .sort(&sort)
     .list()?;
 
diff --git a/migrations/2021-03-31-105915_add_bot_account/down.sql b/migrations/2021-03-31-105915_add_bot_account/down.sql
new file mode 100644 (file)
index 0000000..4f407ce
--- /dev/null
@@ -0,0 +1,6 @@
+drop view person_alias_1, person_alias_2;
+alter table person drop column bot_account;
+create view person_alias_1 as select * from person;
+create view person_alias_2 as select * from person;
+
+alter table local_user drop column show_bot_accounts;
diff --git a/migrations/2021-03-31-105915_add_bot_account/up.sql b/migrations/2021-03-31-105915_add_bot_account/up.sql
new file mode 100644 (file)
index 0000000..a1e207a
--- /dev/null
@@ -0,0 +1,8 @@
+-- Add the bot_account column to the person table
+drop view person_alias_1, person_alias_2;
+alter table person add column bot_account boolean not null default false;
+create view person_alias_1 as select * from person;
+create view person_alias_2 as select * from person;
+
+-- Add the show_bot_accounts to the local user table as a setting
+alter table local_user add column show_bot_accounts boolean not null default true;