Skip to content
Extraits de code Groupes Projets
Non vérifiée Valider f8443868 rédigé par Eugen Rochko's avatar Eugen Rochko Validation de GitHub
Parcourir les fichiers

Add `tootctl accounts merge` (#15201)


* Add `tootctl accounts merge`

* Update lib/mastodon/accounts_cli.rb

Co-authored-by: default avatarYamagishi Kazutoshi <ykzts@desire.sh>

Co-authored-by: default avatarYamagishi Kazutoshi <ykzts@desire.sh>
parent a2da0262
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -67,6 +67,7 @@ class Account < ApplicationRecord
include Paginable
include AccountCounters
include DomainNormalizable
include AccountMerging
TRUST_LEVELS = {
untrusted: 0,
......
# frozen_string_literal: true
module AccountMerging
extend ActiveSupport::Concern
def merge_with!(other_account)
# Since it's the same remote resource, the remote resource likely
# already believes we are following/blocking, so it's safe to
# re-attribute the relationships too. However, during the presence
# of the index bug users could have *also* followed the reference
# account already, therefore mass update will not work and we need
# to check for (and skip past) uniqueness errors
owned_classes = [
Status, StatusPin, MediaAttachment, Poll, Report, Tombstone, Favourite,
Follow, FollowRequest, Block, Mute, AccountIdentityProof,
AccountModerationNote, AccountPin, AccountStat, ListAccount,
PollVote, Mention
]
owned_classes.each do |klass|
klass.where(account_id: other_account.id).find_each do |record|
begin
record.update_attribute(:account_id, id)
rescue ActiveRecord::RecordNotUnique
next
end
end
end
target_classes = [Follow, FollowRequest, Block, Mute, AccountModerationNote, AccountPin]
target_classes.each do |klass|
klass.where(target_account_id: other_account.id).find_each do |record|
begin
record.update_attribute(:target_account_id, id)
rescue ActiveRecord::RecordNotUnique
next
end
end
end
end
end
......@@ -196,6 +196,46 @@ module Mastodon
say('OK', :green)
end
option :force, type: :boolean, aliases: [:f], description: 'Override public key check'
desc 'merge FROM TO', 'Merge two remote accounts into one'
long_desc <<-LONG_DESC
Merge two remote accounts specified by their username@domain
into one, whereby the TO account is the one being merged into
and kept, while the FROM one is removed. It is primarily meant
to fix duplicates caused by other servers changing their domain.
The command by default only works if both accounts have the same
public key to prevent mistakes. To override this, use the --force.
LONG_DESC
def merge(from_acct, to_acct)
username, domain = from_acct.split('@')
from_account = Account.find_remote(username, domain)
if from_account.nil? || from_account.local?
say("No such account (#{from_acct})", :red)
exit(1)
end
username, domain = to_acct.split('@')
to_account = Account.find_remote(username, domain)
if to_account.nil? || to_account.local?
say("No such account (#{to_acct})", :red)
exit(1)
end
if from_account.public_key != to_account.public_key && !options[:force]
say("Accounts don't have the same public key, might not be duplicates!", :red)
say('Override with --force', :red)
exit(1)
end
to_account.merge_with!(from_account)
from_account.destroy
say('OK', :green)
end
desc 'backup USERNAME', 'Request a backup for a user'
long_desc <<-LONG_DESC
Request a new backup for an account with a given USERNAME.
......@@ -335,7 +375,8 @@ module Mastodon
option :verbose, type: :boolean, aliases: [:v]
desc 'unfollow ACCT', 'Make all local accounts unfollow account specified by ACCT'
def unfollow(acct)
target_account = Account.find_remote(*acct.split('@'))
username, domain = acct.split('@')
target_account = Account.find_remote(username, domain)
if target_account.nil?
say('No such account', :red)
......
......@@ -476,48 +476,13 @@ module Mastodon
if other_account.public_key == reference_account.public_key
# The accounts definitely point to the same resource, so
# it's safe to re-attribute content and relationships
merge_accounts!(reference_account, other_account)
reference_account.merge_with!(other_account)
end
other_account.destroy
end
end
def merge_accounts!(main_account, duplicate_account)
# Since it's the same remote resource, the remote resource likely
# already believes we are following/blocking, so it's safe to
# re-attribute the relationships too. However, during the presence
# of the index bug users could have *also* followed the reference
# account already, therefore mass update will not work and we need
# to check for (and skip past) uniqueness errors
owned_classes = [
Status, StatusPin, MediaAttachment, Poll, Report, Tombstone, Favourite,
Follow, FollowRequest, Block, Mute, AccountIdentityProof,
AccountModerationNote, AccountPin, AccountStat, ListAccount,
PollVote, Mention
]
owned_classes.each do |klass|
klass.where(account_id: duplicate_account.id).find_each do |record|
begin
record.update_attribute(:account_id, main_account.id)
rescue ActiveRecord::RecordNotUnique
next
end
end
end
target_classes = [Follow, FollowRequest, Block, Mute, AccountModerationNote, AccountPin]
target_classes.each do |klass|
klass.where(target_account_id: duplicate_account.id).find_each do |record|
begin
record.update_attribute(:target_account_id, main_account.id)
rescue ActiveRecord::RecordNotUnique
next
end
end
end
end
def merge_conversations!(main_conv, duplicate_conv)
owned_classes = [ConversationMute, AccountConversation]
owned_classes.each do |klass|
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter