imap-backup 4.0.5 → 4.1.2
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 +5 -2
- data/lib/imap/backup/account/connection.rb +70 -58
- data/lib/imap/backup/account/folder.rb +23 -3
- data/lib/imap/backup/account.rb +6 -7
- data/lib/imap/backup/cli/accounts.rb +43 -0
- data/lib/imap/backup/cli/folders.rb +3 -1
- data/lib/imap/backup/cli/helpers.rb +8 -9
- data/lib/imap/backup/cli/local.rb +4 -2
- data/lib/imap/backup/cli/setup.rb +1 -1
- data/lib/imap/backup/cli/status.rb +1 -1
- data/lib/imap/backup/cli/utils.rb +3 -2
- data/lib/imap/backup/{configuration/store.rb → configuration.rb} +49 -14
- data/lib/imap/backup/downloader.rb +26 -12
- data/lib/imap/backup/logger.rb +42 -0
- data/lib/imap/backup/sanitizer.rb +42 -0
- data/lib/imap/backup/serializer/mbox_store.rb +2 -2
- data/lib/imap/backup/{configuration → setup}/account.rb +59 -41
- data/lib/imap/backup/{configuration → setup}/asker.rb +5 -5
- data/lib/imap/backup/setup/connection_tester.rb +26 -0
- data/lib/imap/backup/{configuration → setup}/folder_chooser.rb +25 -17
- data/lib/imap/backup/setup/helpers.rb +15 -0
- data/lib/imap/backup/{configuration/setup.rb → setup.rb} +33 -25
- data/lib/imap/backup/uploader.rb +2 -2
- data/lib/imap/backup/version.rb +2 -2
- data/lib/imap/backup.rb +7 -33
- data/lib/retry_on_error.rb +1 -1
- data/spec/features/backup_spec.rb +1 -0
- data/spec/features/status_spec.rb +43 -0
- data/spec/features/support/email_server.rb +5 -2
- data/spec/features/support/shared/connection_context.rb +7 -5
- data/spec/support/higline_test_helpers.rb +1 -1
- data/spec/support/silence_logging.rb +1 -1
- data/spec/unit/email/provider/base_spec.rb +1 -1
- data/spec/unit/email/provider_spec.rb +2 -2
- data/spec/unit/imap/backup/account/connection_spec.rb +22 -26
- data/spec/unit/imap/backup/cli/accounts_spec.rb +47 -0
- data/spec/unit/imap/backup/cli/local_spec.rb +15 -4
- data/spec/unit/imap/backup/cli/utils_spec.rb +54 -42
- data/spec/unit/imap/backup/{configuration/store_spec.rb → configuration_spec.rb} +23 -24
- data/spec/unit/imap/backup/downloader_spec.rb +1 -1
- data/spec/unit/imap/backup/logger_spec.rb +48 -0
- data/spec/unit/imap/backup/{configuration → setup}/account_spec.rb +78 -70
- data/spec/unit/imap/backup/{configuration → setup}/asker_spec.rb +2 -2
- data/spec/unit/imap/backup/{configuration → setup}/connection_tester_spec.rb +10 -10
- data/spec/unit/imap/backup/{configuration → setup}/folder_chooser_spec.rb +25 -26
- data/spec/unit/imap/backup/{configuration/setup_spec.rb → setup_spec.rb} +81 -52
- metadata +51 -48
- data/lib/imap/backup/configuration/connection_tester.rb +0 -14
- data/lib/imap/backup/configuration/list.rb +0 -53
- data/spec/support/shared_examples/account_flagging.rb +0 -23
- data/spec/unit/imap/backup/configuration/list_spec.rb +0 -89
- data/spec/unit/imap/backup_spec.rb +0 -28
@@ -0,0 +1,42 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "singleton"
|
3
|
+
|
4
|
+
require "imap/backup/configuration"
|
5
|
+
require "imap/backup/sanitizer"
|
6
|
+
|
7
|
+
module Imap::Backup
|
8
|
+
class Logger
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
Logger.instance.logger
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.setup_logging(config = Configuration.new)
|
16
|
+
logger.level =
|
17
|
+
if config.debug?
|
18
|
+
::Logger::Severity::DEBUG
|
19
|
+
else
|
20
|
+
::Logger::Severity::ERROR
|
21
|
+
end
|
22
|
+
Net::IMAP.debug = config.debug?
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.sanitize_stderr
|
26
|
+
sanitizer = Sanitizer.new($stdout)
|
27
|
+
previous_stderr = $stderr
|
28
|
+
$stderr = sanitizer
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
sanitizer.flush
|
32
|
+
$stderr = previous_stderr
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :logger
|
36
|
+
|
37
|
+
def initialize
|
38
|
+
@logger = ::Logger.new($stdout)
|
39
|
+
$stdout.sync = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Imap::Backup
|
2
|
+
class Sanitizer
|
3
|
+
attr_reader :output
|
4
|
+
|
5
|
+
def initialize(output)
|
6
|
+
@output = output
|
7
|
+
@current = ""
|
8
|
+
end
|
9
|
+
|
10
|
+
def write(*args)
|
11
|
+
output.write(*args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def print(*args)
|
15
|
+
@current << args.join
|
16
|
+
loop do
|
17
|
+
line, newline, rest = @current.partition("\n")
|
18
|
+
break if newline != "\n"
|
19
|
+
clean = sanitize(line)
|
20
|
+
output.puts clean
|
21
|
+
@current = rest
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def flush
|
26
|
+
return if @current == ""
|
27
|
+
|
28
|
+
clean = sanitize(@current)
|
29
|
+
output.puts clean
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def sanitize(t)
|
35
|
+
# Hide password in Net::IMAP debug output
|
36
|
+
t.gsub(
|
37
|
+
/\A(C: RUBY\d+ LOGIN \S+) \S+/,
|
38
|
+
"\\1 [PASSWORD REDACTED]"
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -46,7 +46,7 @@ module Imap::Backup
|
|
46
46
|
|
47
47
|
uid = uid.to_i
|
48
48
|
if uids.include?(uid)
|
49
|
-
Imap::Backup.logger.debug(
|
49
|
+
Imap::Backup::Logger.logger.debug(
|
50
50
|
"[#{folder}] message #{uid} already downloaded - skipping"
|
51
51
|
)
|
52
52
|
return
|
@@ -65,7 +65,7 @@ module Imap::Backup
|
|
65
65
|
#{body}. #{e}:
|
66
66
|
#{e.backtrace.join("\n")}"
|
67
67
|
ERROR
|
68
|
-
Imap::Backup.logger.warn message
|
68
|
+
Imap::Backup::Logger.logger.warn message
|
69
69
|
ensure
|
70
70
|
mbox&.close
|
71
71
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
require "imap/backup/setup/helpers"
|
2
|
+
|
1
3
|
module Imap::Backup
|
2
|
-
|
4
|
+
class Setup; end
|
3
5
|
|
4
|
-
|
5
|
-
def initialize(
|
6
|
+
Setup::Account = Struct.new(:config, :account, :highline) do
|
7
|
+
def initialize(config, account, highline)
|
6
8
|
super
|
7
9
|
end
|
8
10
|
|
@@ -22,78 +24,91 @@ module Imap::Backup
|
|
22
24
|
header menu
|
23
25
|
modify_email menu
|
24
26
|
modify_password menu
|
25
|
-
modify_server menu
|
26
27
|
modify_backup_path menu
|
27
28
|
choose_folders menu
|
29
|
+
modify_server menu
|
30
|
+
modify_connection_options menu
|
28
31
|
test_connection menu
|
29
32
|
delete_account menu
|
30
|
-
menu.choice("return to main menu") { throw :done }
|
33
|
+
menu.choice("(q) return to main menu") { throw :done }
|
31
34
|
menu.hidden("quit") { throw :done }
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
35
38
|
def header(menu)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
modified = account.modified? ? "*" : ""
|
40
|
+
connection_options =
|
41
|
+
if account.connection_options
|
42
|
+
escaped =
|
43
|
+
JSON.generate(account.connection_options).
|
44
|
+
gsub('"', '\"')
|
45
|
+
"\n connection options #{escaped}"
|
46
|
+
end
|
47
|
+
menu.header = <<~HEADER.chomp
|
48
|
+
#{helpers.title_prefix} Account#{modified}
|
49
|
+
|
50
|
+
email #{account.username}
|
51
|
+
password #{masked_password}
|
52
|
+
path #{account.local_path}
|
53
|
+
folders #{folders.map { |f| f[:name] }.join(', ')}
|
54
|
+
server #{account.server}#{connection_options}
|
55
|
+
|
56
|
+
Choose an action
|
43
57
|
HEADER
|
44
58
|
end
|
45
59
|
|
46
60
|
def modify_email(menu)
|
47
61
|
menu.choice("modify email") do
|
48
|
-
username =
|
62
|
+
username = Setup::Asker.email(username)
|
49
63
|
Kernel.puts "username: #{username}"
|
50
|
-
other_accounts =
|
51
|
-
others = other_accounts.map { |a| a
|
64
|
+
other_accounts = config.accounts.reject { |a| a == account }
|
65
|
+
others = other_accounts.map { |a| a.username }
|
52
66
|
Kernel.puts "others: #{others.inspect}"
|
53
67
|
if others.include?(username)
|
54
68
|
Kernel.puts(
|
55
69
|
"There is already an account set up with that email address"
|
56
70
|
)
|
57
71
|
else
|
58
|
-
account
|
72
|
+
account.username = username
|
59
73
|
# rubocop:disable Style/IfUnlessModifier
|
60
|
-
|
61
|
-
|
74
|
+
default = default_server(username)
|
75
|
+
if default && (account.server.nil? || (account.server == ""))
|
76
|
+
account.server = default
|
62
77
|
end
|
63
78
|
# rubocop:enable Style/IfUnlessModifier
|
64
|
-
account[:modified] = true
|
65
79
|
end
|
66
80
|
end
|
67
81
|
end
|
68
82
|
|
69
83
|
def modify_password(menu)
|
70
84
|
menu.choice("modify password") do
|
71
|
-
password =
|
85
|
+
password = Setup::Asker.password
|
72
86
|
|
73
|
-
if !password.nil?
|
74
|
-
account[:password] = password
|
75
|
-
account[:modified] = true
|
76
|
-
end
|
87
|
+
account.password = password if !password.nil?
|
77
88
|
end
|
78
89
|
end
|
79
90
|
|
80
91
|
def modify_server(menu)
|
81
92
|
menu.choice("modify server") do
|
82
93
|
server = highline.ask("server: ")
|
83
|
-
if !server.nil?
|
84
|
-
|
85
|
-
|
86
|
-
|
94
|
+
account.server = server if !server.nil?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def modify_connection_options(menu)
|
99
|
+
menu.choice("modify connection options") do
|
100
|
+
connection_options = highline.ask("connections options (as JSON): ")
|
101
|
+
account.connection_options = connection_options if !connection_options.nil?
|
87
102
|
end
|
88
103
|
end
|
89
104
|
|
90
105
|
def path_modification_validator(path)
|
91
|
-
same =
|
92
|
-
a
|
106
|
+
same = config.accounts.find do |a|
|
107
|
+
a.username != account.username && a.local_path == path
|
93
108
|
end
|
94
109
|
if same
|
95
110
|
Kernel.puts "The path '#{path}' is used to backup " \
|
96
|
-
"the account '#{same
|
111
|
+
"the account '#{same.username}'"
|
97
112
|
false
|
98
113
|
else
|
99
114
|
true
|
@@ -102,23 +117,22 @@ module Imap::Backup
|
|
102
117
|
|
103
118
|
def modify_backup_path(menu)
|
104
119
|
menu.choice("modify backup path") do
|
105
|
-
existing = account
|
106
|
-
account
|
107
|
-
account
|
120
|
+
existing = account.local_path.clone
|
121
|
+
account.local_path = Setup::Asker.backup_path(
|
122
|
+
account.local_path, ->(path) { path_modification_validator(path) }
|
108
123
|
)
|
109
|
-
account[:modified] = true if existing != account[:local_path]
|
110
124
|
end
|
111
125
|
end
|
112
126
|
|
113
127
|
def choose_folders(menu)
|
114
128
|
menu.choice("choose backup folders") do
|
115
|
-
|
129
|
+
Setup::FolderChooser.new(account).run
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
119
133
|
def test_connection(menu)
|
120
134
|
menu.choice("test connection") do
|
121
|
-
result =
|
135
|
+
result = Setup::ConnectionTester.new(account).test
|
122
136
|
Kernel.puts result
|
123
137
|
highline.ask "Press a key "
|
124
138
|
end
|
@@ -127,21 +141,21 @@ module Imap::Backup
|
|
127
141
|
def delete_account(menu)
|
128
142
|
menu.choice("delete") do
|
129
143
|
if highline.agree("Are you sure? (y/n) ")
|
130
|
-
account
|
144
|
+
account.mark_for_deletion!
|
131
145
|
throw :done
|
132
146
|
end
|
133
147
|
end
|
134
148
|
end
|
135
149
|
|
136
150
|
def folders
|
137
|
-
account
|
151
|
+
account.folders || []
|
138
152
|
end
|
139
153
|
|
140
154
|
def masked_password
|
141
|
-
if (account
|
155
|
+
if (account.password == "") || account.password.nil?
|
142
156
|
"(unset)"
|
143
157
|
else
|
144
|
-
account
|
158
|
+
account.password.gsub(/./, "x")
|
145
159
|
end
|
146
160
|
end
|
147
161
|
|
@@ -155,5 +169,9 @@ module Imap::Backup
|
|
155
169
|
|
156
170
|
provider.host
|
157
171
|
end
|
172
|
+
|
173
|
+
def helpers
|
174
|
+
Setup::Helpers.new
|
175
|
+
end
|
158
176
|
end
|
159
177
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Imap::Backup
|
2
|
-
|
2
|
+
class Setup; end
|
3
3
|
|
4
|
-
|
4
|
+
Setup::Asker = Struct.new(:highline) do
|
5
5
|
EMAIL_MATCHER = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i.freeze
|
6
6
|
|
7
7
|
def initialize(highline)
|
@@ -40,15 +40,15 @@ module Imap::Backup
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def self.email(default = "")
|
43
|
-
new(
|
43
|
+
new(Setup.highline).email(default)
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.password
|
47
|
-
new(
|
47
|
+
new(Setup.highline).password
|
48
48
|
end
|
49
49
|
|
50
50
|
def self.backup_path(default, validator)
|
51
|
-
new(
|
51
|
+
new(Setup.highline).backup_path(default, validator)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Imap::Backup
|
2
|
+
class Setup; end
|
3
|
+
|
4
|
+
class Setup::ConnectionTester
|
5
|
+
attr_reader :account
|
6
|
+
|
7
|
+
def initialize(account)
|
8
|
+
@account = account
|
9
|
+
end
|
10
|
+
|
11
|
+
def test
|
12
|
+
connection.client
|
13
|
+
"Connection successful"
|
14
|
+
rescue Net::IMAP::NoResponseError
|
15
|
+
"No response"
|
16
|
+
rescue StandardError => e
|
17
|
+
"Unexpected error: #{e}"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def connection
|
23
|
+
Account::Connection.new(account)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require "imap/backup/setup/helpers"
|
2
|
+
|
1
3
|
module Imap::Backup
|
2
|
-
|
4
|
+
class Setup; end
|
3
5
|
|
4
|
-
class
|
6
|
+
class Setup::FolderChooser
|
5
7
|
attr_reader :account
|
6
8
|
|
7
9
|
def initialize(account)
|
@@ -10,13 +12,13 @@ module Imap::Backup
|
|
10
12
|
|
11
13
|
def run
|
12
14
|
if connection.nil?
|
13
|
-
Imap::Backup.logger.warn "Connection failed"
|
15
|
+
Imap::Backup::Logger.logger.warn "Connection failed"
|
14
16
|
highline.ask "Press a key "
|
15
17
|
return
|
16
18
|
end
|
17
19
|
|
18
20
|
if imap_folders.nil?
|
19
|
-
Imap::Backup.logger.warn "Unable to get folder list"
|
21
|
+
Imap::Backup::Logger.logger.warn "Unable to get folder list"
|
20
22
|
highline.ask "Press a key "
|
21
23
|
return
|
22
24
|
end
|
@@ -35,10 +37,14 @@ module Imap::Backup
|
|
35
37
|
|
36
38
|
def show_menu
|
37
39
|
highline.choose do |menu|
|
38
|
-
menu.header =
|
40
|
+
menu.header = <<~MENU.chomp
|
41
|
+
#{helpers.title_prefix} Add/remove folders
|
42
|
+
|
43
|
+
Select a folder (toggles)
|
44
|
+
MENU
|
39
45
|
menu.index = :number
|
40
46
|
add_folders menu
|
41
|
-
menu.choice("return to the account menu") { throw :done }
|
47
|
+
menu.choice("(q) return to the account menu") { throw :done }
|
42
48
|
menu.hidden("quit") { throw :done }
|
43
49
|
end
|
44
50
|
end
|
@@ -53,7 +59,7 @@ module Imap::Backup
|
|
53
59
|
end
|
54
60
|
|
55
61
|
def selected?(folder_name)
|
56
|
-
config_folders = account
|
62
|
+
config_folders = account.folders
|
57
63
|
return false if config_folders.nil?
|
58
64
|
|
59
65
|
config_folders.find { |f| f[:name] == folder_name }
|
@@ -62,7 +68,7 @@ module Imap::Backup
|
|
62
68
|
def remove_missing
|
63
69
|
removed = []
|
64
70
|
config_folders = []
|
65
|
-
account
|
71
|
+
account.folders.each do |f|
|
66
72
|
found = imap_folders.find { |folder| folder == f[:name] }
|
67
73
|
if found
|
68
74
|
config_folders << f
|
@@ -73,8 +79,7 @@ module Imap::Backup
|
|
73
79
|
|
74
80
|
return if removed.empty?
|
75
81
|
|
76
|
-
account
|
77
|
-
account[:modified] = true
|
82
|
+
account.folders = config_folders
|
78
83
|
|
79
84
|
Kernel.puts <<~MESSAGE
|
80
85
|
The following folders have been removed: #{removed.join(', ')}
|
@@ -85,12 +90,11 @@ module Imap::Backup
|
|
85
90
|
|
86
91
|
def toggle_selection(folder_name)
|
87
92
|
if selected?(folder_name)
|
88
|
-
|
89
|
-
account
|
93
|
+
new_list = account.folders.select { |f| f[:name] != folder_name }
|
94
|
+
account.folders = new_list
|
90
95
|
else
|
91
|
-
account
|
92
|
-
account
|
93
|
-
account[:modified] = true
|
96
|
+
existing = account.folders || []
|
97
|
+
account.folders = existing + [{name: folder_name}]
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
@@ -101,11 +105,15 @@ module Imap::Backup
|
|
101
105
|
end
|
102
106
|
|
103
107
|
def imap_folders
|
104
|
-
@imap_folders ||= connection.
|
108
|
+
@imap_folders ||= connection.folder_names
|
105
109
|
end
|
106
110
|
|
107
111
|
def highline
|
108
|
-
|
112
|
+
Setup.highline
|
113
|
+
end
|
114
|
+
|
115
|
+
def helpers
|
116
|
+
Setup::Helpers.new
|
109
117
|
end
|
110
118
|
end
|
111
119
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
require "highline"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require "imap/backup/account"
|
4
|
+
require "imap/backup/setup/helpers"
|
5
5
|
|
6
|
-
|
6
|
+
module Imap::Backup
|
7
|
+
class Setup
|
7
8
|
class << self
|
8
9
|
attr_accessor :highline
|
9
10
|
end
|
10
11
|
self.highline = HighLine.new
|
11
12
|
|
12
13
|
def run
|
13
|
-
Imap::Backup.setup_logging config
|
14
14
|
catch :done do
|
15
15
|
loop do
|
16
16
|
Kernel.system("clear")
|
@@ -23,35 +23,41 @@ module Imap::Backup
|
|
23
23
|
|
24
24
|
def show_menu
|
25
25
|
self.class.highline.choose do |menu|
|
26
|
-
menu.header =
|
26
|
+
menu.header = <<~MENU.chomp
|
27
|
+
#{helpers.title_prefix} Main Menu
|
28
|
+
|
29
|
+
Choose an action
|
30
|
+
MENU
|
27
31
|
account_items menu
|
28
32
|
add_account_item menu
|
29
33
|
toggle_logging_item menu
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
throw :done
|
34
|
+
if config.modified?
|
35
|
+
menu.choice("save and exit") do
|
36
|
+
config.save
|
37
|
+
throw :done
|
38
|
+
end
|
39
|
+
menu.choice("exit without saving changes") { throw :done }
|
40
|
+
else
|
41
|
+
menu.choice("quit") { throw :done }
|
36
42
|
end
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
46
|
def account_items(menu)
|
41
47
|
config.accounts.each do |account|
|
42
|
-
next if account
|
48
|
+
next if account.marked_for_deletion?
|
43
49
|
|
44
|
-
item = account
|
45
|
-
item << " *" if account
|
50
|
+
item = account.username.clone
|
51
|
+
item << " *" if account.modified?
|
46
52
|
menu.choice(item) do
|
47
|
-
edit_account account
|
53
|
+
edit_account account.username
|
48
54
|
end
|
49
55
|
end
|
50
56
|
end
|
51
57
|
|
52
58
|
def add_account_item(menu)
|
53
59
|
menu.choice("add account") do
|
54
|
-
username =
|
60
|
+
username = Asker.email
|
55
61
|
edit_account username
|
56
62
|
end
|
57
63
|
end
|
@@ -61,35 +67,37 @@ module Imap::Backup
|
|
61
67
|
new_setting = !config.debug?
|
62
68
|
menu.choice(menu_item) do
|
63
69
|
config.debug = new_setting
|
64
|
-
Imap::Backup.setup_logging
|
70
|
+
Imap::Backup::Logger.setup_logging(config)
|
65
71
|
end
|
66
72
|
end
|
67
73
|
|
68
74
|
def config
|
69
|
-
@config ||= Configuration
|
75
|
+
@config ||= Configuration.new
|
70
76
|
end
|
71
77
|
|
72
78
|
def default_account_config(username)
|
73
|
-
|
79
|
+
::Imap::Backup::Account.new(
|
74
80
|
username: username,
|
75
81
|
password: "",
|
76
82
|
local_path: File.join(config.path, username.tr("@", "_")),
|
77
83
|
folders: []
|
78
|
-
|
84
|
+
).tap do |a|
|
79
85
|
server = Email::Provider.for_address(username)
|
80
|
-
|
86
|
+
a.server = server.host if server.host
|
81
87
|
end
|
82
88
|
end
|
83
89
|
|
84
90
|
def edit_account(username)
|
85
|
-
account = config.accounts.find { |a| a
|
91
|
+
account = config.accounts.find { |a| a.username == username }
|
86
92
|
if account.nil?
|
87
93
|
account = default_account_config(username)
|
88
94
|
config.accounts << account
|
89
95
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
96
|
+
Account.new(config, account, Setup.highline).run
|
97
|
+
end
|
98
|
+
|
99
|
+
def helpers
|
100
|
+
Helpers.new
|
93
101
|
end
|
94
102
|
end
|
95
103
|
end
|
data/lib/imap/backup/uploader.rb
CHANGED
@@ -12,12 +12,12 @@ module Imap::Backup
|
|
12
12
|
count = missing_uids.count
|
13
13
|
return if count.zero?
|
14
14
|
|
15
|
-
Imap::Backup.logger.debug "[#{folder.name}] #{count} to restore"
|
15
|
+
Imap::Backup::Logger.logger.debug "[#{folder.name}] #{count} to restore"
|
16
16
|
serializer.each_message(missing_uids).with_index do |(uid, message), i|
|
17
17
|
next if message.nil?
|
18
18
|
|
19
19
|
log_prefix = "[#{folder.name}] uid: #{uid} (#{i + 1}/#{count}) -"
|
20
|
-
Imap::Backup.logger.debug(
|
20
|
+
Imap::Backup::Logger.logger.debug(
|
21
21
|
"#{log_prefix} #{message.supplied_body.size} bytes"
|
22
22
|
)
|
23
23
|
|
data/lib/imap/backup/version.rb
CHANGED
data/lib/imap/backup.rb
CHANGED
@@ -3,46 +3,20 @@ module Imap; end
|
|
3
3
|
require "imap/backup/utils"
|
4
4
|
require "imap/backup/account/connection"
|
5
5
|
require "imap/backup/account/folder"
|
6
|
-
require "imap/backup/configuration
|
7
|
-
require "imap/backup/configuration/asker"
|
8
|
-
require "imap/backup/configuration/connection_tester"
|
9
|
-
require "imap/backup/configuration/folder_chooser"
|
10
|
-
require "imap/backup/configuration/list"
|
11
|
-
require "imap/backup/configuration/setup"
|
12
|
-
require "imap/backup/configuration/store"
|
6
|
+
require "imap/backup/configuration"
|
13
7
|
require "imap/backup/downloader"
|
8
|
+
require "imap/backup/logger"
|
14
9
|
require "imap/backup/uploader"
|
15
10
|
require "imap/backup/serializer"
|
16
11
|
require "imap/backup/serializer/mbox"
|
12
|
+
require "imap/backup/setup"
|
13
|
+
require "imap/backup/setup/account"
|
14
|
+
require "imap/backup/setup/asker"
|
15
|
+
require "imap/backup/setup/connection_tester"
|
16
|
+
require "imap/backup/setup/folder_chooser"
|
17
17
|
require "imap/backup/version"
|
18
18
|
require "email/provider"
|
19
19
|
|
20
|
-
require "logger"
|
21
|
-
|
22
20
|
module Imap::Backup
|
23
21
|
class ConfigurationNotFound < StandardError; end
|
24
|
-
|
25
|
-
class Logger
|
26
|
-
include Singleton
|
27
|
-
|
28
|
-
attr_reader :logger
|
29
|
-
|
30
|
-
def initialize
|
31
|
-
@logger = ::Logger.new($stdout)
|
32
|
-
$stdout.sync = true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.logger
|
37
|
-
Logger.instance.logger
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.setup_logging(config)
|
41
|
-
logger.level =
|
42
|
-
if config.debug?
|
43
|
-
::Logger::Severity::DEBUG
|
44
|
-
else
|
45
|
-
::Logger::Severity::ERROR
|
46
|
-
end
|
47
|
-
end
|
48
22
|
end
|