123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- # 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
|