imap-backup 4.0.0.rc4 → 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 +30 -0
- data/docs/setup.md +5 -0
- data/imap-backup.gemspec +13 -3
- data/lib/imap/backup/cli/helpers.rb +0 -1
- data/lib/imap/backup/cli/local.rb +26 -10
- 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/downloader.rb +2 -1
- data/lib/imap/backup/serializer/mbox_store.rb +3 -3
- data/lib/imap/backup/version.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/imap/backup/downloader_spec.rb +3 -2
- metadata +41 -43
- data/.circleci/config.yml +0 -51
- data/.gitignore +0 -8
- data/.rspec +0 -2
- data/.rspec-all +0 -4
- data/.rubocop.yml +0 -21
- data/.rubocop_todo.yml +0 -129
- data/CHANGELOG.md +0 -19
- data/Gemfile +0 -3
- data/Rakefile +0 -18
- data/docker-compose.yml +0 -15
- data/docs/docker-imap.md +0 -18
- data/imap-backup +0 -9
- data/tmp/.gitkeep +0 -0
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
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# FAQ
|
2
|
+
|
3
|
+
# How does restore work?
|
4
|
+
|
5
|
+
Backed-up emails are pushed to the IMAP server.
|
6
|
+
If there are clashes, folders are renamed.
|
7
|
+
|
8
|
+
# What are all these 'INBOX.12345' files?
|
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
|
+
|
19
|
+
# Will my email get overwritten?
|
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
|
+
|
26
|
+
## How do I restore to a different service?
|
27
|
+
|
28
|
+
1. Run setup and add the new server, (but don't run any backups),
|
29
|
+
2. Rename of the existing backup directory to match the new email address,
|
30
|
+
3. Run the restore.
|
data/docs/setup.md
ADDED
data/imap-backup.gemspec
CHANGED
@@ -8,13 +8,23 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.authors = ["Joe Yates"]
|
9
9
|
gem.email = ["joe.g.yates@gmail.com"]
|
10
10
|
gem.homepage = "https://github.com/joeyates/imap-backup"
|
11
|
+
gem.licenses = ["MIT"]
|
12
|
+
gem.version = Imap::Backup::VERSION
|
13
|
+
|
14
|
+
gem.files = %w[bin/imap-backup]
|
15
|
+
gem.files += Dir.glob("docs/*.md")
|
16
|
+
gem.files += Dir.glob("lib/**/*.rb")
|
17
|
+
gem.files += %w[imap-backup.gemspec]
|
18
|
+
gem.files += %w[LICENSE README.md]
|
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"]
|
11
23
|
|
12
|
-
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
13
24
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
14
|
-
gem.test_files =
|
25
|
+
gem.test_files = Dir.glob("spec/**/*{.rb,.yml}")
|
15
26
|
gem.require_paths = ["lib"]
|
16
27
|
gem.required_ruby_version = ">= 2.5"
|
17
|
-
gem.version = Imap::Backup::VERSION
|
18
28
|
|
19
29
|
gem.add_runtime_dependency "highline"
|
20
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|
|
@@ -21,14 +21,14 @@ module Imap::Backup
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
desc "
|
25
|
-
def
|
24
|
+
desc "list EMAIL FOLDER", "List emails in a folder"
|
25
|
+
def list(email, folder_name)
|
26
26
|
connections = Imap::Backup::Configuration::List.new
|
27
27
|
account = connections.accounts.find { |a| a[:username] == email }
|
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
|
@@ -40,7 +40,11 @@ module Imap::Backup
|
|
40
40
|
uids = folder_serializer.uids
|
41
41
|
|
42
42
|
folder_serializer.each_message(uids).map do |uid, message|
|
43
|
-
m = {
|
43
|
+
m = {
|
44
|
+
uid: uid,
|
45
|
+
date: message.parsed.date.to_s,
|
46
|
+
subject: message.parsed.subject || ""
|
47
|
+
}
|
44
48
|
if m[:subject].length > max_subject
|
45
49
|
puts format("% 10<uid>u: %.#{max_subject - 3}<subject>s... - %<date>s", m)
|
46
50
|
else
|
@@ -49,8 +53,13 @@ module Imap::Backup
|
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
|
-
desc "
|
53
|
-
|
56
|
+
desc "show EMAIL FOLDER UID[,UID]", "Show one or more emails"
|
57
|
+
long_desc <<~DESC
|
58
|
+
Prints out the requested emails.
|
59
|
+
If more than one UID is given, they are separated by a header indicating
|
60
|
+
the UID.
|
61
|
+
DESC
|
62
|
+
def show(email, folder_name, uids)
|
54
63
|
connections = Imap::Backup::Configuration::List.new
|
55
64
|
account = connections.accounts.find { |a| a[:username] == email }
|
56
65
|
raise "#{email} is not a configured account" if !account
|
@@ -61,10 +70,17 @@ module Imap::Backup
|
|
61
70
|
end
|
62
71
|
raise "Folder '#{folder_name}' not found" if !folder_serializer
|
63
72
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
uid_list = uids.split(",")
|
74
|
+
folder_serializer.each_message(uid_list).each do |uid, message|
|
75
|
+
if uid_list.count > 1
|
76
|
+
puts <<~HEADER
|
77
|
+
#{'-' * 80}
|
78
|
+
#{format('| UID: %-71s |', uid)}
|
79
|
+
#{'-' * 80}
|
80
|
+
HEADER
|
81
|
+
end
|
82
|
+
puts message.supplied_body
|
83
|
+
end
|
68
84
|
end
|
69
85
|
end
|
70
86
|
end
|
@@ -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
|
@@ -40,7 +40,7 @@ module Imap::Backup
|
|
40
40
|
@uids || []
|
41
41
|
end
|
42
42
|
|
43
|
-
def add(uid,
|
43
|
+
def add(uid, body)
|
44
44
|
do_load if !loaded
|
45
45
|
raise "Can't add messages without uid_validity" if !uid_validity
|
46
46
|
|
@@ -52,7 +52,6 @@ module Imap::Backup
|
|
52
52
|
return
|
53
53
|
end
|
54
54
|
|
55
|
-
body = message["RFC822"]
|
56
55
|
mboxrd_message = Email::Mboxrd::Message.new(body)
|
57
56
|
mbox = nil
|
58
57
|
begin
|
@@ -84,7 +83,8 @@ module Imap::Backup
|
|
84
83
|
def each_message(required_uids)
|
85
84
|
return enum_for(:each_message, required_uids) if !block_given?
|
86
85
|
|
87
|
-
indexes = required_uids.each.with_object({}) do |
|
86
|
+
indexes = required_uids.each.with_object({}) do |uid_maybe_string, acc|
|
87
|
+
uid = uid_maybe_string.to_i
|
88
88
|
index = uids.find_index(uid)
|
89
89
|
acc[index] = uid if index
|
90
90
|
end
|
data/lib/imap/backup/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,8 @@ describe Imap::Backup::Downloader do
|
|
2
2
|
describe "#run" do
|
3
3
|
subject { described_class.new(folder, serializer) }
|
4
4
|
|
5
|
-
let(:
|
5
|
+
let(:body) { "blah" }
|
6
|
+
let(:message) { {"RFC822" => body} }
|
6
7
|
let(:folder) do
|
7
8
|
instance_double(
|
8
9
|
Imap::Backup::Account::Folder,
|
@@ -18,7 +19,7 @@ describe Imap::Backup::Downloader do
|
|
18
19
|
|
19
20
|
context "with fetched messages" do
|
20
21
|
specify "are saved" do
|
21
|
-
expect(serializer).to receive(:save).with("111",
|
22
|
+
expect(serializer).to receive(:save).with("111", body)
|
22
23
|
|
23
24
|
subject.run
|
24
25
|
end
|
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,23 +156,18 @@ 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
|
-
- ".circleci/config.yml"
|
162
|
-
- ".gitignore"
|
163
|
-
- ".rspec"
|
164
|
-
- ".rspec-all"
|
165
|
-
- ".rubocop.yml"
|
166
|
-
- ".rubocop_todo.yml"
|
167
|
-
- CHANGELOG.md
|
168
|
-
- Gemfile
|
169
165
|
- LICENSE
|
170
166
|
- README.md
|
171
|
-
- Rakefile
|
172
167
|
- bin/imap-backup
|
173
|
-
-
|
174
|
-
- docs/
|
175
|
-
-
|
168
|
+
- docs/development.md
|
169
|
+
- docs/restore.md
|
170
|
+
- docs/setup.md
|
176
171
|
- imap-backup.gemspec
|
177
172
|
- lib/email/mboxrd/message.rb
|
178
173
|
- lib/email/provider.rb
|
@@ -187,6 +182,7 @@ files:
|
|
187
182
|
- lib/imap/backup/cli/restore.rb
|
188
183
|
- lib/imap/backup/cli/setup.rb
|
189
184
|
- lib/imap/backup/cli/status.rb
|
185
|
+
- lib/imap/backup/cli/utils.rb
|
190
186
|
- lib/imap/backup/configuration/account.rb
|
191
187
|
- lib/imap/backup/configuration/asker.rb
|
192
188
|
- lib/imap/backup/configuration/connection_tester.rb
|
@@ -235,12 +231,14 @@ files:
|
|
235
231
|
- spec/unit/imap/backup/uploader_spec.rb
|
236
232
|
- spec/unit/imap/backup/utils_spec.rb
|
237
233
|
- spec/unit/imap/backup_spec.rb
|
238
|
-
- tmp/.gitkeep
|
239
234
|
homepage: https://github.com/joeyates/imap-backup
|
240
|
-
licenses:
|
235
|
+
licenses:
|
236
|
+
- MIT
|
241
237
|
metadata: {}
|
242
238
|
post_install_message:
|
243
|
-
rdoc_options:
|
239
|
+
rdoc_options:
|
240
|
+
- "--main"
|
241
|
+
- README.md
|
244
242
|
require_paths:
|
245
243
|
- lib
|
246
244
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -250,44 +248,44 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
250
248
|
version: '2.5'
|
251
249
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
252
250
|
requirements:
|
253
|
-
- - "
|
251
|
+
- - ">="
|
254
252
|
- !ruby/object:Gem::Version
|
255
|
-
version:
|
253
|
+
version: '0'
|
256
254
|
requirements: []
|
257
255
|
rubygems_version: 3.1.4
|
258
256
|
signing_key:
|
259
257
|
specification_version: 4
|
260
258
|
summary: Backup GMail (or other IMAP) accounts to disk
|
261
259
|
test_files:
|
262
|
-
- spec/features/backup_spec.rb
|
263
|
-
- spec/features/helper.rb
|
264
|
-
- spec/features/restore_spec.rb
|
265
|
-
- spec/features/support/backup_directory.rb
|
266
|
-
- spec/features/support/email_server.rb
|
267
|
-
- spec/features/support/shared/connection_context.rb
|
268
|
-
- spec/features/support/shared/message_fixtures.rb
|
269
|
-
- spec/fixtures/connection.yml
|
270
|
-
- spec/gather_rspec_coverage.rb
|
271
260
|
- spec/spec_helper.rb
|
272
|
-
- spec/
|
273
|
-
- spec/support/higline_test_helpers.rb
|
274
|
-
- spec/support/shared_examples/account_flagging.rb
|
275
|
-
- spec/support/silence_logging.rb
|
276
|
-
- spec/unit/email/mboxrd/message_spec.rb
|
277
|
-
- spec/unit/email/provider_spec.rb
|
278
|
-
- spec/unit/imap/backup/account/connection_spec.rb
|
279
|
-
- spec/unit/imap/backup/account/folder_spec.rb
|
261
|
+
- spec/unit/imap/backup_spec.rb
|
280
262
|
- spec/unit/imap/backup/configuration/account_spec.rb
|
281
|
-
- spec/unit/imap/backup/configuration/asker_spec.rb
|
282
|
-
- spec/unit/imap/backup/configuration/connection_tester_spec.rb
|
283
|
-
- spec/unit/imap/backup/configuration/folder_chooser_spec.rb
|
284
263
|
- spec/unit/imap/backup/configuration/list_spec.rb
|
264
|
+
- spec/unit/imap/backup/configuration/connection_tester_spec.rb
|
285
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
|
286
268
|
- spec/unit/imap/backup/configuration/store_spec.rb
|
287
|
-
- spec/unit/imap/backup/downloader_spec.rb
|
288
|
-
- spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb
|
289
269
|
- spec/unit/imap/backup/serializer/mbox_spec.rb
|
290
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
|
291
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
|
292
276
|
- spec/unit/imap/backup/utils_spec.rb
|
293
|
-
- 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/.circleci/config.yml
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
version: 2.1
|
2
|
-
|
3
|
-
orbs:
|
4
|
-
ruby: circleci/ruby@1.1.2
|
5
|
-
|
6
|
-
references:
|
7
|
-
restore: &restore
|
8
|
-
restore_cache:
|
9
|
-
keys:
|
10
|
-
- 'imap.backup.<< parameters.ruby_version >>.{{checksum "imap-backup.gemspec"}}'
|
11
|
-
bundle: &bundle
|
12
|
-
run:
|
13
|
-
name: Install Ruby dependencies
|
14
|
-
command: |
|
15
|
-
bundle install
|
16
|
-
bundle clean
|
17
|
-
save: &save
|
18
|
-
save_cache:
|
19
|
-
key: 'imap.backup.<< parameters.ruby_version >>.{{checksum "imap-backup.gemspec"}}'
|
20
|
-
paths:
|
21
|
-
- vendor/bundle
|
22
|
-
|
23
|
-
jobs:
|
24
|
-
test:
|
25
|
-
parameters:
|
26
|
-
ruby_version:
|
27
|
-
type: string
|
28
|
-
environment:
|
29
|
-
BUNDLE_PATH: ./vendor/bundle
|
30
|
-
DOCKER_IMAP_SERVER: 993
|
31
|
-
docker:
|
32
|
-
- image: "cimg/ruby:<< parameters.ruby_version >>"
|
33
|
-
- image: antespi/docker-imap-devel:latest
|
34
|
-
environment:
|
35
|
-
MAIL_ADDRESS: address@example.org
|
36
|
-
MAIL_PASS: pass
|
37
|
-
MAILNAME: example.org
|
38
|
-
steps:
|
39
|
-
- checkout
|
40
|
-
- <<: *restore
|
41
|
-
- <<: *bundle
|
42
|
-
- <<: *save
|
43
|
-
- ruby/rspec-test
|
44
|
-
|
45
|
-
workflows:
|
46
|
-
all-tests:
|
47
|
-
jobs:
|
48
|
-
- test:
|
49
|
-
matrix:
|
50
|
-
parameters:
|
51
|
-
ruby_version: ["2.5", "2.6", "2.7"]
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rspec-all
DELETED
data/.rubocop.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
inherit_from:
|
2
|
-
- https://raw.githubusercontent.com/leanpanda-com/rubocop/0.89.1/rubocop-rspec.yml
|
3
|
-
- .rubocop_todo.yml
|
4
|
-
|
5
|
-
AllCops:
|
6
|
-
Exclude:
|
7
|
-
- "bin/stubs/*"
|
8
|
-
DisplayCopNames:
|
9
|
-
Enabled: true
|
10
|
-
|
11
|
-
RSpec/ContextWording:
|
12
|
-
Exclude:
|
13
|
-
- "spec/features/**/*"
|
14
|
-
RSpec/LeakyConstantDeclaration:
|
15
|
-
Enabled: false
|
16
|
-
RSpec/MessageSpies:
|
17
|
-
Enabled: false
|
18
|
-
RSpec/ReturnFromStub:
|
19
|
-
Enabled: false
|
20
|
-
Style/EmptyCaseCondition:
|
21
|
-
Enabled: false
|
data/.rubocop_todo.yml
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
# `rubocop --auto-gen-config`
|
3
|
-
# on 2021-09-21 15:30:34 UTC using RuboCop version 1.21.0.
|
4
|
-
# The point is for the user to remove these configuration records
|
5
|
-
# one by one as the offenses are removed from the code base.
|
6
|
-
# Note that changes in the inspected code, or installation of new
|
7
|
-
# versions of RuboCop, may require this file to be generated again.
|
8
|
-
|
9
|
-
# Offense count: 1
|
10
|
-
# Cop supports --auto-correct.
|
11
|
-
Layout/ElseAlignment:
|
12
|
-
Exclude:
|
13
|
-
- 'lib/imap/backup/configuration/gmail_oauth2.rb'
|
14
|
-
|
15
|
-
# Offense count: 2
|
16
|
-
# Cop supports --auto-correct.
|
17
|
-
# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines.
|
18
|
-
Layout/EmptyLineBetweenDefs:
|
19
|
-
Exclude:
|
20
|
-
- 'lib/google/auth/stores/in_memory_token_store.rb'
|
21
|
-
|
22
|
-
# Offense count: 1
|
23
|
-
# Cop supports --auto-correct.
|
24
|
-
# Configuration parameters: EnforcedStyleAlignWith, Severity.
|
25
|
-
# SupportedStylesAlignWith: keyword, variable, start_of_line
|
26
|
-
Layout/EndAlignment:
|
27
|
-
Exclude:
|
28
|
-
- 'lib/imap/backup/configuration/gmail_oauth2.rb'
|
29
|
-
|
30
|
-
# Offense count: 1
|
31
|
-
# Cop supports --auto-correct.
|
32
|
-
# Configuration parameters: Width, IgnoredPatterns.
|
33
|
-
Layout/IndentationWidth:
|
34
|
-
Exclude:
|
35
|
-
- 'lib/imap/backup/configuration/gmail_oauth2.rb'
|
36
|
-
|
37
|
-
# Offense count: 34
|
38
|
-
# Configuration parameters: AllowedMethods.
|
39
|
-
# AllowedMethods: enums
|
40
|
-
Lint/ConstantDefinitionInBlock:
|
41
|
-
Exclude:
|
42
|
-
- 'lib/imap/backup/configuration/asker.rb'
|
43
|
-
- 'spec/unit/gmail/authenticator_spec.rb'
|
44
|
-
- 'spec/unit/google/auth/stores/in_memory_token_store_spec.rb'
|
45
|
-
- 'spec/unit/imap/backup/account/connection_spec.rb'
|
46
|
-
- 'spec/unit/imap/backup/account/folder_spec.rb'
|
47
|
-
- 'spec/unit/imap/backup/configuration/account_spec.rb'
|
48
|
-
- 'spec/unit/imap/backup/configuration/gmail_oauth2_spec.rb'
|
49
|
-
|
50
|
-
# Offense count: 2
|
51
|
-
# Cop supports --auto-correct.
|
52
|
-
# Configuration parameters: AllowComments.
|
53
|
-
Lint/UselessMethodDefinition:
|
54
|
-
Exclude:
|
55
|
-
- 'lib/imap/backup/configuration/account.rb'
|
56
|
-
- 'lib/imap/backup/configuration/asker.rb'
|
57
|
-
|
58
|
-
# Offense count: 11
|
59
|
-
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
60
|
-
Metrics/AbcSize:
|
61
|
-
Max: 33
|
62
|
-
|
63
|
-
# Offense count: 3
|
64
|
-
# Configuration parameters: CountComments, CountAsOne.
|
65
|
-
Metrics/ClassLength:
|
66
|
-
Max: 172
|
67
|
-
|
68
|
-
# Offense count: 19
|
69
|
-
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
70
|
-
Metrics/MethodLength:
|
71
|
-
Max: 26
|
72
|
-
|
73
|
-
# Offense count: 2
|
74
|
-
# Configuration parameters: CountComments, CountAsOne.
|
75
|
-
Metrics/ModuleLength:
|
76
|
-
Max: 145
|
77
|
-
|
78
|
-
# Offense count: 2
|
79
|
-
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
|
80
|
-
# SupportedStyles: snake_case, normalcase, non_integer
|
81
|
-
# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
|
82
|
-
Naming/VariableNumber:
|
83
|
-
Exclude:
|
84
|
-
- 'lib/email/provider.rb'
|
85
|
-
- 'spec/unit/email/provider_spec.rb'
|
86
|
-
|
87
|
-
# Offense count: 209
|
88
|
-
# Configuration parameters: AllowSubject.
|
89
|
-
RSpec/MultipleMemoizedHelpers:
|
90
|
-
Max: 16
|
91
|
-
|
92
|
-
# Offense count: 49
|
93
|
-
RSpec/NestedGroups:
|
94
|
-
Max: 6
|
95
|
-
|
96
|
-
# Offense count: 8
|
97
|
-
# Cop supports --auto-correct.
|
98
|
-
# Configuration parameters: EnforcedStyle.
|
99
|
-
# SupportedStyles: nested, compact
|
100
|
-
Style/ClassAndModuleChildren:
|
101
|
-
Exclude:
|
102
|
-
- 'lib/email/mboxrd/message.rb'
|
103
|
-
- 'lib/imap/backup/downloader.rb'
|
104
|
-
- 'lib/imap/backup/serializer.rb'
|
105
|
-
- 'lib/imap/backup/serializer/mbox.rb'
|
106
|
-
- 'lib/imap/backup/serializer/mbox_enumerator.rb'
|
107
|
-
- 'lib/imap/backup/serializer/mbox_store.rb'
|
108
|
-
- 'lib/imap/backup/uploader.rb'
|
109
|
-
- 'lib/imap/backup/utils.rb'
|
110
|
-
|
111
|
-
# Offense count: 1
|
112
|
-
# Cop supports --auto-correct.
|
113
|
-
Style/RedundantBegin:
|
114
|
-
Exclude:
|
115
|
-
- 'lib/imap/backup/account/connection.rb'
|
116
|
-
|
117
|
-
# Offense count: 1
|
118
|
-
# Cop supports --auto-correct.
|
119
|
-
# Configuration parameters: MinSize, WordRegex.
|
120
|
-
# SupportedStyles: percent, brackets
|
121
|
-
Style/WordArray:
|
122
|
-
EnforcedStyle: percent
|
123
|
-
|
124
|
-
# Offense count: 1
|
125
|
-
# Cop supports --auto-correct.
|
126
|
-
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
127
|
-
# URISchemes: http, https
|
128
|
-
Layout/LineLength:
|
129
|
-
Max: 133
|
data/CHANGELOG.md
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# Change Log
|
2
|
-
All notable changes to this project will be documented in this file.
|
3
|
-
|
4
|
-
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
|
-
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
-
|
7
|
-
## [4.0.0.rc2] - 2021-11-18
|
8
|
-
|
9
|
-
### Removed
|
10
|
-
|
11
|
-
* GMail OAuth2 support. Tokens only last a few days, so this authentication
|
12
|
-
method is not usable for automated backups.
|
13
|
-
|
14
|
-
## [4.0.0.rc1] - 2021-11-17
|
15
|
-
|
16
|
-
### Added
|
17
|
-
|
18
|
-
* `local` commands to list accounts, folders and emails and to view single
|
19
|
-
emails.
|
data/Gemfile
DELETED
data/Rakefile
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rspec/core/rake_task"
|
3
|
-
require "rubocop/rake_task"
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new do |t|
|
6
|
-
t.pattern = "spec/**/*_spec.rb"
|
7
|
-
end
|
8
|
-
|
9
|
-
desc "Run RSpec examples, excluding ones relying on Docker IMAP"
|
10
|
-
RSpec::Core::RakeTask.new("no-docker") do |t|
|
11
|
-
t.pattern = "spec/**/*_spec.rb"
|
12
|
-
t.rspec_opts = "--tag ~docker"
|
13
|
-
end
|
14
|
-
|
15
|
-
RuboCop::RakeTask.new
|
16
|
-
|
17
|
-
task default: :spec
|
18
|
-
task default: :rubocop
|
data/docker-compose.yml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# This file adapted from github.com/antespi/docker-imap-devel
|
2
|
-
version: "3"
|
3
|
-
|
4
|
-
services:
|
5
|
-
imap:
|
6
|
-
image: antespi/docker-imap-devel:latest
|
7
|
-
container_name: imap
|
8
|
-
ports:
|
9
|
-
- "8025:25"
|
10
|
-
- "8143:143"
|
11
|
-
- "8993:993"
|
12
|
-
environment:
|
13
|
-
- MAILNAME=example.org
|
14
|
-
- MAIL_ADDRESS=address@example.org
|
15
|
-
- MAIL_PASS=pass
|
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
|
-
```
|
data/imap-backup
DELETED
data/tmp/.gitkeep
DELETED
File without changes
|