imap-backup 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|