Skip to content

Commit

Permalink
Merge branch 'feature/restore-delimiter-option'
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyates committed Jan 31, 2024
2 parents 4c95e76 + e4804cb commit 7ed40b6
Show file tree
Hide file tree
Showing 21 changed files with 189 additions and 113 deletions.
9 changes: 0 additions & 9 deletions lib/imap/backup/account.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require "json"

require "imap/backup/account/client_factory"
require "imap/backup/account/restore"

module Imap; end

Expand Down Expand Up @@ -98,14 +97,6 @@ def capabilities
client.capability
end

# Restore the local backup to the server
#
# @return [void]
def restore
restore = Account::Restore.new(account: self)
restore.run
end

# Indicates whether the account has been configured, and is ready
# to be used
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@
module Imap; end

module Imap::Backup
class CLI < Thor; end
class Account; end

# Implements a folder enumerator for backed-up accounts
class CLI::FolderEnumerator
class Account::FolderMapper
def initialize(
account:,
destination:,
source:,
destination_delimiter: "/",
destination_prefix: "",
source_delimiter: "/",
source_prefix: ""
)
@account = account
@destination = destination
@destination_delimiter = destination_delimiter
@destination_prefix = destination_prefix
@source = source
@source_delimiter = source_delimiter
@source_prefix = source_prefix
end
Expand All @@ -48,7 +48,7 @@ def each

attr_reader :destination
attr_reader :destination_delimiter
attr_reader :source
attr_reader :account
attr_reader :source_delimiter

def destination_prefix_clipped
Expand Down Expand Up @@ -94,7 +94,7 @@ def destination_folder_for_path(name)
end

def source_local_path
source.local_path
account.local_path
end

def source_folder_name(imap_pathname)
Expand Down
24 changes: 20 additions & 4 deletions lib/imap/backup/account/restore.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require "imap/backup/account/serialized_folders"
require "imap/backup/account/folder_mapper"
require "imap/backup/uploader"

module Imap; end
Expand All @@ -8,21 +8,37 @@ class Account; end

# Restores all backed up folders to the server
class Account::Restore
def initialize(account:)
def initialize(account:, delimiter: "/", prefix: "")
@account = account
@destination_delimiter = delimiter
@destination_prefix = prefix
end

# Runs the restore operation
# @return [void]
def run
serialized_folders = Account::SerializedFolders.new(account: account)
serialized_folders.each do |serializer, folder|
folders.each do |serializer, folder|
Uploader.new(folder, serializer).run
end
end

private

attr_reader :account
attr_reader :destination_delimiter
attr_reader :destination_prefix

def enumerator_options
{
account: account,
destination: account,
destination_delimiter: destination_delimiter,
destination_prefix: destination_prefix
}
end

def folders
Account::FolderMapper.new(**enumerator_options)
end
end
end
11 changes: 11 additions & 0 deletions lib/imap/backup/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,17 @@ def mirror(source_email, destination_email)
config_option
quiet_option
verbose_option
method_option(
"delimiter",
type: :string,
desc: "the delimiter for folder names"
)
method_option(
"prefix",
type: :string,
desc: "a prefix (namespace) to add to folder names",
aliases: ["-d"]
)
# Restores backed up emails to an account
# @return [void]
def restore(email = nil)
Expand Down
18 changes: 14 additions & 4 deletions lib/imap/backup/cli/restore.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "thor"

require "imap/backup/account/restore"
require "imap/backup/cli/helpers"
require "imap/backup/logger"

Expand Down Expand Up @@ -28,18 +29,18 @@ def run
case
when email && !options.key?(:accounts)
account = account(config, email)
account.restore
restore(account, **restore_options)
when !email && !options.key?(:accounts)
Logger.logger.info "Calling restore without an EMAIL parameter is deprecated"
config.accounts.map(&:restore)
config.accounts.each { |a| restore(a) }
when email && options.key?(:accounts)
raise "Missing EMAIL parameter"
when !email && options.key?(:accounts)
Logger.logger.info(
"Calling restore with the --account option is deprected, " \
"Calling restore with the --account option is deprecated, " \
"please pass a single EMAIL parameter"
)
requested_accounts(config).each(&:restore)
requested_accounts(config).each { |a| restore(a) }
end
end
end
Expand All @@ -48,5 +49,14 @@ def run

attr_reader :email
attr_reader :options

def restore(account, **options)
restore = Account::Restore.new(account: account, **options)
restore.run
end

def restore_options
options.slice(:delimiter, :prefix)
end
end
end
40 changes: 18 additions & 22 deletions lib/imap/backup/cli/transfer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "imap/backup/account/folder_mapper"
require "imap/backup/cli/backup"
require "imap/backup/cli/helpers"
require "imap/backup/cli/folder_enumerator"
require "imap/backup/logger"
require "imap/backup/migrator"
require "imap/backup/mirror"
Expand All @@ -9,15 +9,13 @@ module Imap; end

module Imap::Backup
# Implements migration and mirroring
class CLI::Transfer < Thor
include Thor::Actions
class CLI::Transfer
include CLI::Helpers

# The possible vaues for the action parameter
# The possible values for the action parameter
ACTIONS = %i(migrate mirror).freeze

def initialize(action, source_email, destination_email, options)
super([])
@action = action
@source_email = source_email
@destination_email = destination_email
Expand All @@ -35,22 +33,20 @@ def initialize(action, source_email, destination_email, options)
# @raise [RuntimeError] if the indicated action is unknown,
# or the source and destination accounts are the same,
# or either of the accounts is not configured,
# or incompatible namespace/delimter parameters have been supplied
# or incompatible namespace/delimiter parameters have been supplied
# @return [void]
no_commands do
def run
raise "Unknown action '#{action}'" if !ACTIONS.include?(action)

process_options!
prepare_mirror if action == :mirror

folders.each do |serializer, folder|
case action
when :migrate
Migrator.new(serializer, folder, reset: reset).run
when :mirror
Mirror.new(serializer, folder).run
end
def run
raise "Unknown action '#{action}'" if !ACTIONS.include?(action)

process_options!
prepare_mirror if action == :mirror

folders.each do |serializer, folder|
case action
when :migrate
Migrator.new(serializer, folder, reset: reset).run
when :mirror
Mirror.new(serializer, folder).run
end
end
end
Expand Down Expand Up @@ -148,17 +144,17 @@ def config

def enumerator_options
{
account: source_account,
destination: destination_account,
destination_delimiter: destination_delimiter,
destination_prefix: destination_prefix,
source: source_account,
source_delimiter: source_delimiter,
source_prefix: source_prefix
}
end

def folders
CLI::FolderEnumerator.new(**enumerator_options)
Account::FolderMapper.new(**enumerator_options)
end

def destination_account
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/delayed_metadata_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Wraps the Serializer, delaying metadata appends
class Serializer::DelayedMetadataSerializer
extend Forwardable
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Stores message metadata
class Serializer::Imap
# The version number to store in the metadata file
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/mbox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Stores messages
class Serializer::Mbox
# @return [String] The path of the mailbox file, without the '.mbox' extension
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Represents a stored message
class Serializer::Message
# @return [Array[Symbol]] the message's flags
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/message_enumerator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Enumerates over a list of stores messages
class Serializer::MessageEnumerator
# @param imap [Serializer::Imap] the metadata serializer for the folder
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/permission_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Ensures a file has the desired permissions
class Serializer::PermissionChecker
# @param filename [String] the file name
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/transaction.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Stores data during a transaction
class Serializer::Transaction
# @return the transaction's stored data
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/unused_name_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Finds a name that can be used to rename a serialized folder
class Serializer::UnusedNameFinder
# @param serializer [Serializer] a folder serializer
Expand Down
2 changes: 2 additions & 0 deletions lib/imap/backup/serializer/version2_migrator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
module Imap; end

module Imap::Backup
class Serializer; end

# Migrates serialized folder metadata from the version 2 format to the version 3 format
class Serializer::Version2Migrator
# @param folder_path [String] the base pathv(without extension) of the folder backup
Expand Down
24 changes: 18 additions & 6 deletions spec/features/restore_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
email: email, folder: folder, flags: [:Draft, :$NON_SYSTEM_FLAG], **message_two
)
end
let(:run_command) { run_command_and_stop("imap-backup restore #{email}") }
let(:command) { "imap-backup restore #{email}" }
let(:run_command) { run_command_and_stop(command) }
let(:cleanup) do
test_server.delete_folder folder
test_server.disconnect
Expand Down Expand Up @@ -195,6 +196,21 @@
end
end

context "when a prefix and delimiter are supplied" do
after do
test_server.delete_folder "CIAO.#{folder}"
test_server.delete_folder "CIAO"
end

let(:command) { "imap-backup restore #{email} --prefix CIAO --delimiter ." }

it "prepends the prefix to the folder name" do
run_command

expect(test_server.folders.map(&:name)).to include("CIAO.#{folder}")
end
end

context "when a config path is supplied" do
let(:custom_config_path) { File.join(File.expand_path("~/.imap-backup"), "foo.json") }
let(:config_options) { super().merge(path: custom_config_path) }
Expand All @@ -215,11 +231,7 @@
**message_one
)
end
let(:run_command) do
run_command_and_stop(
"imap-backup restore #{email} --config #{custom_config_path}"
)
end
let(:command) { "imap-backup restore #{email} --config #{custom_config_path}" }

it "does not raise any errors" do
run_command
Expand Down
Loading

0 comments on commit 7ed40b6

Please sign in to comment.