imap-backup 14.4.1 → 14.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/imap-backup +2 -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
|