about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTakeshi Umeda <noel.yoshiba@gmail.com>2019-04-08 14:46:55 +0900
committerEugen Rochko <eugen@zeonfederated.com>2019-04-08 07:46:55 +0200
commit08ba69b53869256098d09dacdced2b3d1c500471 (patch)
tree8cc8d4a983ffac72aa85e9fdc488aeae65ca8902
parentcb71c95e2292730befb8e12cf3b05d09d3e7443b (diff)
Add `tootctl accounts reset-relationships` (#10483)
* Add `tootctl accounts reset`

* Rename reset to reset-relationships

* Improve command description
-rw-r--r--lib/mastodon/accounts_cli.rb67
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb
index 9b25a2ef7..9dc84f1b5 100644
--- a/lib/mastodon/accounts_cli.rb
+++ b/lib/mastodon/accounts_cli.rb
@@ -367,6 +367,73 @@ module Mastodon
       say("OK, unfollowed target from #{processed} accounts, skipped #{failed}", :green)
     end
 
+    option :follows, type: :boolean, default: false
+    option :followers, type: :boolean, default: false
+    desc 'reset-relationships USERNAME', 'Reset all follows and/or followers for a user'
+    long_desc <<-LONG_DESC
+      Reset all follows and/or followers for a user specified by USERNAME.
+
+      With the --follows option, the command unfollows everyone that the account follows,
+      and then re-follows the users that would be followed by a brand new account.
+
+      With the --followers option, the command removes all followers of the account.
+    LONG_DESC
+    def reset_relationships(username)
+      unless options[:follows] || options[:followers]
+        say('Please specify either --follows or --followers, or both', :red)
+        exit(1)
+      end
+
+      account = Account.find_local(username)
+
+      if account.nil?
+        say('No user with such username', :red)
+        exit(1)
+      end
+
+      if options[:follows]
+        processed = 0
+        failed    = 0
+
+        say("Unfollowing #{account.username}'s followees, this might take a while...")
+
+        Account.where(id: ::Follow.where(account: account).select(:target_account_id)).find_each do |target_account|
+          begin
+            UnfollowService.new.call(account, target_account)
+            processed += 1
+            say('.', :green, false)
+          rescue StandardError
+            failed += 1
+            say('.', :red, false)
+          end
+        end
+
+        BootstrapTimelineWorker.perform_async(account.id)
+
+        say("OK, unfollowed #{processed} followees, skipped #{failed}", :green)
+      end
+
+      if options[:followers]
+        processed = 0
+        failed    = 0
+
+        say("Removing #{account.username}'s followers, this might take a while...")
+
+        Account.where(id: ::Follow.where(target_account: account).select(:account_id)).find_each do |target_account|
+          begin
+            UnfollowService.new.call(target_account, account)
+            processed += 1
+            say('.', :green, false)
+          rescue StandardError
+            failed += 1
+            say('.', :red, false)
+          end
+        end
+
+        say("OK, removed #{processed} followers, skipped #{failed}", :green)
+      end
+    end
+
     option :number, type: :numeric, aliases: [:n]
     option :all, type: :boolean
     desc 'approve [USERNAME]', 'Approve pending accounts'