From e6814a332c3b355893d366cf8639ab3c7e30b52b Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Thu, 4 Apr 2019 09:46:27 -0500 Subject: Fix `tootctl accounts cull` (#10460) * List the actual accounts that would have been culled during a dry run. Otherwise, the dry run mode is basically useless. * Prevent unreachable domains from inheriting the previous status code. * Update CHANGELOG.md for #10460. --- lib/mastodon/accounts_cli.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb index f02b2149b..41e902e8f 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/accounts_cli.rb @@ -219,12 +219,14 @@ module Mastodon def cull skip_threshold = 7.days.ago culled = 0 + dry_run_culled = [] skip_domains = Set.new dry_run = options[:dry_run] ? ' (DRY RUN)' : '' Account.remote.where(protocol: :activitypub).partitioned.find_each do |account| next if account.updated_at >= skip_threshold || (account.last_webfingered_at.present? && account.last_webfingered_at >= skip_threshold) + code = 0 unless skip_domains.include?(account.domain) begin code = Request.new(:head, account.uri).perform(&:code) @@ -236,7 +238,11 @@ module Mastodon end if [404, 410].include?(code) - SuspendAccountService.new.call(account, destroy: true) unless options[:dry_run] + if options[:dry_run] + dry_run_culled << account.acct + else + SuspendAccountService.new.call(account, destroy: true) + end culled += 1 say('+', :green, false) else @@ -252,6 +258,11 @@ module Mastodon say('The following servers were not available during the check:', :yellow) skip_domains.each { |domain| say(' ' + domain) } end + + unless dry_run_culled.empty? + say('The following accounts would have been deleted:', :green) + dry_run_culled.each { |account| say(' ' + account) } + end end option :all, type: :boolean -- cgit From e007c7a99b2ef9903a3aad5ff67902e9fd10b232 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 6 Apr 2019 04:47:05 +0200 Subject: Add `tootctl accounts approve` (#10480) --- lib/mastodon/accounts_cli.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'lib') diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb index 41e902e8f..9b25a2ef7 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/accounts_cli.rb @@ -367,6 +367,37 @@ module Mastodon say("OK, unfollowed target from #{processed} accounts, skipped #{failed}", :green) end + option :number, type: :numeric, aliases: [:n] + option :all, type: :boolean + desc 'approve [USERNAME]', 'Approve pending accounts' + long_desc <<~LONG_DESC + When registrations require review from staff, approve pending accounts, + either all of them with the --all option, or a specific number of them + specified with the --number (-n) option, or only a single specific + account identified by its username. + LONG_DESC + def approve(username = nil) + if options[:all] + User.pending.find_each(&:approve!) + say('OK', :green) + elsif options[:number] + User.pending.limit(options[:number]).each(&:approve!) + say('OK', :green) + elsif username.present? + account = Account.find_local(username) + + if account.nil? + say('No such account', :red) + exit(1) + end + + account.user&.approve! + say('OK', :green) + else + exit(1) + end + end + private def rotate_keys_for_account(account, delay = 0) -- cgit From 6689e572f308933742e0df6f55e2ac81ca178865 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 6 Apr 2019 04:47:16 +0200 Subject: Add `tootctl emoji purge` (#10481) Fix #10441 --- lib/mastodon/emoji_cli.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/emoji_cli.rb index 2262040d4..32827dd45 100644 --- a/lib/mastodon/emoji_cli.rb +++ b/lib/mastodon/emoji_cli.rb @@ -66,6 +66,12 @@ module Mastodon say("Imported #{imported}, skipped #{skipped}, failed to import #{failed}", color(imported, skipped, failed)) end + desc 'purge', 'Remove all custom emoji' + def purge + CustomEmoji.in_batches.destroy_all + say('OK', :green) + end + private def color(green, _yellow, red) -- cgit From 20d301c383c0789ec192a2c86f2df4464c99f457 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 6 Apr 2019 04:47:26 +0200 Subject: Fix missing long description on `tootctl statuses remove` (#10482) --- lib/mastodon/statuses_cli.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mastodon/statuses_cli.rb b/lib/mastodon/statuses_cli.rb index 5881ba260..7f2fbfa85 100644 --- a/lib/mastodon/statuses_cli.rb +++ b/lib/mastodon/statuses_cli.rb @@ -13,7 +13,15 @@ module Mastodon end option :days, type: :numeric, default: 90 - desc 'remove', 'Remove statuses' + desc 'remove', 'Remove unreferenced statuses' + long_desc <<~LONG_DESC + Remove statuses that are not referenced by local user activity, such as + ones that came from relays, or belonging to users that were once followed + by someone locally but no longer are. + + This is a computationally heavy procedure that creates extra database + indicides before commencing, and removes them afterward. + LONG_DESC def remove say('Creating temporary database indices...') -- cgit From 08ba69b53869256098d09dacdced2b3d1c500471 Mon Sep 17 00:00:00 2001 From: Takeshi Umeda Date: Mon, 8 Apr 2019 14:46:55 +0900 Subject: Add `tootctl accounts reset-relationships` (#10483) * Add `tootctl accounts reset` * Rename reset to reset-relationships * Improve command description --- lib/mastodon/accounts_cli.rb | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'lib') 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' -- cgit