imap-backup 4.0.3 → 4.0.7
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/lib/email/provider/apple_mail.rb +2 -2
- data/lib/email/provider/base.rb +8 -0
- data/lib/email/provider/fastmail.rb +2 -2
- data/lib/email/provider/gmail.rb +2 -2
- data/lib/email/provider/{default.rb → unknown.rb} +2 -3
- data/lib/email/provider.rb +2 -2
- data/lib/imap/backup/account/connection.rb +23 -31
- data/lib/imap/backup/account/folder.rb +1 -1
- data/lib/imap/backup/account.rb +98 -0
- data/lib/imap/backup/cli/helpers.rb +1 -1
- data/lib/imap/backup/cli/local.rb +1 -1
- data/lib/imap/backup/configuration/account.rb +38 -30
- data/lib/imap/backup/configuration/folder_chooser.rb +7 -9
- data/lib/imap/backup/configuration/list.rb +1 -1
- data/lib/imap/backup/configuration/setup.rb +10 -8
- data/lib/imap/backup/configuration/store.rb +33 -11
- data/lib/imap/backup/version.rb +1 -1
- data/lib/imap/backup.rb +1 -0
- data/spec/features/support/shared/connection_context.rb +7 -5
- data/spec/unit/email/provider/{default_spec.rb → base_spec.rb} +1 -7
- data/spec/unit/email/provider_spec.rb +2 -2
- data/spec/unit/imap/backup/account/connection_spec.rb +8 -17
- data/spec/unit/imap/backup/cli/local_spec.rb +9 -2
- data/spec/unit/imap/backup/cli/utils_spec.rb +44 -42
- data/spec/unit/imap/backup/configuration/account_spec.rb +47 -46
- data/spec/unit/imap/backup/configuration/folder_chooser_spec.rb +17 -18
- data/spec/unit/imap/backup/configuration/list_spec.rb +12 -5
- data/spec/unit/imap/backup/configuration/setup_spec.rb +33 -12
- data/spec/unit/imap/backup/configuration/store_spec.rb +21 -22
- metadata +32 -32
- data/spec/support/shared_examples/account_flagging.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5819f0b50ce3de10cfedb1cdb5381e51f2d94f00dc2bcdd99234f57855c9959d
|
4
|
+
data.tar.gz: a140267c179d6002a7186f8591743abbfea2dca7697b7f1761feaa359fd1521c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b7d49f159df4d29582cf98f01ce105769301bcf94fd019486f1e0b43321eb90594e16861e24fe9d7993a76eeba0c115d6d991b64c1188020b09d04ea8db0714
|
7
|
+
data.tar.gz: 7dacdd3c5c3835e1925cd36a3beaaf7cdf6bf98d4bf7f02bbdd4abe3635512708c03654c3da9dfbfcf35f4e94a46dd43a3fc9e6e4693dd2b943d34d4a9ec8b02
|
data/lib/email/provider/gmail.rb
CHANGED
data/lib/email/provider.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require "email/provider/default"
|
2
1
|
require "email/provider/apple_mail"
|
3
2
|
require "email/provider/fastmail"
|
4
3
|
require "email/provider/gmail"
|
4
|
+
require "email/provider/unknown"
|
5
5
|
|
6
6
|
module Email; end
|
7
7
|
|
@@ -21,7 +21,7 @@ class Email::Provider
|
|
21
21
|
when address.end_with?("@me.com")
|
22
22
|
Email::Provider::AppleMail.new
|
23
23
|
else
|
24
|
-
Email::Provider::
|
24
|
+
Email::Provider::Unknown.new
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -4,25 +4,17 @@ require "imap/backup/client/default"
|
|
4
4
|
require "retry_on_error"
|
5
5
|
|
6
6
|
module Imap::Backup
|
7
|
-
|
7
|
+
class Account; end
|
8
8
|
|
9
9
|
class Account::Connection
|
10
10
|
include RetryOnError
|
11
11
|
|
12
12
|
LOGIN_RETRY_CLASSES = [EOFError, Errno::ECONNRESET, SocketError].freeze
|
13
13
|
|
14
|
-
attr_reader :
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def initialize(options)
|
20
|
-
@username = options[:username]
|
21
|
-
@password = options[:password]
|
22
|
-
@local_path = options[:local_path]
|
23
|
-
@config_folders = options[:folders]
|
24
|
-
@server = options[:server]
|
25
|
-
@connection_options = options[:connection_options] || {}
|
14
|
+
attr_reader :account
|
15
|
+
|
16
|
+
def initialize(account)
|
17
|
+
@account = account
|
26
18
|
@folders = nil
|
27
19
|
create_account_folder
|
28
20
|
end
|
@@ -33,7 +25,7 @@ module Imap::Backup
|
|
33
25
|
folders = client.list
|
34
26
|
|
35
27
|
if folders.empty?
|
36
|
-
message = "Unable to get folder list for account #{username}"
|
28
|
+
message = "Unable to get folder list for account #{account.username}"
|
37
29
|
Imap::Backup.logger.info message
|
38
30
|
raise message
|
39
31
|
end
|
@@ -45,13 +37,13 @@ module Imap::Backup
|
|
45
37
|
def status
|
46
38
|
backup_folders.map do |backup_folder|
|
47
39
|
f = Account::Folder.new(self, backup_folder[:name])
|
48
|
-
s = Serializer::Mbox.new(local_path, backup_folder[:name])
|
40
|
+
s = Serializer::Mbox.new(account.local_path, backup_folder[:name])
|
49
41
|
{name: backup_folder[:name], local: s.uids, remote: f.uids}
|
50
42
|
end
|
51
43
|
end
|
52
44
|
|
53
45
|
def run_backup
|
54
|
-
Imap::Backup.logger.debug "Running backup of account: #{username}"
|
46
|
+
Imap::Backup.logger.debug "Running backup of account: #{account.username}"
|
55
47
|
# start the connection so we get logging messages in the right order
|
56
48
|
client
|
57
49
|
each_folder do |folder, serializer|
|
@@ -71,11 +63,11 @@ module Imap::Backup
|
|
71
63
|
def local_folders
|
72
64
|
return enum_for(:local_folders) if !block_given?
|
73
65
|
|
74
|
-
glob = File.join(local_path, "**", "*.imap")
|
75
|
-
base = Pathname.new(local_path)
|
66
|
+
glob = File.join(account.local_path, "**", "*.imap")
|
67
|
+
base = Pathname.new(account.local_path)
|
76
68
|
Pathname.glob(glob) do |path|
|
77
69
|
name = path.relative_path_from(base).to_s[0..-6]
|
78
|
-
serializer = Serializer::Mbox.new(local_path, name)
|
70
|
+
serializer = Serializer::Mbox.new(account.local_path, name)
|
79
71
|
folder = Account::Folder.new(self, name)
|
80
72
|
yield serializer, folder
|
81
73
|
end
|
@@ -109,15 +101,15 @@ module Imap::Backup
|
|
109
101
|
else
|
110
102
|
Client::Default.new(server, options)
|
111
103
|
end
|
112
|
-
Imap::Backup.logger.debug "Logging in: #{username}/#{masked_password}"
|
113
|
-
client.login(username, password)
|
104
|
+
Imap::Backup.logger.debug "Logging in: #{account.username}/#{masked_password}"
|
105
|
+
client.login(account.username, account.password)
|
114
106
|
Imap::Backup.logger.debug "Login complete"
|
115
107
|
client
|
116
108
|
end
|
117
109
|
end
|
118
110
|
|
119
111
|
def server
|
120
|
-
@server ||= provider.host
|
112
|
+
@server ||= account.server || provider.host
|
121
113
|
end
|
122
114
|
|
123
115
|
private
|
@@ -125,7 +117,7 @@ module Imap::Backup
|
|
125
117
|
def each_folder
|
126
118
|
backup_folders.each do |backup_folder|
|
127
119
|
folder = Account::Folder.new(self, backup_folder[:name])
|
128
|
-
serializer = Serializer::Mbox.new(local_path, backup_folder[:name])
|
120
|
+
serializer = Serializer::Mbox.new(account.local_path, backup_folder[:name])
|
129
121
|
yield folder, serializer
|
130
122
|
end
|
131
123
|
end
|
@@ -142,7 +134,7 @@ module Imap::Backup
|
|
142
134
|
Imap::Backup.logger.debug(
|
143
135
|
"Backup '#{old_name}' renamed and restored to '#{new_name}'"
|
144
136
|
)
|
145
|
-
new_serializer = Serializer::Mbox.new(local_path, new_name)
|
137
|
+
new_serializer = Serializer::Mbox.new(account.local_path, new_name)
|
146
138
|
new_folder = Account::Folder.new(self, new_name)
|
147
139
|
new_folder.create
|
148
140
|
new_serializer.force_uid_validity(new_folder.uid_validity)
|
@@ -159,21 +151,21 @@ module Imap::Backup
|
|
159
151
|
|
160
152
|
def create_account_folder
|
161
153
|
Utils.make_folder(
|
162
|
-
File.dirname(local_path),
|
163
|
-
File.basename(local_path),
|
154
|
+
File.dirname(account.local_path),
|
155
|
+
File.basename(account.local_path),
|
164
156
|
Serializer::DIRECTORY_PERMISSIONS
|
165
157
|
)
|
166
158
|
end
|
167
159
|
|
168
160
|
def masked_password
|
169
|
-
password.gsub(/./, "x")
|
161
|
+
account.password.gsub(/./, "x")
|
170
162
|
end
|
171
163
|
|
172
164
|
def backup_folders
|
173
165
|
@backup_folders ||=
|
174
166
|
begin
|
175
|
-
if
|
176
|
-
|
167
|
+
if account.folders&.any?
|
168
|
+
account.folders
|
177
169
|
else
|
178
170
|
folders.map { |name| {name: name} }
|
179
171
|
end
|
@@ -181,11 +173,11 @@ module Imap::Backup
|
|
181
173
|
end
|
182
174
|
|
183
175
|
def provider
|
184
|
-
@provider ||= Email::Provider.for_address(username)
|
176
|
+
@provider ||= Email::Provider.for_address(account.username)
|
185
177
|
end
|
186
178
|
|
187
179
|
def provider_options
|
188
|
-
provider.options.merge(connection_options)
|
180
|
+
provider.options.merge(account.connection_options || {})
|
189
181
|
end
|
190
182
|
end
|
191
183
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Imap::Backup
|
2
|
+
class Account
|
3
|
+
attr_reader :username
|
4
|
+
attr_reader :password
|
5
|
+
attr_reader :local_path
|
6
|
+
attr_reader :folders
|
7
|
+
attr_reader :server
|
8
|
+
attr_reader :connection_options
|
9
|
+
attr_reader :changes
|
10
|
+
attr_reader :marked_for_deletion
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
@username = options[:username]
|
14
|
+
@password = options[:password]
|
15
|
+
@local_path = options[:local_path]
|
16
|
+
@folders = options[:folders]
|
17
|
+
@server = options[:server]
|
18
|
+
@connection_options = options[:connection_options]
|
19
|
+
@changes = {}
|
20
|
+
@marked_for_deletion = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
username && password
|
25
|
+
end
|
26
|
+
|
27
|
+
def modified?
|
28
|
+
changes.any?
|
29
|
+
end
|
30
|
+
|
31
|
+
def clear_changes!
|
32
|
+
@changes = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def mark_for_deletion!
|
36
|
+
@marked_for_deletion = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def marked_for_deletion?
|
40
|
+
@marked_for_deletion
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_h
|
44
|
+
h = {
|
45
|
+
username: @username,
|
46
|
+
password: @password,
|
47
|
+
}
|
48
|
+
h[:local_path] = @local_path if @local_path
|
49
|
+
h[:folders] = @folders if @folders
|
50
|
+
h[:server] = @server if @server
|
51
|
+
h[:connection_options] = @connection_options if @connection_options
|
52
|
+
h
|
53
|
+
end
|
54
|
+
|
55
|
+
def username=(value)
|
56
|
+
update(:username, value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def password=(value)
|
60
|
+
update(:password, value)
|
61
|
+
end
|
62
|
+
|
63
|
+
def local_path=(value)
|
64
|
+
update(:local_path, value)
|
65
|
+
end
|
66
|
+
|
67
|
+
def folders=(value)
|
68
|
+
raise "folders must be an Array" if !value.is_a?(Array)
|
69
|
+
update(:folders, value)
|
70
|
+
end
|
71
|
+
|
72
|
+
def server=(value)
|
73
|
+
update(:server, value)
|
74
|
+
end
|
75
|
+
|
76
|
+
def connection_options=(value)
|
77
|
+
parsed = JSON.parse(value)
|
78
|
+
update(:connection_options, parsed)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def update(field, value)
|
84
|
+
if changes[field]
|
85
|
+
change = changes[field]
|
86
|
+
changes.delete(field) if change[:from] == value
|
87
|
+
end
|
88
|
+
set_field!(field, value)
|
89
|
+
end
|
90
|
+
|
91
|
+
def set_field!(field, value)
|
92
|
+
key = :"@#{field}"
|
93
|
+
current = instance_variable_get(key)
|
94
|
+
changes[field] = {from: current, to: value}
|
95
|
+
instance_variable_set(key, value)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -7,7 +7,7 @@ module Imap::Backup::CLI::Helpers
|
|
7
7
|
|
8
8
|
def account(email)
|
9
9
|
connections = Imap::Backup::Configuration::List.new
|
10
|
-
account = connections.accounts.find { |a| a
|
10
|
+
account = connections.accounts.find { |a| a.username == email }
|
11
11
|
raise "#{email} is not a configured account" if !account
|
12
12
|
|
13
13
|
account
|
@@ -6,7 +6,7 @@ module Imap::Backup
|
|
6
6
|
desc "accounts", "List locally backed-up accounts"
|
7
7
|
def accounts
|
8
8
|
connections = Imap::Backup::Configuration::List.new
|
9
|
-
connections.accounts.each { |a| Kernel.puts a
|
9
|
+
connections.accounts.each { |a| Kernel.puts a.username }
|
10
10
|
end
|
11
11
|
|
12
12
|
desc "folders EMAIL", "List account folders"
|
@@ -22,9 +22,10 @@ module Imap::Backup
|
|
22
22
|
header menu
|
23
23
|
modify_email menu
|
24
24
|
modify_password menu
|
25
|
-
modify_server menu
|
26
25
|
modify_backup_path menu
|
27
26
|
choose_folders menu
|
27
|
+
modify_server menu
|
28
|
+
modify_connection_options menu
|
28
29
|
test_connection menu
|
29
30
|
delete_account menu
|
30
31
|
menu.choice("return to main menu") { throw :done }
|
@@ -33,13 +34,20 @@ module Imap::Backup
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def header(menu)
|
36
|
-
|
37
|
+
connection_options =
|
38
|
+
if account.connection_options
|
39
|
+
escaped =
|
40
|
+
JSON.generate(account.connection_options).
|
41
|
+
gsub('"', '\"')
|
42
|
+
"\n connection options: #{escaped}"
|
43
|
+
end
|
44
|
+
menu.header = <<~HEADER
|
37
45
|
Account:
|
38
|
-
email: #{account
|
39
|
-
server: #{account[:server]}
|
40
|
-
path: #{account[:local_path]}
|
41
|
-
folders: #{folders.map { |f| f[:name] }.join(', ')}
|
46
|
+
email: #{account.username}
|
42
47
|
password: #{masked_password}
|
48
|
+
path: #{account.local_path}
|
49
|
+
folders: #{folders.map { |f| f[:name] }.join(', ')}
|
50
|
+
server: #{account.server}#{connection_options}
|
43
51
|
HEADER
|
44
52
|
end
|
45
53
|
|
@@ -48,20 +56,20 @@ module Imap::Backup
|
|
48
56
|
username = Configuration::Asker.email(username)
|
49
57
|
Kernel.puts "username: #{username}"
|
50
58
|
other_accounts = store.accounts.reject { |a| a == account }
|
51
|
-
others = other_accounts.map { |a| a
|
59
|
+
others = other_accounts.map { |a| a.username }
|
52
60
|
Kernel.puts "others: #{others.inspect}"
|
53
61
|
if others.include?(username)
|
54
62
|
Kernel.puts(
|
55
63
|
"There is already an account set up with that email address"
|
56
64
|
)
|
57
65
|
else
|
58
|
-
account
|
66
|
+
account.username = username
|
59
67
|
# rubocop:disable Style/IfUnlessModifier
|
60
|
-
|
61
|
-
|
68
|
+
default = default_server(username)
|
69
|
+
if default && (account.server.nil? || (account.server == ""))
|
70
|
+
account.server = default
|
62
71
|
end
|
63
72
|
# rubocop:enable Style/IfUnlessModifier
|
64
|
-
account[:modified] = true
|
65
73
|
end
|
66
74
|
end
|
67
75
|
end
|
@@ -70,30 +78,31 @@ module Imap::Backup
|
|
70
78
|
menu.choice("modify password") do
|
71
79
|
password = Configuration::Asker.password
|
72
80
|
|
73
|
-
if !password.nil?
|
74
|
-
account[:password] = password
|
75
|
-
account[:modified] = true
|
76
|
-
end
|
81
|
+
account.password = password if !password.nil?
|
77
82
|
end
|
78
83
|
end
|
79
84
|
|
80
85
|
def modify_server(menu)
|
81
86
|
menu.choice("modify server") do
|
82
87
|
server = highline.ask("server: ")
|
83
|
-
if !server.nil?
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
account.server = server if !server.nil?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def modify_connection_options(menu)
|
93
|
+
menu.choice("modify connection options") do
|
94
|
+
connection_options = highline.ask("connections options (as JSON): ")
|
95
|
+
account.connection_options = connection_options if !connection_options.nil?
|
87
96
|
end
|
88
97
|
end
|
89
98
|
|
90
99
|
def path_modification_validator(path)
|
91
100
|
same = store.accounts.find do |a|
|
92
|
-
a
|
101
|
+
a.username != account.username && a.local_path == path
|
93
102
|
end
|
94
103
|
if same
|
95
104
|
Kernel.puts "The path '#{path}' is used to backup " \
|
96
|
-
"the account '#{same
|
105
|
+
"the account '#{same.username}'"
|
97
106
|
false
|
98
107
|
else
|
99
108
|
true
|
@@ -102,11 +111,10 @@ module Imap::Backup
|
|
102
111
|
|
103
112
|
def modify_backup_path(menu)
|
104
113
|
menu.choice("modify backup path") do
|
105
|
-
existing = account
|
106
|
-
account
|
107
|
-
account
|
114
|
+
existing = account.local_path.clone
|
115
|
+
account.local_path = Configuration::Asker.backup_path(
|
116
|
+
account.local_path, ->(path) { path_modification_validator(path) }
|
108
117
|
)
|
109
|
-
account[:modified] = true if existing != account[:local_path]
|
110
118
|
end
|
111
119
|
end
|
112
120
|
|
@@ -127,28 +135,28 @@ module Imap::Backup
|
|
127
135
|
def delete_account(menu)
|
128
136
|
menu.choice("delete") do
|
129
137
|
if highline.agree("Are you sure? (y/n) ")
|
130
|
-
account
|
138
|
+
account.mark_for_deletion!
|
131
139
|
throw :done
|
132
140
|
end
|
133
141
|
end
|
134
142
|
end
|
135
143
|
|
136
144
|
def folders
|
137
|
-
account
|
145
|
+
account.folders || []
|
138
146
|
end
|
139
147
|
|
140
148
|
def masked_password
|
141
|
-
if (account
|
149
|
+
if (account.password == "") || account.password.nil?
|
142
150
|
"(unset)"
|
143
151
|
else
|
144
|
-
account
|
152
|
+
account.password.gsub(/./, "x")
|
145
153
|
end
|
146
154
|
end
|
147
155
|
|
148
156
|
def default_server(username)
|
149
157
|
provider = Email::Provider.for_address(username)
|
150
158
|
|
151
|
-
if provider.is_a?(Email::Provider::
|
159
|
+
if provider.is_a?(Email::Provider::Unknown)
|
152
160
|
Kernel.puts "Can't decide provider for email address '#{username}'"
|
153
161
|
return nil
|
154
162
|
end
|
@@ -53,7 +53,7 @@ module Imap::Backup
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def selected?(folder_name)
|
56
|
-
config_folders = account
|
56
|
+
config_folders = account.folders
|
57
57
|
return false if config_folders.nil?
|
58
58
|
|
59
59
|
config_folders.find { |f| f[:name] == folder_name }
|
@@ -62,7 +62,7 @@ module Imap::Backup
|
|
62
62
|
def remove_missing
|
63
63
|
removed = []
|
64
64
|
config_folders = []
|
65
|
-
account
|
65
|
+
account.folders.each do |f|
|
66
66
|
found = imap_folders.find { |folder| folder == f[:name] }
|
67
67
|
if found
|
68
68
|
config_folders << f
|
@@ -73,8 +73,7 @@ module Imap::Backup
|
|
73
73
|
|
74
74
|
return if removed.empty?
|
75
75
|
|
76
|
-
account
|
77
|
-
account[:modified] = true
|
76
|
+
account.folders = config_folders
|
78
77
|
|
79
78
|
Kernel.puts <<~MESSAGE
|
80
79
|
The following folders have been removed: #{removed.join(', ')}
|
@@ -85,12 +84,11 @@ module Imap::Backup
|
|
85
84
|
|
86
85
|
def toggle_selection(folder_name)
|
87
86
|
if selected?(folder_name)
|
88
|
-
|
89
|
-
account
|
87
|
+
new_list = account.folders.select { |f| f[:name] != folder_name }
|
88
|
+
account.folders = new_list
|
90
89
|
else
|
91
|
-
account
|
92
|
-
account
|
93
|
-
account[:modified] = true
|
90
|
+
existing = account.folders || []
|
91
|
+
account.folders = existing + [{name: folder_name}]
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require "highline"
|
2
2
|
|
3
|
+
require "imap/backup/account"
|
4
|
+
|
3
5
|
module Imap::Backup
|
4
6
|
module Configuration; end
|
5
7
|
|
@@ -39,12 +41,12 @@ module Imap::Backup
|
|
39
41
|
|
40
42
|
def account_items(menu)
|
41
43
|
config.accounts.each do |account|
|
42
|
-
next if account
|
44
|
+
next if account.marked_for_deletion?
|
43
45
|
|
44
|
-
item = account
|
45
|
-
item << " *" if account
|
46
|
+
item = account.username.clone
|
47
|
+
item << " *" if account.modified?
|
46
48
|
menu.choice(item) do
|
47
|
-
edit_account account
|
49
|
+
edit_account account.username
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -70,19 +72,19 @@ module Imap::Backup
|
|
70
72
|
end
|
71
73
|
|
72
74
|
def default_account_config(username)
|
73
|
-
|
75
|
+
::Imap::Backup::Account.new(
|
74
76
|
username: username,
|
75
77
|
password: "",
|
76
78
|
local_path: File.join(config.path, username.tr("@", "_")),
|
77
79
|
folders: []
|
78
|
-
|
80
|
+
).tap do |a|
|
79
81
|
server = Email::Provider.for_address(username)
|
80
|
-
|
82
|
+
a.server = server.host if server.host
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
86
|
def edit_account(username)
|
85
|
-
account = config.accounts.find { |a| a
|
87
|
+
account = config.accounts.find { |a| a.username == username }
|
86
88
|
if account.nil?
|
87
89
|
account = default_account_config(username)
|
88
90
|
config.accounts << account
|