mirror of
https://github.com/mastodon/mastodon
synced 2024-12-01 00:08:21 +09:00
186 lines
4.8 KiB
Ruby
186 lines
4.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class BulkImportService < BaseService
|
|
def call(import)
|
|
@import = import
|
|
@account = @import.account
|
|
|
|
case @import.type.to_sym
|
|
when :following
|
|
import_follows!
|
|
when :blocking
|
|
import_blocks!
|
|
when :muting
|
|
import_mutes!
|
|
when :domain_blocking
|
|
import_domain_blocks!
|
|
when :bookmarks
|
|
import_bookmarks!
|
|
when :lists
|
|
import_lists!
|
|
end
|
|
|
|
@import.update!(state: :finished, finished_at: Time.now.utc) if @import.processed_items == @import.total_items
|
|
rescue
|
|
@import.update!(state: :finished, finished_at: Time.now.utc)
|
|
|
|
raise
|
|
end
|
|
|
|
private
|
|
|
|
def extract_rows_by_acct
|
|
local_domain_suffix = "@#{Rails.configuration.x.local_domain}"
|
|
@import.rows.to_a.index_by { |row| row.data['acct'].delete_suffix(local_domain_suffix) }
|
|
end
|
|
|
|
def import_follows!
|
|
rows_by_acct = extract_rows_by_acct
|
|
|
|
if @import.overwrite?
|
|
@account.following.reorder(nil).find_each do |followee|
|
|
row = rows_by_acct.delete(followee.acct)
|
|
|
|
if row.nil?
|
|
UnfollowService.new.call(@account, followee)
|
|
else
|
|
row.destroy
|
|
@import.processed_items += 1
|
|
@import.imported_items += 1
|
|
|
|
# Since we're updating the settings of an existing relationship, we can safely call
|
|
# FollowService directly
|
|
FollowService.new.call(@account, followee, reblogs: row.data['show_reblogs'], notify: row.data['notify'], languages: row.data['languages'])
|
|
end
|
|
end
|
|
|
|
# Save pending infos due to `overwrite?` handling
|
|
@import.save!
|
|
end
|
|
|
|
Import::RowWorker.push_bulk(rows_by_acct.values) do |row|
|
|
[row.id]
|
|
end
|
|
end
|
|
|
|
def import_blocks!
|
|
rows_by_acct = extract_rows_by_acct
|
|
|
|
if @import.overwrite?
|
|
@account.blocking.reorder(nil).find_each do |blocked_account|
|
|
row = rows_by_acct.delete(blocked_account.acct)
|
|
|
|
if row.nil?
|
|
UnblockService.new.call(@account, blocked_account)
|
|
else
|
|
row.destroy
|
|
@import.processed_items += 1
|
|
@import.imported_items += 1
|
|
BlockService.new.call(@account, blocked_account)
|
|
end
|
|
end
|
|
|
|
# Save pending infos due to `overwrite?` handling
|
|
@import.save!
|
|
end
|
|
|
|
Import::RowWorker.push_bulk(rows_by_acct.values) do |row|
|
|
[row.id]
|
|
end
|
|
end
|
|
|
|
def import_mutes!
|
|
rows_by_acct = extract_rows_by_acct
|
|
|
|
if @import.overwrite?
|
|
@account.muting.reorder(nil).find_each do |muted_account|
|
|
row = rows_by_acct.delete(muted_account.acct)
|
|
|
|
if row.nil?
|
|
UnmuteService.new.call(@account, muted_account)
|
|
else
|
|
row.destroy
|
|
@import.processed_items += 1
|
|
@import.imported_items += 1
|
|
MuteService.new.call(@account, muted_account, notifications: row.data['hide_notifications'])
|
|
end
|
|
end
|
|
|
|
# Save pending infos due to `overwrite?` handling
|
|
@import.save!
|
|
end
|
|
|
|
Import::RowWorker.push_bulk(rows_by_acct.values) do |row|
|
|
[row.id]
|
|
end
|
|
end
|
|
|
|
def import_domain_blocks!
|
|
domains = @import.rows.map { |row| row.data['domain'] }
|
|
|
|
if @import.overwrite?
|
|
@account.domain_blocks.find_each do |domain_block|
|
|
domain = domains.delete(domain_block)
|
|
|
|
@account.unblock_domain!(domain_block.domain) if domain.nil?
|
|
end
|
|
end
|
|
|
|
@import.rows.delete_all
|
|
domains.each { |domain| @account.block_domain!(domain) }
|
|
@import.update!(processed_items: @import.total_items, imported_items: @import.total_items)
|
|
|
|
AfterAccountDomainBlockWorker.push_bulk(domains) do |domain|
|
|
[@account.id, domain]
|
|
end
|
|
end
|
|
|
|
def import_bookmarks!
|
|
rows_by_uri = @import.rows.index_by { |row| row.data['uri'] }
|
|
|
|
if @import.overwrite?
|
|
@account.bookmarks.includes(:status).find_each do |bookmark|
|
|
row = rows_by_uri.delete(ActivityPub::TagManager.instance.uri_for(bookmark.status))
|
|
|
|
if row.nil?
|
|
bookmark.destroy!
|
|
else
|
|
row.destroy
|
|
@import.processed_items += 1
|
|
@import.imported_items += 1
|
|
end
|
|
end
|
|
|
|
# Save pending infos due to `overwrite?` handling
|
|
@import.save!
|
|
end
|
|
|
|
Import::RowWorker.push_bulk(rows_by_uri.values) do |row|
|
|
[row.id]
|
|
end
|
|
end
|
|
|
|
def import_lists!
|
|
rows = @import.rows.to_a
|
|
included_lists = rows.map { |row| row.data['list_name'] }.uniq
|
|
|
|
if @import.overwrite?
|
|
@account.owned_lists.where.not(title: included_lists).destroy_all
|
|
|
|
# As list membership changes do not retroactively change timeline
|
|
# contents, simplify things by just clearing everything
|
|
@account.owned_lists.find_each do |list|
|
|
list.list_accounts.destroy_all
|
|
end
|
|
end
|
|
|
|
included_lists.each do |title|
|
|
@account.owned_lists.find_or_create_by!(title: title)
|
|
end
|
|
|
|
Import::RowWorker.push_bulk(rows) do |row|
|
|
[row.id]
|
|
end
|
|
end
|
|
end
|