imap-backup 4.0.0 → 4.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85e081f686a106384d27ffc91cb21965832edd629da671261bda69b668776d5e
4
- data.tar.gz: 8253587491a279e76ebed2268a66b60d9aab4f517cdafadb8c9494e7c3f3648b
3
+ metadata.gz: 97ae9089aa19dee6fcf7a1c211091671a6befe882d5b664654a25d6d10e81704
4
+ data.tar.gz: 2677746ed662c457a738033224da11a40a76367e4031e7636b33391d51ee4659
5
5
  SHA512:
6
- metadata.gz: e2b3806cedfe124c286477f50690781c4593db1f3b12d53281c666d3d5771f9a42aa4cc24851fb88f9205a2f11a8e299c74a331a606de1aab056e56b753e3cf1
7
- data.tar.gz: fc96edce37dd33793d04da272f2aea087ad7a16aa409726c83d6cf453bd386e3673a75b8d4e0eee90f352fc1e9168d611865dd87f79c05ff0cf132278bf59df3
6
+ metadata.gz: 5e97ba8ab64e27924166609c1cb80e52dbfa8136b4248324a7589e143d64ebddbb415ad6c4c7a0e472732db55c717d14e08be47c7640efcb36029c80b10938ef
7
+ data.tar.gz: 2fd74f2b86946b79d07a1354a55b00444022838fcd4968a6a2f0dc15494f4c2d80d0ea06b1e0290b921e7f2242566a56fb8e9bd6bf03b5a88595871c91d08604
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
@@ -178,6 +178,7 @@ If you have problems:
178
178
  "debug": true
179
179
  }
180
180
  ```
181
+
181
182
  # Restore
182
183
 
183
184
  All missing messages are pushed to the IMAP server.
@@ -206,48 +207,7 @@ $ imap-backup status
206
207
  * Restartable - calculate start point based on already downloaded messages
207
208
  * Standalone - do not rely on an email client or MTA
208
209
 
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
210
+ # Documentation
248
211
 
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
212
+ * [Development](./docs/development.md)
213
+ * [Restore](./docs/restore.md)
@@ -0,0 +1,60 @@
1
+ # Testing
2
+
3
+ ## Integration Tests
4
+
5
+ Integration tests (feature specs) are run against a Docker image
6
+ (antespi/docker-imap-devel:latest).
7
+
8
+ In one shell, run the Docker image:
9
+
10
+ ```sh
11
+ $ docker run \
12
+ --env MAIL_ADDRESS=address@example.org \
13
+ --env MAIL_PASS=pass \
14
+ --env MAILNAME=example.org \
15
+ --publish 8993:993 \
16
+ antespi/docker-imap-devel:latest
17
+ ```
18
+
19
+ ```sh
20
+ $ rake
21
+ ```
22
+
23
+ To exclude Docker-based tests:
24
+
25
+ ```sh
26
+ rake no-docker
27
+ ```
28
+
29
+ or
30
+
31
+ ```sh
32
+ $ rspec --tag ~docker
33
+ ```
34
+
35
+ ## Access Docker imap server
36
+
37
+ ```ruby
38
+ require "net/imap"
39
+
40
+ imap = Net::IMAP.new("localhost", {port: 8993, ssl: {verify_mode: 0}})
41
+ username = "address@example.org"
42
+ imap.login(username, "pass")
43
+
44
+ message = "From: #{username}\nSubject: Some Subject\n\nHello!\n"
45
+ response = imap.append("INBOX", message, nil, nil)
46
+
47
+ imap.examine("INBOX")
48
+ uids = imap.uid_search(["ALL"]).sort
49
+
50
+ REQUESTED_ATTRIBUTES = ["RFC822", "FLAGS", "INTERNALDATE"].freeze
51
+ fetch_data_items = imap.uid_fetch(uids, REQUESTED_ATTRIBUTES)
52
+ ```
53
+
54
+ # Contributing
55
+
56
+ 1. Fork it
57
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
58
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
59
+ 4. Push to the branch (`git push origin my-new-feature`)
60
+ 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,21 +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
 
20
+ gem.extra_rdoc_files += Dir.glob("README.md")
21
+ gem.extra_rdoc_files += Dir.glob("docs/*.md")
22
+ gem.rdoc_options = ["--main", "README.md"]
23
+
23
24
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
24
- gem.test_files = gem.files.grep(%r{^spec/})
25
+ gem.test_files = Dir.glob("spec/**/*{.rb,.yml}")
25
26
  gem.require_paths = ["lib"]
26
27
  gem.required_ruby_version = ">= 2.5"
27
- gem.version = Imap::Backup::VERSION
28
28
 
29
29
  gem.add_runtime_dependency "highline"
30
30
  gem.add_runtime_dependency "mail"
@@ -10,7 +10,6 @@ module Imap::Backup::CLI::Helpers
10
10
  connections = Imap::Backup::Configuration::List.new(names)
11
11
  rescue Imap::Backup::ConfigurationNotFound
12
12
  raise "imap-backup is not configured. Run `imap-backup setup`"
13
- return
14
13
  end
15
14
 
16
15
  connections.each_connection do |connection|
@@ -28,7 +28,7 @@ module Imap::Backup
28
28
  raise "#{email} is not a configured account" if !account
29
29
 
30
30
  account_connection = Imap::Backup::Account::Connection.new(account)
31
- folder_serializer, folder = account_connection.local_folders.find do |(_s, f)|
31
+ folder_serializer, _folder = account_connection.local_folders.find do |(_s, f)|
32
32
  f.name == folder_name
33
33
  end
34
34
  raise "Folder '#{folder_name}' not found" if !folder_serializer
@@ -74,9 +74,9 @@ module Imap::Backup
74
74
  folder_serializer.each_message(uid_list).each do |uid, message|
75
75
  if uid_list.count > 1
76
76
  puts <<~HEADER
77
- #{"-" * 80}
78
- #{format("| UID: %-71s |", uid)}
79
- #{"-" * 80}
77
+ #{'-' * 80}
78
+ #{format('| UID: %-71s |', uid)}
79
+ #{'-' * 80}
80
80
  HEADER
81
81
  end
82
82
  puts message.supplied_body
@@ -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
 
@@ -0,0 +1,41 @@
1
+ module Imap::Backup
2
+ class CLI::Utils < Thor
3
+ include Thor::Actions
4
+
5
+ FAKE_EMAIL = "fake@email.com"
6
+
7
+ desc "ignore-history EMAIL", "Skip downloading emails up to today for all configured folders"
8
+ def ignore_history(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
+ connection = Imap::Backup::Account::Connection.new(account)
14
+
15
+ connection.local_folders.each do |_s, f|
16
+ next if !folder.exist?
17
+ do_ignore_folder_history(connection, folder)
18
+ end
19
+ end
20
+
21
+ no_commands do
22
+ def do_ignore_folder_history(connection, folder)
23
+ serializer = Imap::Backup::Serializer::Mbox.new(connection.local_path, folder.name)
24
+ uids = folder.uids - serializer.uids
25
+ Imap::Backup.logger.info "Folder '#{folder.name}' - #{uids.length} messages"
26
+
27
+ serializer.apply_uid_validity(folder.uid_validity)
28
+
29
+ uids.each do |uid|
30
+ message = <<~MESSAGE
31
+ From: #{FAKE_EMAIL}
32
+ Subject: Message #{uid} not backed up
33
+ Skipped #{uid}
34
+ MESSAGE
35
+
36
+ serializer.save(uid, message)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -13,6 +13,7 @@ module Imap::Backup
13
13
  autoload :Restore, "imap/backup/cli/restore"
14
14
  autoload :Setup, "imap/backup/cli/setup"
15
15
  autoload :Status, "imap/backup/cli/status"
16
+ autoload :Utils, "imap/backup/cli/utils"
16
17
 
17
18
  include Helpers
18
19
 
@@ -73,7 +74,7 @@ module Imap::Backup
73
74
  Configure email accounts to back up.
74
75
  DESC
75
76
  def setup
76
- Setup.new().run
77
+ Setup.new.run
77
78
  end
78
79
 
79
80
  desc "status", "Show backup status"
@@ -87,5 +88,8 @@ module Imap::Backup
87
88
 
88
89
  desc "local SUBCOMMAND [OPTIONS]", "View local info"
89
90
  subcommand "local", Local
91
+
92
+ desc "utils SUBCOMMAND [OPTIONS]", "Various utilities"
93
+ subcommand "utils", Utils
90
94
  end
91
95
  end
@@ -3,7 +3,7 @@ module Imap; end
3
3
  module Imap::Backup
4
4
  MAJOR = 4
5
5
  MINOR = 0
6
- REVISION = 0
6
+ REVISION = 1
7
7
  PRE = nil
8
8
  VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
9
9
  end
data/spec/spec_helper.rb CHANGED
@@ -15,5 +15,6 @@ SimpleCov.start do
15
15
  end
16
16
 
17
17
  require "imap/backup"
18
+ require "imap/backup/cli"
18
19
 
19
20
  silence_logging
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-22 00:00:00.000000000 Z
11
+ date: 2021-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -156,12 +156,16 @@ email:
156
156
  executables:
157
157
  - imap-backup
158
158
  extensions: []
159
- extra_rdoc_files: []
159
+ extra_rdoc_files:
160
+ - README.md
161
+ - docs/setup.md
162
+ - docs/restore.md
163
+ - docs/development.md
160
164
  files:
161
165
  - LICENSE
162
166
  - README.md
163
167
  - bin/imap-backup
164
- - docs/docker-imap.md
168
+ - docs/development.md
165
169
  - docs/restore.md
166
170
  - docs/setup.md
167
171
  - imap-backup.gemspec
@@ -178,6 +182,7 @@ files:
178
182
  - lib/imap/backup/cli/restore.rb
179
183
  - lib/imap/backup/cli/setup.rb
180
184
  - lib/imap/backup/cli/status.rb
185
+ - lib/imap/backup/cli/utils.rb
181
186
  - lib/imap/backup/configuration/account.rb
182
187
  - lib/imap/backup/configuration/asker.rb
183
188
  - lib/imap/backup/configuration/connection_tester.rb
@@ -231,7 +236,9 @@ licenses:
231
236
  - MIT
232
237
  metadata: {}
233
238
  post_install_message:
234
- rdoc_options: []
239
+ rdoc_options:
240
+ - "--main"
241
+ - README.md
235
242
  require_paths:
236
243
  - lib
237
244
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -250,35 +257,35 @@ signing_key:
250
257
  specification_version: 4
251
258
  summary: Backup GMail (or other IMAP) accounts to disk
252
259
  test_files:
253
- - spec/features/backup_spec.rb
254
- - spec/features/helper.rb
255
- - spec/features/restore_spec.rb
256
- - spec/features/support/backup_directory.rb
257
- - spec/features/support/email_server.rb
258
- - spec/features/support/shared/connection_context.rb
259
- - spec/features/support/shared/message_fixtures.rb
260
- - spec/fixtures/connection.yml
261
- - spec/gather_rspec_coverage.rb
262
260
  - spec/spec_helper.rb
263
- - spec/support/fixtures.rb
264
- - spec/support/higline_test_helpers.rb
265
- - spec/support/shared_examples/account_flagging.rb
266
- - spec/support/silence_logging.rb
267
- - spec/unit/email/mboxrd/message_spec.rb
268
- - spec/unit/email/provider_spec.rb
269
- - spec/unit/imap/backup/account/connection_spec.rb
270
- - spec/unit/imap/backup/account/folder_spec.rb
261
+ - spec/unit/imap/backup_spec.rb
271
262
  - spec/unit/imap/backup/configuration/account_spec.rb
272
- - spec/unit/imap/backup/configuration/asker_spec.rb
273
- - spec/unit/imap/backup/configuration/connection_tester_spec.rb
274
- - spec/unit/imap/backup/configuration/folder_chooser_spec.rb
275
263
  - spec/unit/imap/backup/configuration/list_spec.rb
264
+ - spec/unit/imap/backup/configuration/connection_tester_spec.rb
276
265
  - spec/unit/imap/backup/configuration/setup_spec.rb
266
+ - spec/unit/imap/backup/configuration/asker_spec.rb
267
+ - spec/unit/imap/backup/configuration/folder_chooser_spec.rb
277
268
  - spec/unit/imap/backup/configuration/store_spec.rb
278
- - spec/unit/imap/backup/downloader_spec.rb
279
- - spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb
280
269
  - spec/unit/imap/backup/serializer/mbox_spec.rb
281
270
  - spec/unit/imap/backup/serializer/mbox_store_spec.rb
271
+ - spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb
272
+ - spec/unit/imap/backup/downloader_spec.rb
282
273
  - spec/unit/imap/backup/uploader_spec.rb
274
+ - spec/unit/imap/backup/account/folder_spec.rb
275
+ - spec/unit/imap/backup/account/connection_spec.rb
283
276
  - spec/unit/imap/backup/utils_spec.rb
284
- - spec/unit/imap/backup_spec.rb
277
+ - spec/unit/email/mboxrd/message_spec.rb
278
+ - spec/unit/email/provider_spec.rb
279
+ - spec/features/backup_spec.rb
280
+ - spec/features/helper.rb
281
+ - spec/features/restore_spec.rb
282
+ - spec/features/support/email_server.rb
283
+ - spec/features/support/backup_directory.rb
284
+ - spec/features/support/shared/connection_context.rb
285
+ - spec/features/support/shared/message_fixtures.rb
286
+ - spec/support/fixtures.rb
287
+ - spec/support/silence_logging.rb
288
+ - spec/support/higline_test_helpers.rb
289
+ - spec/support/shared_examples/account_flagging.rb
290
+ - spec/fixtures/connection.yml
291
+ - spec/gather_rspec_coverage.rb
data/docs/docker-imap.md DELETED
@@ -1,18 +0,0 @@
1
- # Access Docker imap server
2
-
3
- ```ruby
4
- require "net/imap"
5
-
6
- imap = Net::IMAP.new("localhost", {port: 8993, ssl: {verify_mode: 0}})
7
- username = "address@example.org"
8
- imap.login(username, "pass")
9
-
10
- message = "From: #{username}\nSubject: Some Subject\n\nHello!\n"
11
- response = imap.append("INBOX", message, nil, nil)
12
-
13
- imap.examine("INBOX")
14
- uids = imap.uid_search(["ALL"]).sort
15
-
16
- REQUESTED_ATTRIBUTES = ["RFC822", "FLAGS", "INTERNALDATE"].freeze
17
- fetch_data_items = imap.uid_fetch(uids, REQUESTED_ATTRIBUTES)
18
- ```