imap-backup 14.4.1 → 14.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/imap-backup +5 -2
- data/docs/api.md +20 -0
- data/docs/development.md +18 -7
- data/lib/imap/backup/account/backup.rb +6 -3
- data/lib/imap/backup/account/backup_folders.rb +6 -3
- data/lib/imap/backup/account/client_factory.rb +3 -2
- data/lib/imap/backup/account/folder.rb +10 -9
- data/lib/imap/backup/account/folder_backup.rb +5 -4
- data/lib/imap/backup/account/folder_ensurer.rb +5 -2
- data/lib/imap/backup/account/local_only_folder_deleter.rb +7 -3
- data/lib/imap/backup/account/restore.rb +5 -2
- data/lib/imap/backup/account/serialized_folders.rb +3 -2
- data/lib/imap/backup/account.rb +85 -0
- data/lib/imap/backup/cli/backup.rb +14 -12
- data/lib/imap/backup/cli/folder_enumerator.rb +5 -5
- data/lib/imap/backup/cli/local/check.rb +4 -2
- data/lib/imap/backup/cli/local.rb +50 -49
- data/lib/imap/backup/cli/remote.rb +46 -46
- data/lib/imap/backup/cli/restore.rb +5 -3
- data/lib/imap/backup/cli/setup.rb +4 -2
- data/lib/imap/backup/cli/single/backup.rb +3 -3
- data/lib/imap/backup/cli/stats.rb +54 -52
- data/lib/imap/backup/cli/transfer.rb +93 -93
- data/lib/imap/backup/cli/utils.rb +28 -28
- data/lib/imap/backup/cli.rb +12 -0
- data/lib/imap/backup/client/default.rb +5 -5
- data/lib/imap/backup/configuration.rb +5 -4
- data/lib/imap/backup/downloader.rb +6 -14
- data/lib/imap/backup/email/mboxrd/message.rb +2 -3
- data/lib/imap/backup/file_mode.rb +4 -2
- data/lib/imap/backup/flag_refresher.rb +3 -3
- data/lib/imap/backup/local_only_message_deleter.rb +5 -3
- data/lib/imap/backup/migrator.rb +6 -4
- data/lib/imap/backup/mirror/map.rb +3 -3
- data/lib/imap/backup/mirror.rb +5 -5
- data/lib/imap/backup/serializer/appender.rb +7 -4
- data/lib/imap/backup/serializer/delayed_metadata_serializer.rb +15 -2
- data/lib/imap/backup/serializer/directory.rb +12 -3
- data/lib/imap/backup/serializer/folder_maker.rb +12 -4
- data/lib/imap/backup/serializer/imap.rb +5 -1
- data/lib/imap/backup/serializer/integrity_checker.rb +10 -3
- data/lib/imap/backup/serializer/mbox.rb +2 -1
- data/lib/imap/backup/serializer/message.rb +10 -18
- data/lib/imap/backup/serializer/permission_checker.rb +5 -3
- data/lib/imap/backup/serializer/transaction.rb +4 -1
- data/lib/imap/backup/serializer/unused_name_finder.rb +4 -2
- data/lib/imap/backup/serializer/version2_migrator.rb +2 -2
- data/lib/imap/backup/serializer.rb +5 -0
- data/lib/imap/backup/setup/account/header.rb +3 -3
- data/lib/imap/backup/setup/account.rb +6 -6
- data/lib/imap/backup/setup/asker.rb +6 -4
- data/lib/imap/backup/setup/backup_path.rb +3 -4
- data/lib/imap/backup/setup/connection_tester.rb +4 -2
- data/lib/imap/backup/setup/{email.rb → email_changer.rb} +4 -4
- data/lib/imap/backup/setup/folder_chooser.rb +2 -2
- data/lib/imap/backup/setup/global_options/download_strategy_chooser.rb +2 -2
- data/lib/imap/backup/setup/global_options.rb +2 -2
- data/lib/imap/backup/setup.rb +2 -2
- data/lib/imap/backup/text/sanitizer.rb +2 -2
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +10 -8
- data/lib/imap/backup/uploader.rb +3 -3
- data/lib/imap/backup/version.rb +1 -1
- metadata +4 -4
- data/lib/imap/backup/cli_coverage.rb +0 -21
@@ -14,8 +14,6 @@ module Imap::Backup
|
|
14
14
|
include Thor::Actions
|
15
15
|
include CLI::Helpers
|
16
16
|
|
17
|
-
MAX_SUBJECT = 60
|
18
|
-
|
19
17
|
desc "accounts", "List locally backed-up accounts"
|
20
18
|
config_option
|
21
19
|
format_option
|
@@ -122,69 +120,72 @@ module Imap::Backup
|
|
122
120
|
end
|
123
121
|
end
|
124
122
|
|
125
|
-
|
126
|
-
def list_emails_as_json(serializer)
|
127
|
-
emails = serializer.each_message.map do |message|
|
128
|
-
{
|
129
|
-
uid: message.uid,
|
130
|
-
date: message.date.to_s,
|
131
|
-
subject: message.subject || ""
|
132
|
-
}
|
133
|
-
end
|
134
|
-
Kernel.puts emails.to_json
|
135
|
-
end
|
136
|
-
|
137
|
-
def list_emails_as_text(serializer)
|
138
|
-
Kernel.puts format(
|
139
|
-
"%-10<uid>s %-#{MAX_SUBJECT}<subject>s - %<date>s",
|
140
|
-
{uid: "UID", subject: "Subject", date: "Date"}
|
141
|
-
)
|
142
|
-
Kernel.puts "-" * (12 + MAX_SUBJECT + 28)
|
123
|
+
private
|
143
124
|
|
144
|
-
|
145
|
-
list_message_as_text message
|
146
|
-
end
|
147
|
-
end
|
125
|
+
MAX_SUBJECT = 60
|
148
126
|
|
149
|
-
|
150
|
-
|
127
|
+
def list_emails_as_json(serializer)
|
128
|
+
emails = serializer.each_message.map do |message|
|
129
|
+
{
|
151
130
|
uid: message.uid,
|
152
131
|
date: message.date.to_s,
|
153
132
|
subject: message.subject || ""
|
154
133
|
}
|
155
|
-
if m[:subject].length > MAX_SUBJECT
|
156
|
-
Kernel.puts format("% 10<uid>u: %.#{MAX_SUBJECT - 3}<subject>s... - %<date>s", m)
|
157
|
-
else
|
158
|
-
Kernel.puts format("% 10<uid>u: %-#{MAX_SUBJECT}<subject>s - %<date>s", m)
|
159
|
-
end
|
160
134
|
end
|
135
|
+
Kernel.puts emails.to_json
|
136
|
+
end
|
161
137
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
138
|
+
def list_emails_as_text(serializer)
|
139
|
+
Kernel.puts format(
|
140
|
+
"%-10<uid>s %-#{MAX_SUBJECT}<subject>s - %<date>s",
|
141
|
+
{uid: "UID", subject: "Subject", date: "Date"}
|
142
|
+
)
|
143
|
+
Kernel.puts "-" * (12 + MAX_SUBJECT + 28)
|
144
|
+
|
145
|
+
serializer.each_message.map do |message|
|
146
|
+
list_message_as_text message
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def list_message_as_text(message)
|
151
|
+
m = {
|
152
|
+
uid: message.uid,
|
153
|
+
date: message.date.to_s,
|
154
|
+
subject: message.subject || ""
|
155
|
+
}
|
156
|
+
if m[:subject].length > MAX_SUBJECT
|
157
|
+
Kernel.puts format("% 10<uid>u: %.#{MAX_SUBJECT - 3}<subject>s... - %<date>s", m)
|
158
|
+
else
|
159
|
+
Kernel.puts format("% 10<uid>u: %-#{MAX_SUBJECT}<subject>s - %<date>s", m)
|
167
160
|
end
|
161
|
+
end
|
168
162
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
163
|
+
def show_emails_as_json(serializer, uids)
|
164
|
+
emails = serializer.each_message(uids).map do |m|
|
165
|
+
m.to_h.tap { |h| h[:body] = m.body }
|
166
|
+
end
|
167
|
+
Kernel.puts emails.to_json
|
168
|
+
end
|
169
|
+
|
170
|
+
def show_emails_as_text(serializer, uids)
|
171
|
+
serializer.each_message(uids).each do |message|
|
172
|
+
if uids.count > 1
|
173
|
+
Kernel.puts <<~HEADER
|
174
|
+
#{'-' * 80}
|
175
|
+
#{format('| UID: %-71s |', message.uid)}
|
176
|
+
#{'-' * 80}
|
177
|
+
HEADER
|
179
178
|
end
|
179
|
+
Kernel.puts message.body
|
180
180
|
end
|
181
|
+
end
|
181
182
|
|
182
|
-
|
183
|
-
|
183
|
+
def config
|
184
|
+
@config ||=
|
185
|
+
begin
|
184
186
|
non_logging_options = Logger.setup_logging(options)
|
185
187
|
load_config(**non_logging_options)
|
186
188
|
end
|
187
|
-
end
|
188
189
|
end
|
189
190
|
end
|
190
191
|
end
|
@@ -68,63 +68,63 @@ module Imap::Backup
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
|
72
|
-
def folder_names(email)
|
73
|
-
config = load_config(**options)
|
74
|
-
account = account(config, email)
|
71
|
+
private
|
75
72
|
|
76
|
-
|
77
|
-
|
73
|
+
def folder_names(email)
|
74
|
+
config = load_config(**options)
|
75
|
+
account = account(config, email)
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
{name: name}
|
82
|
-
end
|
83
|
-
Kernel.puts list.to_json
|
84
|
-
end
|
77
|
+
account.client.list
|
78
|
+
end
|
85
79
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
80
|
+
def json_format_names(names)
|
81
|
+
list = names.map do |name|
|
82
|
+
{name: name}
|
90
83
|
end
|
84
|
+
Kernel.puts list.to_json
|
85
|
+
end
|
91
86
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
other: namespace_info(namespaces.other.first),
|
96
|
-
shared: namespace_info(namespaces.shared.first)
|
97
|
-
}
|
98
|
-
Kernel.puts list.to_json
|
87
|
+
def list_names(names)
|
88
|
+
names.each do |name|
|
89
|
+
Kernel.puts %("#{name}")
|
99
90
|
end
|
91
|
+
end
|
100
92
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
93
|
+
def json_format_namespaces(namespaces)
|
94
|
+
list = {
|
95
|
+
personal: namespace_info(namespaces.personal.first),
|
96
|
+
other: namespace_info(namespaces.other.first),
|
97
|
+
shared: namespace_info(namespaces.shared.first)
|
98
|
+
}
|
99
|
+
Kernel.puts list.to_json
|
100
|
+
end
|
101
|
+
|
102
|
+
def list_namespaces(namespaces)
|
103
|
+
Kernel.puts format(
|
104
|
+
"%-10<name>s %-10<prefix>s %<delim>s",
|
105
|
+
{name: "Name", prefix: "Prefix", delim: "Delimiter"}
|
106
|
+
)
|
107
|
+
list_namespace namespaces, :personal
|
108
|
+
list_namespace namespaces, :other
|
109
|
+
list_namespace namespaces, :shared
|
110
|
+
end
|
110
111
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end
|
112
|
+
def list_namespace(namespaces, name)
|
113
|
+
info = namespace_info(namespaces.send(name).first, quote: true)
|
114
|
+
if info
|
115
|
+
Kernel.puts format("%-10<name>s %-10<prefix>s %<delim>s", name: name, **info)
|
116
|
+
else
|
117
|
+
Kernel.puts format("%-10<name>s (Not defined)", name: name)
|
118
118
|
end
|
119
|
+
end
|
119
120
|
|
120
|
-
|
121
|
-
|
121
|
+
def namespace_info(namespace, quote: false)
|
122
|
+
return nil if !namespace
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
124
|
+
{
|
125
|
+
prefix: quote ? namespace.prefix.to_json : namespace.prefix,
|
126
|
+
delim: quote ? namespace.delim.to_json : namespace.delim
|
127
|
+
}
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
@@ -12,9 +12,6 @@ module Imap::Backup
|
|
12
12
|
include Thor::Actions
|
13
13
|
include CLI::Helpers
|
14
14
|
|
15
|
-
attr_reader :email
|
16
|
-
attr_reader :options
|
17
|
-
|
18
15
|
def initialize(email = nil, options)
|
19
16
|
super([])
|
20
17
|
@email = email
|
@@ -42,5 +39,10 @@ module Imap::Backup
|
|
42
39
|
end
|
43
40
|
end
|
44
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
attr_reader :email
|
46
|
+
attr_reader :options
|
45
47
|
end
|
46
48
|
end
|
@@ -12,8 +12,6 @@ module Imap::Backup
|
|
12
12
|
include Thor::Actions
|
13
13
|
include CLI::Helpers
|
14
14
|
|
15
|
-
attr_reader :options
|
16
|
-
|
17
15
|
def initialize(options)
|
18
16
|
super([])
|
19
17
|
@options = options
|
@@ -25,5 +23,9 @@ module Imap::Backup
|
|
25
23
|
Setup.new(config: config).run
|
26
24
|
end
|
27
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :options
|
28
30
|
end
|
29
31
|
end
|
@@ -11,9 +11,6 @@ module Imap::Backup
|
|
11
11
|
class CLI::Single < Thor; end
|
12
12
|
|
13
13
|
class CLI::Single::Backup
|
14
|
-
attr_reader :options
|
15
|
-
attr_reader :password
|
16
|
-
|
17
14
|
def initialize(options)
|
18
15
|
@options = options
|
19
16
|
@password = nil
|
@@ -40,6 +37,9 @@ module Imap::Backup
|
|
40
37
|
|
41
38
|
private
|
42
39
|
|
40
|
+
attr_reader :options
|
41
|
+
attr_reader :password
|
42
|
+
|
43
43
|
def process_options!
|
44
44
|
if !email
|
45
45
|
raise Thor::RequiredArgumentMissingError,
|
@@ -8,17 +8,6 @@ module Imap::Backup
|
|
8
8
|
include Thor::Actions
|
9
9
|
include CLI::Helpers
|
10
10
|
|
11
|
-
TEXT_COLUMNS = [
|
12
|
-
{name: :folder, width: 20, alignment: :left},
|
13
|
-
{name: :remote, width: 8, alignment: :right},
|
14
|
-
{name: :both, width: 8, alignment: :right},
|
15
|
-
{name: :local, width: 8, alignment: :right}
|
16
|
-
].freeze
|
17
|
-
ALIGNMENT_FORMAT_SYMBOL = {left: "-", right: " "}.freeze
|
18
|
-
|
19
|
-
attr_reader :email
|
20
|
-
attr_reader :options
|
21
|
-
|
22
11
|
def initialize(email, options)
|
23
12
|
super([])
|
24
13
|
@email = email
|
@@ -34,56 +23,69 @@ module Imap::Backup
|
|
34
23
|
format_text stats
|
35
24
|
end
|
36
25
|
end
|
26
|
+
end
|
37
27
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
next if !folder.exist?
|
48
|
-
|
49
|
-
serializer = Serializer.new(account.local_path, folder.name)
|
50
|
-
local_uids = serializer.uids
|
51
|
-
Logger.logger.debug("[Stats] fetching email list for '#{folder.name}'")
|
52
|
-
remote_uids = folder.uids
|
53
|
-
{
|
54
|
-
folder: folder.name,
|
55
|
-
remote: (remote_uids - local_uids).count,
|
56
|
-
both: (serializer.uids & folder.uids).count,
|
57
|
-
local: (local_uids - remote_uids).count
|
58
|
-
}
|
59
|
-
end.compact
|
60
|
-
end
|
28
|
+
private
|
29
|
+
|
30
|
+
TEXT_COLUMNS = [
|
31
|
+
{name: :folder, width: 20, alignment: :left},
|
32
|
+
{name: :remote, width: 8, alignment: :right},
|
33
|
+
{name: :both, width: 8, alignment: :right},
|
34
|
+
{name: :local, width: 8, alignment: :right}
|
35
|
+
].freeze
|
36
|
+
ALIGNMENT_FORMAT_SYMBOL = {left: "-", right: " "}.freeze
|
61
37
|
|
62
|
-
|
63
|
-
|
38
|
+
attr_reader :email
|
39
|
+
attr_reader :options
|
64
40
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
format("%#{symbol}#{column[:width]}s", count)
|
70
|
-
end.join("|")
|
41
|
+
def stats
|
42
|
+
Logger.logger.debug("[Stats] loading configuration")
|
43
|
+
config = load_config(**options)
|
44
|
+
account = account(config, email)
|
71
45
|
|
72
|
-
|
73
|
-
|
74
|
-
|
46
|
+
backup_folders = Account::BackupFolders.new(
|
47
|
+
client: account.client, account: account
|
48
|
+
)
|
49
|
+
backup_folders.map do |folder|
|
50
|
+
next if !folder.exist?
|
75
51
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
52
|
+
serializer = Serializer.new(account.local_path, folder.name)
|
53
|
+
local_uids = serializer.uids
|
54
|
+
Logger.logger.debug("[Stats] fetching email list for '#{folder.name}'")
|
55
|
+
remote_uids = folder.uids
|
56
|
+
{
|
57
|
+
folder: folder.name,
|
58
|
+
remote: (remote_uids - local_uids).count,
|
59
|
+
both: (serializer.uids & folder.uids).count,
|
60
|
+
local: (local_uids - remote_uids).count
|
61
|
+
}
|
62
|
+
end.compact
|
63
|
+
end
|
64
|
+
|
65
|
+
def format_text(stats)
|
66
|
+
Kernel.puts text_header
|
80
67
|
|
81
|
-
|
82
|
-
|
68
|
+
stats.each do |stat|
|
69
|
+
columns = TEXT_COLUMNS.map do |column|
|
70
|
+
symbol = ALIGNMENT_FORMAT_SYMBOL[column[:alignment]]
|
71
|
+
count = stat[column[:name]]
|
72
|
+
format("%#{symbol}#{column[:width]}s", count)
|
83
73
|
end.join("|")
|
84
74
|
|
85
|
-
|
75
|
+
Kernel.puts columns
|
86
76
|
end
|
87
77
|
end
|
78
|
+
|
79
|
+
def text_header
|
80
|
+
titles = TEXT_COLUMNS.map do |column|
|
81
|
+
format("%-#{column[:width]}s", column[:name])
|
82
|
+
end.join("|")
|
83
|
+
|
84
|
+
underline = TEXT_COLUMNS.map do |column|
|
85
|
+
"-" * column[:width]
|
86
|
+
end.join("|")
|
87
|
+
|
88
|
+
"#{titles}\n#{underline}"
|
89
|
+
end
|
88
90
|
end
|
89
91
|
end
|
@@ -14,18 +14,6 @@ module Imap::Backup
|
|
14
14
|
|
15
15
|
ACTIONS = %i(migrate mirror).freeze
|
16
16
|
|
17
|
-
attr_reader :action
|
18
|
-
attr_accessor :automatic_namespaces
|
19
|
-
attr_accessor :config_path
|
20
|
-
attr_accessor :destination_delimiter
|
21
|
-
attr_reader :destination_email
|
22
|
-
attr_accessor :destination_prefix
|
23
|
-
attr_reader :options
|
24
|
-
attr_accessor :reset
|
25
|
-
attr_accessor :source_delimiter
|
26
|
-
attr_reader :source_email
|
27
|
-
attr_accessor :source_prefix
|
28
|
-
|
29
17
|
def initialize(action, source_email, destination_email, options)
|
30
18
|
super([])
|
31
19
|
@action = action
|
@@ -57,108 +45,120 @@ module Imap::Backup
|
|
57
45
|
end
|
58
46
|
end
|
59
47
|
end
|
48
|
+
end
|
60
49
|
|
61
|
-
|
62
|
-
self.automatic_namespaces = options[:automatic_namespaces] || false
|
63
|
-
self.config_path = options[:config]
|
64
|
-
self.destination_delimiter = options[:destination_delimiter]
|
65
|
-
self.destination_prefix = options[:destination_prefix]
|
66
|
-
self.source_delimiter = options[:source_delimiter]
|
67
|
-
self.source_prefix = options[:source_prefix]
|
68
|
-
self.reset = options[:reset] || false
|
69
|
-
check_accounts!
|
70
|
-
choose_prefixes_and_delimiters!
|
71
|
-
end
|
50
|
+
private
|
72
51
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
52
|
+
attr_reader :action
|
53
|
+
attr_accessor :automatic_namespaces
|
54
|
+
attr_accessor :config_path
|
55
|
+
attr_accessor :destination_delimiter
|
56
|
+
attr_reader :destination_email
|
57
|
+
attr_accessor :destination_prefix
|
58
|
+
attr_reader :options
|
59
|
+
attr_accessor :reset
|
60
|
+
attr_accessor :source_delimiter
|
61
|
+
attr_reader :source_email
|
62
|
+
attr_accessor :source_prefix
|
77
63
|
|
78
|
-
|
64
|
+
def process_options!
|
65
|
+
self.automatic_namespaces = options[:automatic_namespaces] || false
|
66
|
+
self.config_path = options[:config]
|
67
|
+
self.destination_delimiter = options[:destination_delimiter]
|
68
|
+
self.destination_prefix = options[:destination_prefix]
|
69
|
+
self.source_delimiter = options[:source_delimiter]
|
70
|
+
self.source_prefix = options[:source_prefix]
|
71
|
+
self.reset = options[:reset] || false
|
72
|
+
check_accounts!
|
73
|
+
choose_prefixes_and_delimiters!
|
74
|
+
end
|
79
75
|
|
80
|
-
|
76
|
+
def check_accounts!
|
77
|
+
if destination_email == source_email
|
78
|
+
raise "Source and destination accounts cannot be the same!"
|
81
79
|
end
|
82
80
|
|
83
|
-
|
84
|
-
if automatic_namespaces
|
85
|
-
ensure_no_prefix_or_delimiter_parameters!
|
86
|
-
query_servers_for_settings
|
87
|
-
else
|
88
|
-
add_prefix_and_delimiter_defaults
|
89
|
-
end
|
90
|
-
end
|
81
|
+
raise "Account '#{destination_email}' does not exist" if !destination_account
|
91
82
|
|
92
|
-
|
93
|
-
|
94
|
-
raise "--automatic-namespaces is incompatible with --destination-delimiter"
|
95
|
-
end
|
96
|
-
if destination_prefix
|
97
|
-
raise "--automatic-namespaces is incompatible with --destination-prefix"
|
98
|
-
end
|
99
|
-
raise "--automatic-namespaces is incompatible with --source-delimiter" if source_delimiter
|
100
|
-
raise "--automatic-namespaces is incompatible with --source-prefix" if source_prefix
|
101
|
-
end
|
83
|
+
raise "Account '#{source_email}' does not exist" if !source_account
|
84
|
+
end
|
102
85
|
|
103
|
-
|
104
|
-
|
105
|
-
|
86
|
+
def choose_prefixes_and_delimiters!
|
87
|
+
if automatic_namespaces
|
88
|
+
ensure_no_prefix_or_delimiter_parameters!
|
89
|
+
query_servers_for_settings
|
90
|
+
else
|
91
|
+
add_prefix_and_delimiter_defaults
|
106
92
|
end
|
93
|
+
end
|
107
94
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
[personal.prefix, personal.delim]
|
95
|
+
def ensure_no_prefix_or_delimiter_parameters!
|
96
|
+
if destination_delimiter
|
97
|
+
raise "--automatic-namespaces is incompatible with --destination-delimiter"
|
112
98
|
end
|
99
|
+
raise "--automatic-namespaces is incompatible with --destination-prefix" if destination_prefix
|
100
|
+
raise "--automatic-namespaces is incompatible with --source-delimiter" if source_delimiter
|
101
|
+
raise "--automatic-namespaces is incompatible with --source-prefix" if source_prefix
|
102
|
+
end
|
113
103
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
self.source_prefix ||= ""
|
119
|
-
end
|
104
|
+
def query_servers_for_settings
|
105
|
+
self.destination_prefix, self.destination_delimiter = account_settings(destination_account)
|
106
|
+
self.source_prefix, self.source_delimiter = account_settings(source_account)
|
107
|
+
end
|
120
108
|
|
121
|
-
|
122
|
-
|
109
|
+
def account_settings(account)
|
110
|
+
namespaces = account.client.namespace
|
111
|
+
personal = namespaces.personal.first
|
112
|
+
[personal.prefix, personal.delim]
|
113
|
+
end
|
123
114
|
|
124
|
-
|
125
|
-
|
115
|
+
def add_prefix_and_delimiter_defaults
|
116
|
+
self.destination_delimiter ||= "/"
|
117
|
+
self.destination_prefix ||= ""
|
118
|
+
self.source_delimiter ||= "/"
|
119
|
+
self.source_prefix ||= ""
|
120
|
+
end
|
126
121
|
|
127
|
-
|
128
|
-
|
122
|
+
def prepare_mirror
|
123
|
+
warn_if_source_account_is_not_in_mirror_mode
|
129
124
|
|
130
|
-
|
131
|
-
|
132
|
-
"is not set up to make mirror backups"
|
133
|
-
Logger.logger.warn message
|
134
|
-
end
|
125
|
+
CLI::Backup.new(config: config_path, accounts: source_email).run
|
126
|
+
end
|
135
127
|
|
136
|
-
|
137
|
-
|
138
|
-
end
|
128
|
+
def warn_if_source_account_is_not_in_mirror_mode
|
129
|
+
return if source_account.mirror_mode
|
139
130
|
|
140
|
-
|
141
|
-
{
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
source: source_account,
|
146
|
-
source_delimiter: source_delimiter,
|
147
|
-
source_prefix: source_prefix
|
148
|
-
}
|
149
|
-
end
|
131
|
+
message =
|
132
|
+
"The account '#{source_account.username}' " \
|
133
|
+
"is not set up to make mirror backups"
|
134
|
+
Logger.logger.warn message
|
135
|
+
end
|
150
136
|
|
151
|
-
|
152
|
-
|
153
|
-
|
137
|
+
def config
|
138
|
+
@config ||= load_config(config: config_path)
|
139
|
+
end
|
154
140
|
|
155
|
-
|
156
|
-
|
157
|
-
|
141
|
+
def enumerator_options
|
142
|
+
{
|
143
|
+
destination: destination_account,
|
144
|
+
destination_delimiter: destination_delimiter,
|
145
|
+
destination_prefix: destination_prefix,
|
146
|
+
source: source_account,
|
147
|
+
source_delimiter: source_delimiter,
|
148
|
+
source_prefix: source_prefix
|
149
|
+
}
|
150
|
+
end
|
158
151
|
|
159
|
-
|
160
|
-
|
161
|
-
|
152
|
+
def folders
|
153
|
+
CLI::FolderEnumerator.new(**enumerator_options)
|
154
|
+
end
|
155
|
+
|
156
|
+
def destination_account
|
157
|
+
config.accounts.find { |a| a.username == destination_email }
|
158
|
+
end
|
159
|
+
|
160
|
+
def source_account
|
161
|
+
config.accounts.find { |a| a.username == source_email }
|
162
162
|
end
|
163
163
|
end
|
164
164
|
end
|