imap-backup 2.2.1 → 2.2.2
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/.rubocop.yml +1 -2
- data/.rubocop_todo.yml +42 -8
- data/.travis.yml +1 -1
- data/bin/imap-backup +1 -1
- data/imap-backup.gemspec +1 -1
- data/lib/email/mboxrd/message.rb +2 -2
- data/lib/imap/backup/serializer/mbox.rb +4 -0
- data/lib/imap/backup/serializer/mbox_store.rb +20 -4
- data/lib/imap/backup/uploader.rb +1 -2
- data/lib/imap/backup/version.rb +1 -1
- data/spec/features/backup_spec.rb +2 -2
- data/spec/features/helper.rb +1 -1
- data/spec/features/support/backup_directory.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/support/fixtures.rb +1 -1
- data/spec/unit/email/mboxrd/message_spec.rb +2 -2
- data/spec/unit/email/provider_spec.rb +2 -2
- data/spec/unit/imap/backup/serializer/mbox_spec.rb +8 -0
- data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +45 -4
- data/spec/unit/imap/backup/uploader_spec.rb +5 -2
- data/spec/unit/imap/backup/utils_spec.rb +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 726ef170419a3bcdc1a39517cdd81640ca0674f5d5f5452f8bc97ef819d74031
|
4
|
+
data.tar.gz: 8fc24ed36537a68899a45e22afa3fcf1dee90c27e8432853c2d88e5b4d5c5325
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2b59fa22614c634169104d75ad6214a0d8c788da712a8c3545281e98666b4d23b17e1a10cc1744fcf615966bd63616daa3241f7e932d2af4d10fd4508391583
|
7
|
+
data.tar.gz: 9e73290e3684aadc443f449f870c7ed8d23506408439bb69dc41b57613e8e439e32a4017f8dbfaf462ea5dac5fd029a0d4691c861600d4aaeeaff290e94e9215
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,24 +1,58 @@
|
|
1
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2020-09-24 16:30:54 UTC using RuboCop version 0.89.1.
|
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: 10
|
10
|
+
# Configuration parameters: IgnoredMethods.
|
2
11
|
Metrics/AbcSize:
|
3
12
|
Max: 29
|
4
13
|
|
5
14
|
# Offense count: 2
|
6
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
15
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
7
16
|
# ExcludedMethods: refine
|
8
17
|
Metrics/BlockLength:
|
9
18
|
Max: 133
|
10
19
|
|
11
20
|
# Offense count: 2
|
12
|
-
# Configuration parameters: CountComments.
|
21
|
+
# Configuration parameters: CountComments, CountAsOne.
|
13
22
|
Metrics/ClassLength:
|
14
|
-
Max:
|
23
|
+
Max: 167
|
15
24
|
|
16
|
-
# Offense count:
|
17
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
25
|
+
# Offense count: 14
|
26
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
18
27
|
Metrics/MethodLength:
|
19
28
|
Max: 25
|
20
29
|
|
21
|
-
# Offense count:
|
22
|
-
# Configuration parameters: CountComments.
|
30
|
+
# Offense count: 2
|
31
|
+
# Configuration parameters: CountComments, CountAsOne.
|
23
32
|
Metrics/ModuleLength:
|
24
33
|
Max: 136
|
34
|
+
|
35
|
+
# Offense count: 181
|
36
|
+
# Configuration parameters: AllowSubject.
|
37
|
+
RSpec/MultipleMemoizedHelpers:
|
38
|
+
Max: 19
|
39
|
+
|
40
|
+
# Offense count: 1
|
41
|
+
# Cop supports --auto-correct.
|
42
|
+
Style/GlobalStdStream:
|
43
|
+
Exclude:
|
44
|
+
- 'lib/imap/backup.rb'
|
45
|
+
|
46
|
+
# Offense count: 3
|
47
|
+
# Cop supports --auto-correct.
|
48
|
+
Style/IfUnlessModifier:
|
49
|
+
Exclude:
|
50
|
+
- 'bin/imap-backup'
|
51
|
+
- 'lib/email/mboxrd/message.rb'
|
52
|
+
- 'lib/imap/backup/configuration/account.rb'
|
53
|
+
|
54
|
+
# Offense count: 1
|
55
|
+
# Cop supports --auto-correct.
|
56
|
+
Style/RedundantRegexpEscape:
|
57
|
+
Exclude:
|
58
|
+
- 'spec/features/backup_spec.rb'
|
data/.travis.yml
CHANGED
data/bin/imap-backup
CHANGED
data/imap-backup.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
14
14
|
gem.test_files = gem.files.grep(%r{^spec/})
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.required_ruby_version = [">= 2.
|
16
|
+
gem.required_ruby_version = [">= 2.4.0"]
|
17
17
|
gem.version = Imap::Backup::VERSION
|
18
18
|
|
19
19
|
gem.post_install_message = <<-MESSAGE.gsub(/^\s{4}/m, "")
|
data/lib/email/mboxrd/message.rb
CHANGED
@@ -21,7 +21,7 @@ module Email::Mboxrd
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def to_serialized
|
24
|
-
"From
|
24
|
+
"From #{from}\n" + mboxrd_body
|
25
25
|
end
|
26
26
|
|
27
27
|
def date
|
@@ -44,7 +44,7 @@ module Email::Mboxrd
|
|
44
44
|
@from ||=
|
45
45
|
begin
|
46
46
|
from = best_from.dup
|
47
|
-
from << " "
|
47
|
+
from << " #{asctime}" if asctime != ""
|
48
48
|
from
|
49
49
|
end
|
50
50
|
end
|
@@ -81,6 +81,22 @@ module Imap::Backup
|
|
81
81
|
load_nth(message_index)
|
82
82
|
end
|
83
83
|
|
84
|
+
def each_message(required_uids)
|
85
|
+
return enum_for(:each_message, required_uids) if !block_given?
|
86
|
+
|
87
|
+
indexes = required_uids.each.with_object({}) do |uid, acc|
|
88
|
+
index = uids.find_index(uid)
|
89
|
+
acc[index] = uid if index
|
90
|
+
end
|
91
|
+
enumerator = Serializer::MboxEnumerator.new(mbox_pathname)
|
92
|
+
enumerator.each.with_index do |raw, i|
|
93
|
+
uid = indexes[i]
|
94
|
+
next if !uid
|
95
|
+
|
96
|
+
yield uid, Email::Mboxrd::Message.from_serialized(raw)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
84
100
|
def update_uid(old, new)
|
85
101
|
index = uids.find_index(old.to_i)
|
86
102
|
return if index.nil?
|
@@ -98,8 +114,8 @@ module Imap::Backup
|
|
98
114
|
end
|
99
115
|
|
100
116
|
def rename(new_name)
|
101
|
-
new_mbox_pathname = absolute_path(new_name
|
102
|
-
new_imap_pathname = absolute_path(new_name
|
117
|
+
new_mbox_pathname = absolute_path("#{new_name}.mbox")
|
118
|
+
new_imap_pathname = absolute_path("#{new_name}.imap")
|
103
119
|
File.rename(mbox_pathname, new_mbox_pathname)
|
104
120
|
File.rename(imap_pathname, new_imap_pathname)
|
105
121
|
@folder = new_name
|
@@ -191,11 +207,11 @@ module Imap::Backup
|
|
191
207
|
end
|
192
208
|
|
193
209
|
def mbox_pathname
|
194
|
-
absolute_path(folder
|
210
|
+
absolute_path("#{folder}.mbox")
|
195
211
|
end
|
196
212
|
|
197
213
|
def imap_pathname
|
198
|
-
absolute_path(folder
|
214
|
+
absolute_path("#{folder}.imap")
|
199
215
|
end
|
200
216
|
end
|
201
217
|
end
|
data/lib/imap/backup/uploader.rb
CHANGED
@@ -13,8 +13,7 @@ module Imap::Backup
|
|
13
13
|
return if count.zero?
|
14
14
|
|
15
15
|
Imap::Backup.logger.debug "[#{folder.name}] #{count} to restore"
|
16
|
-
missing_uids.
|
17
|
-
message = serializer.load(uid)
|
16
|
+
serializer.each_message(missing_uids).with_index do |(uid, message), i|
|
18
17
|
next if message.nil?
|
19
18
|
|
20
19
|
log_prefix = "[#{folder.name}] uid: #{uid} (#{i + 1}/#{count}) -"
|
data/lib/imap/backup/version.rb
CHANGED
@@ -60,7 +60,7 @@ RSpec.describe "backup", type: :feature, docker: true do
|
|
60
60
|
connection.run_backup
|
61
61
|
server_rename_folder folder, new_name
|
62
62
|
end
|
63
|
-
let(:renamed_folder) { folder
|
63
|
+
let(:renamed_folder) { "#{folder}.#{original_folder_uid_validity}" }
|
64
64
|
|
65
65
|
after do
|
66
66
|
server_delete_folder new_name
|
@@ -82,7 +82,7 @@ RSpec.describe "backup", type: :feature, docker: true do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it "moves the old backup to a uniquely named directory" do
|
85
|
-
renamed = folder
|
85
|
+
renamed = "#{folder}.#{original_folder_uid_validity}.1"
|
86
86
|
expect(mbox_content(renamed)).to eq(message_as_mbox_entry(msg3))
|
87
87
|
end
|
88
88
|
end
|
data/spec/features/helper.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
support_glob = File.expand_path("support/**/*.rb", __dir__)
|
2
|
-
Dir[support_glob].each { |f| require f }
|
2
|
+
Dir[support_glob].sort.each { |f| require f }
|
@@ -26,11 +26,11 @@ module BackupDirectoryHelpers
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def mbox_path(name)
|
29
|
-
File.join(local_backup_path, name
|
29
|
+
File.join(local_backup_path, "#{name}.mbox")
|
30
30
|
end
|
31
31
|
|
32
32
|
def imap_path(name)
|
33
|
-
File.join(local_backup_path, name
|
33
|
+
File.join(local_backup_path, "#{name}.imap")
|
34
34
|
end
|
35
35
|
|
36
36
|
def imap_content(name)
|
data/spec/spec_helper.rb
CHANGED
@@ -7,7 +7,7 @@ spec_path = File.dirname(__FILE__)
|
|
7
7
|
$LOAD_PATH << File.expand_path("../lib", spec_path)
|
8
8
|
|
9
9
|
support_glob = File.join(spec_path, "support", "**", "*.rb")
|
10
|
-
Dir[support_glob].each { |f| require f }
|
10
|
+
Dir[support_glob].sort.each { |f| require f }
|
11
11
|
|
12
12
|
require "simplecov"
|
13
13
|
SimpleCov.start do
|
data/spec/support/fixtures.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
def fixture(name)
|
2
2
|
spec_root = File.expand_path("..", File.dirname(__FILE__))
|
3
|
-
fixture_path = File.join(spec_root, "fixtures", name
|
3
|
+
fixture_path = File.join(spec_root, "fixtures", "#{name}.yml")
|
4
4
|
fixture = File.read(fixture_path)
|
5
5
|
YAML.safe_load(fixture, [Symbol])
|
6
6
|
end
|
@@ -129,7 +129,7 @@ describe Email::Mboxrd::Message do
|
|
129
129
|
let(:message_body) { msg_no_from_but_return_path }
|
130
130
|
|
131
131
|
it "'return path' is used as 'from'" do
|
132
|
-
expect(subject.to_serialized).to start_with("From
|
132
|
+
expect(subject.to_serialized).to start_with("From #{from}\n")
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
@@ -137,7 +137,7 @@ describe Email::Mboxrd::Message do
|
|
137
137
|
let(:message_body) { msg_no_from_but_sender }
|
138
138
|
|
139
139
|
it "Sender is used as 'from'" do
|
140
|
-
expect(subject.to_serialized).to start_with("From
|
140
|
+
expect(subject.to_serialized).to start_with("From #{from}\n")
|
141
141
|
end
|
142
142
|
end
|
143
143
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
describe Email::Provider do
|
2
|
+
subject { described_class.new(:gmail) }
|
3
|
+
|
2
4
|
describe ".for_address" do
|
3
5
|
context "with known providers" do
|
4
6
|
[
|
@@ -20,8 +22,6 @@ describe Email::Provider do
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
subject { described_class.new(:gmail) }
|
24
|
-
|
25
25
|
describe "#options" do
|
26
26
|
it "returns options" do
|
27
27
|
expect(subject.options).to be_a(Hash)
|
@@ -182,6 +182,14 @@ describe Imap::Backup::Serializer::Mbox do
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
+
describe "#each_message" do
|
186
|
+
it "calls the store" do
|
187
|
+
expect(store).to receive(:each_message).with([1])
|
188
|
+
|
189
|
+
subject.each_message([1])
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
185
193
|
describe "#save" do
|
186
194
|
it "calls the store" do
|
187
195
|
expect(store).to receive(:add).with("foo", "bar")
|
@@ -4,10 +4,10 @@ describe Imap::Backup::Serializer::MboxStore do
|
|
4
4
|
let(:base_path) { "/base/path" }
|
5
5
|
let(:folder) { "the/folder" }
|
6
6
|
let(:folder_path) { File.join(base_path, folder) }
|
7
|
-
let(:imap_pathname) { folder_path
|
7
|
+
let(:imap_pathname) { "#{folder_path}.imap" }
|
8
8
|
let(:imap_exists) { true }
|
9
9
|
let(:imap_file) { instance_double(File, write: nil, close: nil) }
|
10
|
-
let(:mbox_pathname) { folder_path
|
10
|
+
let(:mbox_pathname) { "#{folder_path}.mbox" }
|
11
11
|
let(:mbox_exists) { true }
|
12
12
|
let(:mbox_file) { instance_double(File, write: nil, close: nil) }
|
13
13
|
let(:uids) { [3, 2, 1] }
|
@@ -208,6 +208,47 @@ describe Imap::Backup::Serializer::MboxStore do
|
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
211
|
+
describe "#each_message" do
|
212
|
+
let(:enumerator) do
|
213
|
+
instance_double(Imap::Backup::Serializer::MboxEnumerator)
|
214
|
+
end
|
215
|
+
let(:enumeration) { instance_double(Enumerator) }
|
216
|
+
|
217
|
+
before do
|
218
|
+
allow(Imap::Backup::Serializer::MboxEnumerator).
|
219
|
+
to receive(:new) { enumerator }
|
220
|
+
allow(enumerator).to receive(:each) { enumeration }
|
221
|
+
allow(enumeration).
|
222
|
+
to receive(:with_index).
|
223
|
+
and_yield("", 0).
|
224
|
+
and_yield("", 1).
|
225
|
+
and_yield("ciao", 2)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "yields messages" do
|
229
|
+
expect { |b| subject.each_message([1], &b) }.
|
230
|
+
to yield_successive_args([1, instance_of(Email::Mboxrd::Message)])
|
231
|
+
end
|
232
|
+
|
233
|
+
it "yields the requested message uid" do
|
234
|
+
subject.each_message([1]) do |uid, _message|
|
235
|
+
expect(uid).to eq(1)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
it "yields the requested message" do
|
240
|
+
subject.each_message([1]) do |_uid, message|
|
241
|
+
expect(message.supplied_body).to eq("ciao")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context "without a block" do
|
246
|
+
it "returns an Enumerator" do
|
247
|
+
expect(subject.each_message([1])).to be_a(Enumerator)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
211
252
|
describe "#update_uid" do
|
212
253
|
let(:old_uid) { "2" }
|
213
254
|
let(:updated_imap_content) do
|
@@ -258,8 +299,8 @@ describe Imap::Backup::Serializer::MboxStore do
|
|
258
299
|
describe "#rename" do
|
259
300
|
let(:new_name) { "new_name" }
|
260
301
|
let(:new_folder_path) { File.join(base_path, new_name) }
|
261
|
-
let(:new_imap_name) { new_folder_path
|
262
|
-
let(:new_mbox_name) { new_folder_path
|
302
|
+
let(:new_imap_name) { "#{new_folder_path}.imap" }
|
303
|
+
let(:new_mbox_name) { "#{new_folder_path}.mbox" }
|
263
304
|
|
264
305
|
before do
|
265
306
|
allow(File).to receive(:rename).and_call_original
|
@@ -20,10 +20,13 @@ describe Imap::Backup::Uploader do
|
|
20
20
|
instance_double(Email::Mboxrd::Message, supplied_body: "existing message")
|
21
21
|
end
|
22
22
|
|
23
|
+
def message_enumerator
|
24
|
+
yield [1, missing_message]
|
25
|
+
end
|
26
|
+
|
23
27
|
describe "#run" do
|
24
28
|
before do
|
25
|
-
allow(serializer).to receive(:
|
26
|
-
allow(serializer).to receive(:load).with(2) { existing_message }
|
29
|
+
allow(serializer).to receive(:each_message).and_return(enum_for(:message_enumerator))
|
27
30
|
end
|
28
31
|
|
29
32
|
context "with messages that are missing" do
|
@@ -12,6 +12,7 @@ describe Imap::Backup::Utils do
|
|
12
12
|
describe ".check_permissions" do
|
13
13
|
let(:requested) { 0o345 }
|
14
14
|
|
15
|
+
# rubocop:disable RSpec/EmptyExampleGroup
|
15
16
|
context "with existing files" do
|
16
17
|
[
|
17
18
|
[0o100, "less than the limit", true],
|
@@ -36,6 +37,7 @@ describe Imap::Backup::Utils do
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
40
|
+
# rubocop:enable RSpec/EmptyExampleGroup
|
39
41
|
|
40
42
|
context "with non-existent files" do
|
41
43
|
let(:exists) { false }
|
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: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -212,14 +212,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
212
212
|
requirements:
|
213
213
|
- - ">="
|
214
214
|
- !ruby/object:Gem::Version
|
215
|
-
version: 2.
|
215
|
+
version: 2.4.0
|
216
216
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
217
|
requirements:
|
218
218
|
- - ">="
|
219
219
|
- !ruby/object:Gem::Version
|
220
220
|
version: '0'
|
221
221
|
requirements: []
|
222
|
-
rubygems_version: 3.
|
222
|
+
rubygems_version: 3.1.2
|
223
223
|
signing_key:
|
224
224
|
specification_version: 4
|
225
225
|
summary: Backup GMail (or other IMAP) accounts to disk
|