From 96c1e7132971877fba308c51cd42306f0b1bf166 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 19 Nov 2020 17:48:13 +0100 Subject: Add import/export feature for bookmarks (#14956) * Add ability to export bookmarks * Add support for importing bookmarks * Add bookmark import tests * Add bookmarks export test --- app/services/import_service.rb | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'app/services/import_service.rb') diff --git a/app/services/import_service.rb b/app/services/import_service.rb index 7e55452de..288e47f1e 100644 --- a/app/services/import_service.rb +++ b/app/services/import_service.rb @@ -18,6 +18,8 @@ class ImportService < BaseService import_mutes! when 'domain_blocking' import_domain_blocks! + when 'bookmarks' + import_bookmarks! end end @@ -88,6 +90,39 @@ class ImportService < BaseService end end + def import_bookmarks! + parse_import_data!(['#uri']) + items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#uri'].strip } + + if @import.overwrite? + presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true } + + @account.bookmarks.find_each do |bookmark| + if presence_hash[bookmark.status.uri] + items.delete(bookmark.status.uri) + else + bookmark.destroy! + end + end + end + + statuses = items.map do |uri| + status = ActivityPub::TagManager.instance.uri_to_resource(uri, Status) + next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri) + + status || ActivityPub::FetchRemoteStatusService.new.call(uri) + end.compact + + account_ids = statuses.map(&:account_id) + preloaded_relations = relations_map_for_account(@account, account_ids) + + statuses.keep_if { |status| StatusPolicy.new(@account, status, preloaded_relations).show? } + + statuses.each do |status| + @account.bookmarks.find_or_create_by!(account: @account, status: status) + end + end + def parse_import_data!(default_headers) data = CSV.parse(import_data, headers: true) data = CSV.parse(import_data, headers: default_headers) unless data.headers&.first&.strip&.include?(' ') @@ -101,4 +136,14 @@ class ImportService < BaseService def follow_limit FollowLimitValidator.limit_for_account(@account) end + + def relations_map_for_account(account, account_ids) + { + blocking: {}, + blocked_by: Account.blocked_by_map(account_ids, account.id), + muting: {}, + following: Account.following_map(account_ids, account.id), + domain_blocking_by_domain: {}, + } + end end -- cgit