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 +4 -4
- data/README.md +8 -48
- data/docs/development.md +60 -0
- data/docs/restore.md +17 -0
- data/imap-backup.gemspec +7 -7
- data/lib/imap/backup/cli/helpers.rb +0 -1
- data/lib/imap/backup/cli/local.rb +4 -4
- data/lib/imap/backup/cli/setup.rb +1 -1
- data/lib/imap/backup/cli/utils.rb +41 -0
- data/lib/imap/backup/cli.rb +5 -1
- data/lib/imap/backup/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- metadata +35 -28
- data/docs/docker-imap.md +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97ae9089aa19dee6fcf7a1c211091671a6befe882d5b664654a25d6d10e81704
|
4
|
+
data.tar.gz: 2677746ed662c457a738033224da11a40a76367e4031e7636b33391d51ee4659
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
#
|
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
|
-
|
250
|
-
|
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)
|
data/docs/development.md
ADDED
@@ -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
|
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 =
|
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,
|
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
|
-
#{
|
78
|
-
#{format(
|
79
|
-
#{
|
77
|
+
#{'-' * 80}
|
78
|
+
#{format('| UID: %-71s |', uid)}
|
79
|
+
#{'-' * 80}
|
80
80
|
HEADER
|
81
81
|
end
|
82
82
|
puts message.supplied_body
|
@@ -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
|
data/lib/imap/backup/cli.rb
CHANGED
@@ -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
|
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
|
data/lib/imap/backup/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
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.
|
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
|
+
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/
|
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/
|
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/
|
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
|
-
```
|