Add option to overwrite imported data (#9962)
* Add option to overwrite imported data Fix #7465 * Add import for domain blocksmaster
parent
c5071f2d78
commit
d14c276e58
@ -0,0 +1,90 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
require 'csv' |
||||
|
||||
class ImportService < BaseService |
||||
ROWS_PROCESSING_LIMIT = 20_000 |
||||
|
||||
def call(import) |
||||
@import = import |
||||
@account = @import.account |
||||
@data = CSV.new(import_data).reject(&:blank?) |
||||
|
||||
case @import.type |
||||
when 'following' |
||||
import_follows! |
||||
when 'blocking' |
||||
import_blocks! |
||||
when 'muting' |
||||
import_mutes! |
||||
when 'domain_blocking' |
||||
import_domain_blocks! |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def import_follows! |
||||
import_relationships!('follow', 'unfollow', @account.following, follow_limit) |
||||
end |
||||
|
||||
def import_blocks! |
||||
import_relationships!('block', 'unblock', @account.blocking, ROWS_PROCESSING_LIMIT) |
||||
end |
||||
|
||||
def import_mutes! |
||||
import_relationships!('mute', 'unmute', @account.muting, ROWS_PROCESSING_LIMIT) |
||||
end |
||||
|
||||
def import_domain_blocks! |
||||
items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row.first.strip } |
||||
|
||||
if @import.overwrite? |
||||
presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true } |
||||
|
||||
@account.domain_blocks.find_each do |domain_block| |
||||
if presence_hash[domain_block.domain] |
||||
items.delete(domain_block.domain) |
||||
else |
||||
@account.unblock_domain!(domain_block.domain) |
||||
end |
||||
end |
||||
end |
||||
|
||||
items.each do |domain| |
||||
@account.block_domain!(domain) |
||||
end |
||||
|
||||
AfterAccountDomainBlockWorker.push_bulk(items) do |domain| |
||||
[@account.id, domain] |
||||
end |
||||
end |
||||
|
||||
def import_relationships!(action, undo_action, overwrite_scope, limit) |
||||
items = @data.take(limit).map { |row| row.first.strip } |
||||
|
||||
if @import.overwrite? |
||||
presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true } |
||||
|
||||
overwrite_scope.find_each do |target_account| |
||||
if presence_hash[target_account.acct] |
||||
items.delete(target_account.acct) |
||||
else |
||||
Import::RelationshipWorker.perform_async(@account.id, target_account.acct, undo_action) |
||||
end |
||||
end |
||||
end |
||||
|
||||
Import::RelationshipWorker.push_bulk(items) do |acct| |
||||
[@account.id, acct, action] |
||||
end |
||||
end |
||||
|
||||
def import_data |
||||
Paperclip.io_adapters.for(@import.data).read |
||||
end |
||||
|
||||
def follow_limit |
||||
FollowLimitValidator.limit_for_account(@account) |
||||
end |
||||
end |
@ -1,44 +1,14 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
require 'csv' |
||||
|
||||
class ImportWorker |
||||
include Sidekiq::Worker |
||||
|
||||
sidekiq_options queue: 'pull', retry: false |
||||
|
||||
attr_reader :import |
||||
|
||||
def perform(import_id) |
||||
@import = Import.find(import_id) |
||||
|
||||
Import::RelationshipWorker.push_bulk(import_rows) do |row| |
||||
[@import.account_id, row.first, relationship_type] |
||||
end |
||||
|
||||
@import.destroy |
||||
end |
||||
|
||||
private |
||||
|
||||
def import_contents |
||||
Paperclip.io_adapters.for(@import.data).read |
||||
end |
||||
|
||||
def relationship_type |
||||
case @import.type |
||||
when 'following' |
||||
'follow' |
||||
when 'blocking' |
||||
'block' |
||||
when 'muting' |
||||
'mute' |
||||
end |
||||
end |
||||
|
||||
def import_rows |
||||
rows = CSV.new(import_contents).reject(&:blank?) |
||||
rows = rows.take(FollowLimitValidator.limit_for_account(@import.account)) if @import.type == 'following' |
||||
rows |
||||
import = Import.find(import_id) |
||||
ImportService.new.call(import) |
||||
ensure |
||||
import&.destroy |
||||
end |
||||
end |
||||
|
@ -0,0 +1,17 @@ |
||||
require Rails.root.join('lib', 'mastodon', 'migration_helpers') |
||||
|
||||
class AddOverwriteToImports < ActiveRecord::Migration[5.2] |
||||
include Mastodon::MigrationHelpers |
||||
|
||||
disable_ddl_transaction! |
||||
|
||||
def up |
||||
safety_assured do |
||||
add_column_with_default :imports, :overwrite, :boolean, default: false, allow_null: false |
||||
end |
||||
end |
||||
|
||||
def down |
||||
remove_column :imports, :overwrite, :boolean |
||||
end |
||||
end |
Loading…
Reference in new issue