Allow to choose to overwrite settings and profile data

This commit is contained in:
Benjamin Neff 2021-11-09 04:04:27 +01:00
parent 96493b4a5c
commit 34528521f2
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
5 changed files with 179 additions and 53 deletions

View file

@ -3,14 +3,14 @@
class ImportService
include Diaspora::Logging
def import_by_user(user)
import_by_files(user.export.current_path, user.exported_photos_file.current_path, user.username)
def import_by_user(user, opts={})
import_by_files(user.export.current_path, user.exported_photos_file.current_path, user.username, opts)
end
def import_by_files(path_to_profile, path_to_photos, username)
def import_by_files(path_to_profile, path_to_photos, username, opts={})
if path_to_profile.present?
logger.info "Import for profile #{username} at path #{path_to_profile} requested"
import_user_profile(path_to_profile, username)
import_user_profile(path_to_profile, username, opts)
end
user = User.find_by(username: username)
@ -25,10 +25,10 @@ class ImportService
private
def import_user_profile(path_to_profile, username)
def import_user_profile(path_to_profile, username, opts)
raise ArgumentError, "Profile file not found at path: #{path_to_profile}" unless File.exist?(path_to_profile)
service = MigrationService.new(path_to_profile, username)
service = MigrationService.new(path_to_profile, username, opts)
logger.info "Start validating user profile #{username}"
service.validate
logger.info "Start importing user profile for '#{username}'"

View file

@ -1,12 +1,14 @@
# frozen_string_literal: true
class MigrationService
attr_reader :archive_path, :new_user_name
attr_reader :archive_path, :new_user_name, :opts
delegate :errors, :warnings, to: :archive_validator
def initialize(archive_path, new_user_name)
def initialize(archive_path, new_user_name, opts={})
@archive_path = archive_path
@new_user_name = new_user_name
@opts = opts
end
def validate
@ -40,12 +42,11 @@ class MigrationService
private
def find_or_create_user
archive_importer.user = User.find_by(username: new_user_name)
archive_importer.create_user(username: new_user_name, password: SecureRandom.hex) if archive_importer.user.nil?
archive_importer.find_or_create_user(username: new_user_name, password: SecureRandom.hex)
end
def import_archive
archive_importer.import
archive_importer.import(opts)
end
def run_migration

View file

@ -10,7 +10,7 @@ class ArchiveImporter
@archive_hash = archive_hash
end
def import
def import(opts={})
import_tag_followings
import_aspects
import_contacts
@ -19,12 +19,12 @@ class ArchiveImporter
import_subscriptions
import_others_relayables
import_blocks
import_settings if opts.fetch(:import_settings, true)
import_profile if opts.fetch(:import_profile, true)
end
def create_user(attr)
allowed_keys = %w[
email strip_exif show_community_spotlight_in_stream language disable_mail auto_follow_back
]
def find_or_create_user(attr)
allowed_keys = %w[email language]
data = convert_keys(archive_hash["user"], allowed_keys)
# setting getting_started to false as the user doesn't need to see the getting started wizard
data.merge!(
@ -36,8 +36,6 @@ class ArchiveImporter
}
)
self.user = User.find_or_build(data)
user.show_community_spotlight_in_stream = data.fetch(:show_community_spotlight_in_stream, true)
user.strip_exif = data.fetch(:strip_exif, true)
user.getting_started = false
user.save!
end
@ -63,7 +61,7 @@ class ArchiveImporter
return if name.nil?
aspect = user.aspects.find_by(name: name)
user.update(auto_follow_back_aspect: aspect) if aspect
user.update(auto_follow_back: true, auto_follow_back_aspect: aspect) if aspect
end
def import_aspects
@ -74,7 +72,6 @@ class ArchiveImporter
logger.warn "#{self}: #{e}"
end
end
set_auto_follow_back_aspect
end
def import_posts
@ -125,6 +122,21 @@ class ArchiveImporter
end
end
def import_settings
allowed_keys = %w[language show_community_spotlight_in_stream strip_exif]
convert_keys(archive_hash["user"], allowed_keys).each do |key, value|
user.update(key => value) unless value.nil?
end
set_auto_follow_back_aspect if archive_hash.fetch("user").fetch("auto_follow_back", false)
end
def import_profile
profile_attributes.each do |key, value|
user.person.profile.update(key => value) unless value.nil?
end
end
def convert_keys(hash, allowed_keys)
hash
.slice(*allowed_keys)

View file

@ -2,13 +2,16 @@
namespace :accounts do
desc "Perform migration"
task :migration, %i[archive_path photos_path new_user_name] => :environment do |_t, args|
puts "Account migration is requested. You can import a profile or a photos archive or booth."
args = %i[archive_path photos_path new_user_name].map {|name| [name, args[name]] }.to_h
task :migration,
%i[archive_path photos_path new_user_name import_settings import_profile] => :environment do |_t, args|
puts "Account migration is requested. You can import a profile or a photos archive or both."
args = %i[archive_path photos_path new_user_name import_settings import_profile]
.map {|name| [name, args[name]] }.to_h
process_arguments(args)
start_time = Time.now.getlocal
if args[:new_user_name].present? && (args[:archive_path].present? || args[:photos_path].present?)
ImportService.new.import_by_files(args[:archive_path], args[:photos_path], args[:new_user_name])
ImportService.new.import_by_files(args[:archive_path], args[:photos_path], args[:new_user_name],
args.slice(:import_settings, :import_profile))
puts "\n Migration completed in #{Time.now.getlocal - start_time} seconds. (Photos might still be processed in)"
else
puts "Must set a user name and a archive file path or photos file path"
@ -19,11 +22,14 @@ namespace :accounts do
args[:archive_path] = request_parameter(args[:archive_path], "Enter the archive (.json, .gz, .zip) path: ")
args[:photos_path] = request_parameter(args[:photos_path], "Enter the photos (.zip) path: ")
args[:new_user_name] = request_parameter(args[:new_user_name], "Enter the new user name: ")
args[:import_settings] = request_boolean_parameter(args[:import_settings], "Import and overwrite settings [Y/n]: ")
args[:import_profile] = request_boolean_parameter(args[:import_profile], "Import and overwrite profile [Y/n]: ")
puts "Archive path: #{args[:archive_path]}"
puts "Photos path: #{args[:photos_path]}"
puts "New username: #{args[:new_user_name]}"
end
puts "Import settings: #{args[:import_settings]}"
puts "Import profile: #{args[:import_profile]}"
end
def request_parameter(arg, text)
@ -32,3 +38,15 @@ def request_parameter(arg, text)
print text
$stdin.gets.strip
end
def request_boolean_parameter(arg, text, default: true)
return arg == "true" unless arg.nil?
print text
response = $stdin.gets.strip.downcase
return default if response == ""
response[0] == "y"
end
end

View file

@ -56,15 +56,11 @@ describe ArchiveImporter do
let(:archive_hash) {
{
"user" => {
"auto_follow_back_aspect" => "Friends",
"profile" => {
"entity_data" => {
"author" => "old_id@old_pod.nowhere"
}
},
"contact_groups" => [{
"name" => "Friends"
}],
"followed_tags" => [target.tag_followings.first.tag.name],
"post_subscriptions" => [target.participations.first.target.guid]
}
@ -109,10 +105,118 @@ describe ArchiveImporter do
}.not_to raise_error
end
end
context "with settings" do
let(:archive_hash) {
{
"user" => {
"profile" => {
"entity_data" => {
"author" => "old_id@old_pod.nowhere"
}
},
"contact_groups" => [{
"name" => "Follow"
}],
"strip_exif" => false,
"show_community_spotlight_in_stream" => false,
"language" => "ru",
"auto_follow_back" => true,
"auto_follow_back_aspect" => "Follow"
}
}
}
it "imports the settings" do
expect {
archive_importer.import
}.not_to raise_error
expect(archive_importer.user.strip_exif).to eq(false)
expect(archive_importer.user.show_community_spotlight_in_stream).to eq(false)
expect(archive_importer.user.language).to eq("ru")
expect(archive_importer.user.auto_follow_back).to eq(true)
expect(archive_importer.user.auto_follow_back_aspect.name).to eq("Follow")
end
describe "#create_user" do
let(:archive_importer) { ArchiveImporter.new(archive_hash) }
it "does not overwrite settings if import_settings is disabled" do
expect {
archive_importer.import(import_settings: false)
}.not_to raise_error
expect(archive_importer.user.strip_exif).to eq(true)
expect(archive_importer.user.show_community_spotlight_in_stream).to eq(true)
expect(archive_importer.user.language).to eq("en")
expect(archive_importer.user.auto_follow_back).to eq(false)
end
end
context "with profile" do
let(:archive_hash) {
{
"user" => {
"profile" => {
"entity_data" => {
"author" => "old_id@old_pod.nowhere",
"first_name" => "First",
"last_name" => "Last",
"full_name" => "Full Name",
"image_url" => "https://example.com/my_avatar.png",
"bio" => "I'm just a test account",
"gender" => "Robot",
"birthday" => "2006-01-01",
"location" => "diaspora* specs",
"searchable" => false,
"public" => true,
"nsfw" => true,
"tag_string" => "#diaspora #linux #partying"
}
}
}
}
}
it "imports the profile data" do
expect {
archive_importer.import
}.not_to raise_error
expect(archive_importer.user.profile.first_name).to eq("First")
expect(archive_importer.user.profile.last_name).to eq("Last")
expect(archive_importer.user.profile.image_url).to eq("https://example.com/my_avatar.png")
expect(archive_importer.user.profile.bio).to eq("I'm just a test account")
expect(archive_importer.user.profile.gender).to eq("Robot")
expect(archive_importer.user.profile.birthday).to eq(Date.new(2006, 1, 1))
expect(archive_importer.user.profile.location).to eq("diaspora* specs")
expect(archive_importer.user.profile.searchable).to eq(false)
expect(archive_importer.user.profile.public_details).to eq(true)
expect(archive_importer.user.profile.nsfw).to eq(true)
expect(archive_importer.user.profile.tag_string).to eq("#diaspora #linux #partying")
end
it "does not overwrite profile if import_profile is disabled" do
original_profile = target.profile.dup
expect {
archive_importer.import(import_profile: false)
}.not_to raise_error
expect(archive_importer.user.profile.first_name).to eq(original_profile.first_name)
expect(archive_importer.user.profile.last_name).to eq(original_profile.last_name)
expect(archive_importer.user.profile.image_url).to eq(original_profile.image_url)
expect(archive_importer.user.profile.bio).to eq(original_profile.bio)
expect(archive_importer.user.profile.gender).to eq(original_profile.gender)
expect(archive_importer.user.profile.birthday).to eq(original_profile.birthday)
expect(archive_importer.user.profile.location).to eq(original_profile.location)
expect(archive_importer.user.profile.searchable).to eq(original_profile.searchable)
expect(archive_importer.user.profile.public_details).to eq(original_profile.public_details)
expect(archive_importer.user.profile.nsfw).to eq(original_profile.nsfw)
expect(archive_importer.user.profile.tag_string).to eq(original_profile.tag_string)
end
end
end
describe "#find_or_create_user" do
let(:archive_hash) {
{
"user" => {
@ -133,26 +237,17 @@ describe ArchiveImporter do
"tag_string" => "#diaspora #linux #partying"
}
},
"email" => "user@example.com",
"strip_exif" => false,
"show_community_spotlight_in_stream" => false,
"language" => "ru",
"disable_mail" => false,
"auto_follow_back" => true
"email" => "user@example.com"
}
}
}
let(:archive_importer) { ArchiveImporter.new(archive_hash) }
it "creates user" do
expect {
archive_importer.create_user(username: "new_name", password: "123456")
archive_importer.find_or_create_user(username: "new_name", password: "123456")
}.to change(User, :count).by(1)
expect(archive_importer.user.email).to eq("user@example.com")
expect(archive_importer.user.strip_exif).to eq(false)
expect(archive_importer.user.show_community_spotlight_in_stream).to eq(false)
expect(archive_importer.user.language).to eq("ru")
expect(archive_importer.user.disable_mail).to eq(false)
expect(archive_importer.user.auto_follow_back).to eq(true)
expect(archive_importer.user.getting_started).to be_falsey
expect(archive_importer.user.profile.first_name).to eq("First")