imap-backup 4.0.0 → 4.0.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -49
  3. data/docs/development.md +53 -0
  4. data/docs/restore.md +17 -0
  5. data/imap-backup.gemspec +4 -7
  6. data/lib/email/mboxrd/message.rb +6 -2
  7. data/lib/email/provider/apple_mail.rb +7 -0
  8. data/lib/email/provider/default.rb +12 -0
  9. data/lib/email/provider/fastmail.rb +7 -0
  10. data/lib/email/provider/gmail.rb +7 -0
  11. data/lib/email/provider.rb +16 -26
  12. data/lib/imap/backup/account/connection.rb +19 -29
  13. data/lib/imap/backup/account/folder.rb +9 -10
  14. data/lib/imap/backup/cli/helpers.rb +14 -1
  15. data/lib/imap/backup/cli/local.rb +22 -28
  16. data/lib/imap/backup/cli/setup.rb +1 -1
  17. data/lib/imap/backup/cli/utils.rb +98 -0
  18. data/lib/imap/backup/cli.rb +5 -1
  19. data/lib/imap/backup/client/apple_mail.rb +11 -0
  20. data/lib/imap/backup/client/default.rb +51 -0
  21. data/lib/imap/backup/configuration/account.rb +3 -1
  22. data/lib/imap/backup/configuration/connection_tester.rb +1 -1
  23. data/lib/imap/backup/configuration/store.rb +10 -5
  24. data/lib/imap/backup/downloader.rb +3 -4
  25. data/lib/imap/backup/serializer/mbox.rb +5 -0
  26. data/lib/imap/backup/serializer/mbox_store.rb +8 -8
  27. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +58 -0
  28. data/lib/imap/backup/version.rb +1 -1
  29. data/lib/imap/backup.rb +1 -0
  30. data/lib/thunderbird/install.rb +16 -0
  31. data/lib/thunderbird/local_folder.rb +65 -0
  32. data/lib/thunderbird/profile.rb +30 -0
  33. data/lib/thunderbird/profiles.rb +71 -0
  34. data/lib/thunderbird/subdirectory.rb +96 -0
  35. data/lib/thunderbird/subdirectory_placeholder.rb +21 -0
  36. data/lib/thunderbird.rb +14 -0
  37. data/spec/features/restore_spec.rb +1 -1
  38. data/spec/features/support/email_server.rb +2 -2
  39. data/spec/spec_helper.rb +1 -0
  40. data/spec/unit/email/provider/apple_mail_spec.rb +7 -0
  41. data/spec/unit/email/provider/default_spec.rb +17 -0
  42. data/spec/unit/email/provider/fastmail_spec.rb +7 -0
  43. data/spec/unit/email/provider/gmail_spec.rb +7 -0
  44. data/spec/unit/email/provider_spec.rb +12 -25
  45. data/spec/unit/imap/backup/account/connection_spec.rb +26 -51
  46. data/spec/unit/imap/backup/account/folder_spec.rb +22 -22
  47. data/spec/unit/imap/backup/cli/local_spec.rb +70 -0
  48. data/spec/unit/imap/backup/cli/utils_spec.rb +50 -0
  49. data/spec/unit/imap/backup/client/default_spec.rb +22 -0
  50. data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +3 -3
  51. data/spec/unit/imap/backup/configuration/store_spec.rb +25 -12
  52. data/spec/unit/imap/backup/downloader_spec.rb +1 -2
  53. metadata +71 -28
  54. data/docs/docker-imap.md +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85e081f686a106384d27ffc91cb21965832edd629da671261bda69b668776d5e
4
- data.tar.gz: 8253587491a279e76ebed2268a66b60d9aab4f517cdafadb8c9494e7c3f3648b
3
+ metadata.gz: 69ed28d85dda7c3d30cd6c8d4a9888e9f477eedd6f8ff08741fcc7d27cf087f8
4
+ data.tar.gz: 1a99e7143052a1d0b1b2d58381c5f9da0db2b1e0e3882c24e56036cebead043f
5
5
  SHA512:
6
- metadata.gz: e2b3806cedfe124c286477f50690781c4593db1f3b12d53281c666d3d5771f9a42aa4cc24851fb88f9205a2f11a8e299c74a331a606de1aab056e56b753e3cf1
7
- data.tar.gz: fc96edce37dd33793d04da272f2aea087ad7a16aa409726c83d6cf453bd386e3673a75b8d4e0eee90f352fc1e9168d611865dd87f79c05ff0cf132278bf59df3
6
+ metadata.gz: deb80ed5d629c81253574d96a7da0dcc6382eb6d5216c1f317b8083ca0f4dac80a3188cbc0b7f46ffbc01229dad9ab913858649558ca7b3a29bf7b81395bcce3
7
+ data.tar.gz: 2e6b2b8d2c67c6bc1e3ff5dcbb91c4eec92d0edb87ff33ad6e8a360b6635895c72cc7eb4cc68a7ff24bcfbad5a3533bda0a916e3c4d0c40ee67de70a010d4b2b
data/README.md CHANGED
@@ -16,10 +16,6 @@
16
16
  [Rubygem]: http://rubygems.org/gems/imap-backup "Ruby gem at rubygems.org"
17
17
  [Continuous Integration]: https://circleci.com/gh/joeyates/imap-backup "Build status by CirceCI"
18
18
 
19
- # GMail
20
-
21
- To use imap-backup with GMail, you will need to enable 'App passwords' on your account.
22
-
23
19
  # Installation
24
20
 
25
21
  ```shell
@@ -51,6 +47,10 @@ Run:
51
47
  $ imap-backup setup
52
48
  ```
53
49
 
50
+ ## GMail
51
+
52
+ To use imap-backup with GMail, you will need to enable 'App passwords' on your account.
53
+
54
54
  ## Folders
55
55
 
56
56
  By default, all folders are backed-up. You can override this by choosing
@@ -134,7 +134,15 @@ in the configuration file.
134
134
 
135
135
  The directory ~/.imap-backup, the configuration file and all backup
136
136
  directories have their access permissions set to only allow access
137
- by your user.
137
+ by your user. This is not done on Windows - see below.
138
+
139
+ ## Windows
140
+
141
+ Due to the complexity of managing permissions on Windows,
142
+ directory and file access permissions are not set explicity.
143
+
144
+ A pull request that implements permissions management on Windows
145
+ would be welcome!
138
146
 
139
147
  # Run Backup
140
148
 
@@ -178,6 +186,7 @@ If you have problems:
178
186
  "debug": true
179
187
  }
180
188
  ```
189
+
181
190
  # Restore
182
191
 
183
192
  All missing messages are pushed to the IMAP server.
@@ -206,48 +215,7 @@ $ imap-backup status
206
215
  * Restartable - calculate start point based on already downloaded messages
207
216
  * Standalone - do not rely on an email client or MTA
208
217
 
209
- # Similar Software
210
-
211
- * https://github.com/OfflineIMAP/offlineimap
212
-
213
- # Testing
214
-
215
- ## Integration Tests
216
-
217
- Integration tests (feature specs) are run against a Docker image
218
- (antespi/docker-imap-devel:latest).
219
-
220
- In one shell, run the Docker image:
221
-
222
- ```sh
223
- $ docker run \
224
- --env MAIL_ADDRESS=address@example.org \
225
- --env MAIL_PASS=pass \
226
- --env MAILNAME=example.org \
227
- --publish 8993:993 \
228
- antespi/docker-imap-devel:latest
229
- ```
230
-
231
- ```sh
232
- $ rake
233
- ```
234
-
235
- To exclude Docker-based tests:
236
-
237
- ```sh
238
- rake no-docker
239
- ```
240
-
241
- or
242
-
243
- ```sh
244
- $ rspec --tag ~docker
245
- ```
246
-
247
- ## Contributing
218
+ # Documentation
248
219
 
249
- 1. Fork it
250
- 2. Create your feature branch (`git checkout -b my-new-feature`)
251
- 3. Commit your changes (`git commit -am 'Added some feature'`)
252
- 4. Push to the branch (`git push origin my-new-feature`)
253
- 5. Create new Pull Request
220
+ * [Development](./docs/development.md)
221
+ * [Restore](./docs/restore.md)
@@ -0,0 +1,53 @@
1
+ # Testing
2
+
3
+ ## Integration Tests
4
+
5
+ Integration tests (feature specs) are run against a local IMAP server
6
+ controlled by Docker Compose, which needs to be started
7
+ before running the test suite.
8
+
9
+ ```sh
10
+ $ docker-compose up -d
11
+ ```
12
+
13
+ ```sh
14
+ $ rake
15
+ ```
16
+
17
+ To exclude Docker-based tests:
18
+
19
+ ```sh
20
+ rake no-docker
21
+ ```
22
+
23
+ or
24
+
25
+ ```sh
26
+ $ rspec --tag ~docker
27
+ ```
28
+
29
+ ## Access Docker imap server
30
+
31
+ ```ruby
32
+ require "net/imap"
33
+
34
+ imap = Net::IMAP.new("localhost", {port: 8993, ssl: {verify_mode: 0}})
35
+ username = "address@example.org"
36
+ imap.login(username, "pass")
37
+
38
+ message = "From: #{username}\nSubject: Some Subject\n\nHello!\n"
39
+ response = imap.append("INBOX", message, nil, nil)
40
+
41
+ imap.examine("INBOX")
42
+ uids = imap.uid_search(["ALL"]).sort
43
+
44
+ fetch_data_items = imap.uid_fetch(uids, ["BODY[]"])
45
+ ```
46
+
47
+ # Contributing
48
+
49
+ 1. Fork it
50
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
51
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
52
+ 4. Push to the branch (`git push origin my-new-feature`)
53
+ 5. Create new Pull Request
data/docs/restore.md CHANGED
@@ -2,10 +2,27 @@
2
2
 
3
3
  # How does restore work?
4
4
 
5
+ Backed-up emails are pushed to the IMAP server.
6
+ If there are clashes, folders are renamed.
7
+
5
8
  # What are all these 'INBOX.12345' files?
6
9
 
10
+ If, when the backup is launched, the IMAP server contains a folder with
11
+ the same name, but different history to the local backup, the local
12
+ emails cannot simply be added to the existing folder.
13
+
14
+ In this case, a numeric suffix is added to the **local** folder,
15
+ before it is restored.
16
+
17
+ In this way, old and new emails are kept separate.
18
+
7
19
  # Will my email get overwritten?
8
20
 
21
+ No.
22
+
23
+ Emails are identified by folder and a specific email id. Any email that
24
+ is already on the server is skipped.
25
+
9
26
  ## How do I restore to a different service?
10
27
 
11
28
  1. Run setup and add the new server, (but don't run any backups),
data/imap-backup.gemspec CHANGED
@@ -1,6 +1,5 @@
1
1
  $LOAD_PATH.unshift(File.expand_path("lib", __dir__))
2
2
  require "imap/backup/version"
3
- require "rake/file_list"
4
3
 
5
4
  Gem::Specification.new do |gem|
6
5
  gem.name = "imap-backup"
@@ -10,24 +9,22 @@ Gem::Specification.new do |gem|
10
9
  gem.email = ["joe.g.yates@gmail.com"]
11
10
  gem.homepage = "https://github.com/joeyates/imap-backup"
12
11
  gem.licenses = ["MIT"]
12
+ gem.version = Imap::Backup::VERSION
13
13
 
14
- # Build list of files manually, see also
15
- # https://github.com/rubygems/rubygems/blob/master/bundler/bundler.gemspec#L37
16
14
  gem.files = %w[bin/imap-backup]
17
- gem.files += Dir.glob("docs/*{.png,.md}")
15
+ gem.files += Dir.glob("docs/*.md")
18
16
  gem.files += Dir.glob("lib/**/*.rb")
19
- gem.files += Dir.glob("spec/**/*{.rb,.yml}")
20
17
  gem.files += %w[imap-backup.gemspec]
21
18
  gem.files += %w[LICENSE README.md]
22
19
 
23
20
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
24
- gem.test_files = gem.files.grep(%r{^spec/})
21
+ gem.test_files = Dir.glob("spec/**/*{.rb,.yml}")
25
22
  gem.require_paths = ["lib"]
26
23
  gem.required_ruby_version = ">= 2.5"
27
- gem.version = Imap::Backup::VERSION
28
24
 
29
25
  gem.add_runtime_dependency "highline"
30
26
  gem.add_runtime_dependency "mail"
27
+ gem.add_runtime_dependency "os"
31
28
  gem.add_runtime_dependency "rake"
32
29
  gem.add_runtime_dependency "thor", "~> 1.1"
33
30
 
@@ -1,9 +1,13 @@
1
+ require "forwardable"
1
2
  require "mail"
2
3
 
3
4
  module Email; end
4
5
 
5
6
  module Email::Mboxrd
6
7
  class Message
8
+ extend Forwardable
9
+ def_delegators :@parsed, :subject
10
+
7
11
  attr_reader :supplied_body
8
12
 
9
13
  def self.from_serialized(serialized)
@@ -36,12 +40,12 @@ module Email::Mboxrd
36
40
  supplied_body.gsub(/(?<!\r)\n/, "\r\n")
37
41
  end
38
42
 
43
+ private
44
+
39
45
  def parsed
40
46
  @parsed ||= Mail.new(supplied_body)
41
47
  end
42
48
 
43
- private
44
-
45
49
  def from
46
50
  @from ||=
47
51
  begin
@@ -0,0 +1,7 @@
1
+ require "email/provider/default"
2
+
3
+ class Email::Provider::AppleMail < Email::Provider::Default
4
+ def host
5
+ "imap.mail.me.com"
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Email; end
2
+ class Email::Provider; end
3
+
4
+ class Email::Provider::Default
5
+ # We don't know how to guess the IMAP server
6
+ def host
7
+ end
8
+
9
+ def options
10
+ {port: 993, ssl: {ssl_version: :TLSv1_2}}
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ require "email/provider/default"
2
+
3
+ class Email::Provider::Fastmail < Email::Provider::Default
4
+ def host
5
+ "imap.fastmail.com"
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "email/provider/default"
2
+
3
+ class Email::Provider::GMail < Email::Provider::Default
4
+ def host
5
+ "imap.gmail.com"
6
+ end
7
+ end
@@ -1,37 +1,27 @@
1
+ require "email/provider/default"
2
+ require "email/provider/apple_mail"
3
+ require "email/provider/fastmail"
4
+ require "email/provider/gmail"
5
+
1
6
  module Email; end
2
7
 
3
8
  class Email::Provider
4
- GMAIL_IMAP_SERVER = "imap.gmail.com".freeze
5
-
6
9
  def self.for_address(address)
7
10
  case
8
11
  when address.end_with?("@fastmail.com")
9
- new(:fastmail)
10
- when address.end_with?("@gmail.com")
11
- new(:gmail)
12
+ Email::Provider::Fastmail.new
12
13
  when address.end_with?("@fastmail.fm")
13
- new(:fastmail)
14
+ Email::Provider::Fastmail.new
15
+ when address.end_with?("@gmail.com")
16
+ Email::Provider::GMail.new
17
+ when address.end_with?("@icloud.com")
18
+ Email::Provider::AppleMail.new
19
+ when address.end_with?("@mac.com")
20
+ Email::Provider::AppleMail.new
21
+ when address.end_with?("@me.com")
22
+ Email::Provider::AppleMail.new
14
23
  else
15
- new(:default)
16
- end
17
- end
18
-
19
- attr_reader :provider
20
-
21
- def initialize(provider)
22
- @provider = provider
23
- end
24
-
25
- def options
26
- {port: 993, ssl: {ssl_version: :TLSv1_2}}
27
- end
28
-
29
- def host
30
- case provider
31
- when :gmail
32
- GMAIL_IMAP_SERVER
33
- when :fastmail
34
- "imap.fastmail.com"
24
+ Email::Provider::Default.new
35
25
  end
36
26
  end
37
27
  end
@@ -1,4 +1,5 @@
1
- require "net/imap"
1
+ require "imap/backup/client/apple_mail"
2
+ require "imap/backup/client/default"
2
3
 
3
4
  require "retry_on_error"
4
5
 
@@ -29,17 +30,15 @@ module Imap::Backup
29
30
  def folders
30
31
  @folders ||=
31
32
  begin
32
- root = provider_root
33
- mailbox_lists = imap.list(root, "*")
33
+ folders = client.list
34
34
 
35
- if mailbox_lists.nil?
35
+ if folders.empty?
36
36
  message = "Unable to get folder list for account #{username}"
37
37
  Imap::Backup.logger.info message
38
38
  raise message
39
39
  end
40
40
 
41
- utf7_encoded = mailbox_lists.map(&:name)
42
- utf7_encoded.map { |n| Net::IMAP.decode_utf7(n) }
41
+ folders
43
42
  end
44
43
  end
45
44
 
@@ -54,7 +53,7 @@ module Imap::Backup
54
53
  def run_backup
55
54
  Imap::Backup.logger.debug "Running backup of account: #{username}"
56
55
  # start the connection so we get logging messages in the right order
57
- imap
56
+ client
58
57
  each_folder do |folder, serializer|
59
58
  next if !folder.exist?
60
59
 
@@ -89,34 +88,36 @@ module Imap::Backup
89
88
  end
90
89
 
91
90
  def disconnect
92
- imap.disconnect if @imap
91
+ client.disconnect if @client
93
92
  end
94
93
 
95
94
  def reconnect
96
95
  disconnect
97
- @imap = nil
96
+ @client = nil
98
97
  end
99
98
 
100
- def imap
101
- @imap ||=
99
+ def client
100
+ @client ||=
102
101
  retry_on_error(errors: LOGIN_RETRY_CLASSES) do
103
102
  options = provider_options
104
103
  Imap::Backup.logger.debug(
105
104
  "Creating IMAP instance: #{server}, options: #{options.inspect}"
106
105
  )
107
- imap = Net::IMAP.new(server, options)
106
+ client =
107
+ if provider.is_a?(Email::Provider::AppleMail)
108
+ Client::AppleMail.new(server, options)
109
+ else
110
+ Client::Default.new(server, options)
111
+ end
108
112
  Imap::Backup.logger.debug "Logging in: #{username}/#{masked_password}"
109
- imap.login(username, password)
113
+ client.login(username, password)
110
114
  Imap::Backup.logger.debug "Login complete"
111
- imap
115
+ client
112
116
  end
113
117
  end
114
118
 
115
119
  def server
116
- return @server if @server
117
- return nil if provider.nil?
118
-
119
- @server = provider.host
120
+ @server ||= provider.host
120
121
  end
121
122
 
122
123
  private
@@ -186,16 +187,5 @@ module Imap::Backup
186
187
  def provider_options
187
188
  provider.options.merge(connection_options)
188
189
  end
189
-
190
- # 6.3.8. LIST Command
191
- # An empty ("" string) mailbox name argument is a special request to
192
- # return the hierarchy delimiter and the root name of the name given
193
- # in the reference.
194
- def provider_root
195
- return @provider_root if @provider_root
196
-
197
- root_info = imap.list("", "")[0]
198
- @provider_root = root_info.name
199
- end
200
190
  end
201
191
  end
@@ -11,13 +11,13 @@ module Imap::Backup
11
11
  extend Forwardable
12
12
  include RetryOnError
13
13
 
14
- REQUESTED_ATTRIBUTES = %w[RFC822 FLAGS INTERNALDATE].freeze
14
+ BODY_ATTRIBUTE = "BODY[]".freeze
15
15
  UID_FETCH_RETRY_CLASSES = [EOFError].freeze
16
16
 
17
17
  attr_reader :connection
18
18
  attr_reader :name
19
19
 
20
- delegate imap: :connection
20
+ delegate client: :connection
21
21
 
22
22
  def initialize(connection, name)
23
23
  @connection = connection
@@ -40,20 +40,20 @@ module Imap::Backup
40
40
  def create
41
41
  return if exist?
42
42
 
43
- imap.create(utf7_encoded_name)
43
+ client.create(utf7_encoded_name)
44
44
  end
45
45
 
46
46
  def uid_validity
47
47
  @uid_validity ||=
48
48
  begin
49
49
  examine
50
- imap.responses["UIDVALIDITY"][-1]
50
+ client.responses["UIDVALIDITY"][-1]
51
51
  end
52
52
  end
53
53
 
54
54
  def uids
55
55
  examine
56
- imap.uid_search(["ALL"]).sort
56
+ client.uid_search(["ALL"]).sort
57
57
  rescue FolderNotFound
58
58
  []
59
59
  rescue NoMethodError
@@ -72,15 +72,14 @@ module Imap::Backup
72
72
  examine
73
73
  fetch_data_items =
74
74
  retry_on_error(errors: UID_FETCH_RETRY_CLASSES) do
75
- imap.uid_fetch([uid.to_i], REQUESTED_ATTRIBUTES)
75
+ client.uid_fetch([uid.to_i], [BODY_ATTRIBUTE])
76
76
  end
77
77
  return nil if fetch_data_items.nil?
78
78
 
79
79
  fetch_data_item = fetch_data_items[0]
80
80
  attributes = fetch_data_item.attr
81
- return nil if !attributes.key?("RFC822")
82
81
 
83
- attributes
82
+ attributes[BODY_ATTRIBUTE]
84
83
  rescue FolderNotFound
85
84
  nil
86
85
  end
@@ -88,14 +87,14 @@ module Imap::Backup
88
87
  def append(message)
89
88
  body = message.imap_body
90
89
  date = message.date&.to_time
91
- response = imap.append(utf7_encoded_name, body, nil, date)
90
+ response = client.append(utf7_encoded_name, body, nil, date)
92
91
  extract_uid(response)
93
92
  end
94
93
 
95
94
  private
96
95
 
97
96
  def examine
98
- imap.examine(utf7_encoded_name)
97
+ client.examine(utf7_encoded_name)
99
98
  rescue Net::IMAP::NoResponseError
100
99
  Imap::Backup.logger.warn "Folder '#{name}' does not exist on server"
101
100
  raise FolderNotFound, "Folder '#{name}' does not exist on server"
@@ -5,12 +5,25 @@ module Imap::Backup::CLI::Helpers
5
5
  options.each.with_object({}) { |(k, v), acc| acc[k.intern] = v }
6
6
  end
7
7
 
8
+ def account(email)
9
+ connections = Imap::Backup::Configuration::List.new
10
+ account = connections.accounts.find { |a| a[:username] == email }
11
+ raise "#{email} is not a configured account" if !account
12
+
13
+ account
14
+ end
15
+
16
+ def connection(email)
17
+ account = account(email)
18
+
19
+ Imap::Backup::Account::Connection.new(account)
20
+ end
21
+
8
22
  def each_connection(names)
9
23
  begin
10
24
  connections = Imap::Backup::Configuration::List.new(names)
11
25
  rescue Imap::Backup::ConfigurationNotFound
12
26
  raise "imap-backup is not configured. Run `imap-backup setup`"
13
- return
14
27
  end
15
28
 
16
29
  connections.each_connection do |connection|
@@ -6,49 +6,46 @@ 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| puts a[:username] }
9
+ connections.accounts.each { |a| Kernel.puts a[:username] }
10
10
  end
11
11
 
12
12
  desc "folders EMAIL", "List account folders"
13
13
  def folders(email)
14
- connections = Imap::Backup::Configuration::List.new
15
- account = connections.accounts.find { |a| a[:username] == email }
16
- raise "#{email} is not a configured account" if !account
14
+ connection = connection(email)
17
15
 
18
- account_connection = Imap::Backup::Account::Connection.new(account)
19
- account_connection.local_folders.each do |_s, f|
20
- puts %("#{f.name}")
16
+ connection.local_folders.each do |_s, f|
17
+ Kernel.puts %("#{f.name}")
21
18
  end
22
19
  end
23
20
 
24
21
  desc "list EMAIL FOLDER", "List emails in a folder"
25
22
  def list(email, folder_name)
26
- connections = Imap::Backup::Configuration::List.new
27
- account = connections.accounts.find { |a| a[:username] == email }
28
- raise "#{email} is not a configured account" if !account
23
+ connection = connection(email)
29
24
 
30
- account_connection = Imap::Backup::Account::Connection.new(account)
31
- folder_serializer, folder = account_connection.local_folders.find do |(_s, f)|
25
+ folder_serializer, _folder = connection.local_folders.find do |(_s, f)|
32
26
  f.name == folder_name
33
27
  end
34
28
  raise "Folder '#{folder_name}' not found" if !folder_serializer
35
29
 
36
30
  max_subject = 60
37
- puts format("%-10<uid>s %-#{max_subject}<subject>s - %<date>s", {uid: "UID", subject: "Subject", date: "Date"})
38
- puts "-" * (12 + max_subject + 28)
31
+ Kernel.puts format(
32
+ "%-10<uid>s %-#{max_subject}<subject>s - %<date>s",
33
+ {uid: "UID", subject: "Subject", date: "Date"}
34
+ )
35
+ Kernel.puts "-" * (12 + max_subject + 28)
39
36
 
40
37
  uids = folder_serializer.uids
41
38
 
42
39
  folder_serializer.each_message(uids).map do |uid, message|
43
40
  m = {
44
41
  uid: uid,
45
- date: message.parsed.date.to_s,
46
- subject: message.parsed.subject || ""
42
+ date: message.date.to_s,
43
+ subject: message.subject || ""
47
44
  }
48
45
  if m[:subject].length > max_subject
49
- puts format("% 10<uid>u: %.#{max_subject - 3}<subject>s... - %<date>s", m)
46
+ Kernel.puts format("% 10<uid>u: %.#{max_subject - 3}<subject>s... - %<date>s", m)
50
47
  else
51
- puts format("% 10<uid>u: %-#{max_subject}<subject>s - %<date>s", m)
48
+ Kernel.puts format("% 10<uid>u: %-#{max_subject}<subject>s - %<date>s", m)
52
49
  end
53
50
  end
54
51
  end
@@ -60,12 +57,9 @@ module Imap::Backup
60
57
  the UID.
61
58
  DESC
62
59
  def show(email, folder_name, uids)
63
- connections = Imap::Backup::Configuration::List.new
64
- account = connections.accounts.find { |a| a[:username] == email }
65
- raise "#{email} is not a configured account" if !account
60
+ connection = connection(email)
66
61
 
67
- account_connection = Imap::Backup::Account::Connection.new(account)
68
- folder_serializer, _folder = account_connection.local_folders.find do |(_s, f)|
62
+ folder_serializer, _folder = connection.local_folders.find do |(_s, f)|
69
63
  f.name == folder_name
70
64
  end
71
65
  raise "Folder '#{folder_name}' not found" if !folder_serializer
@@ -73,13 +67,13 @@ module Imap::Backup
73
67
  uid_list = uids.split(",")
74
68
  folder_serializer.each_message(uid_list).each do |uid, message|
75
69
  if uid_list.count > 1
76
- puts <<~HEADER
77
- #{"-" * 80}
78
- #{format("| UID: %-71s |", uid)}
79
- #{"-" * 80}
70
+ Kernel.puts <<~HEADER
71
+ #{'-' * 80}
72
+ #{format('| UID: %-71s |', uid)}
73
+ #{'-' * 80}
80
74
  HEADER
81
75
  end
82
- puts message.supplied_body
76
+ Kernel.puts message.supplied_body
83
77
  end
84
78
  end
85
79
  end
@@ -1,7 +1,7 @@
1
1
  class Imap::Backup::CLI::Setup < Thor
2
2
  include Thor::Actions
3
3
 
4
- def initialize()
4
+ def initialize
5
5
  super([])
6
6
  end
7
7