imap-backup 5.2.0 → 6.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 +9 -2
- data/docs/development.md +10 -4
- data/imap-backup.gemspec +5 -1
- data/lib/cli_coverage.rb +11 -11
- data/lib/email/provider/base.rb +2 -0
- data/lib/email/provider/unknown.rb +2 -0
- data/lib/email/provider.rb +2 -0
- data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
- data/lib/imap/backup/account/connection/client_factory.rb +54 -0
- data/lib/imap/backup/account/connection/folder_names.rb +26 -0
- data/lib/imap/backup/account/connection.rb +17 -105
- data/lib/imap/backup/account/folder.rb +9 -6
- data/lib/imap/backup/account.rb +36 -16
- data/lib/imap/backup/cli/backup.rb +1 -3
- data/lib/imap/backup/cli/folders.rb +3 -3
- data/lib/imap/backup/cli/helpers.rb +24 -22
- data/lib/imap/backup/cli/local.rb +20 -13
- data/lib/imap/backup/cli/migrate.rb +5 -11
- data/lib/imap/backup/cli/restore.rb +8 -7
- data/lib/imap/backup/cli/setup.rb +10 -8
- data/lib/imap/backup/cli/stats.rb +78 -0
- data/lib/imap/backup/cli/status.rb +2 -2
- data/lib/imap/backup/cli/utils.rb +6 -8
- data/lib/imap/backup/cli.rb +24 -3
- data/lib/imap/backup/configuration.rb +9 -21
- data/lib/imap/backup/downloader.rb +56 -34
- data/lib/imap/backup/migrator.rb +5 -5
- data/lib/imap/backup/sanitizer.rb +3 -2
- data/lib/imap/backup/serializer/appender.rb +49 -0
- data/lib/imap/backup/serializer/directory.rb +37 -0
- data/lib/imap/backup/serializer/imap.rb +144 -0
- data/lib/imap/backup/serializer/mbox.rb +33 -88
- data/lib/imap/backup/serializer/mbox_enumerator.rb +2 -0
- data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
- data/lib/imap/backup/serializer/unused_name_finder.rb +25 -0
- data/lib/imap/backup/serializer.rb +160 -3
- data/lib/imap/backup/setup/account/header.rb +75 -0
- data/lib/imap/backup/setup/account.rb +41 -95
- data/lib/imap/backup/setup/asker.rb +4 -15
- data/lib/imap/backup/setup/backup_path.rb +41 -0
- data/lib/imap/backup/setup/email.rb +45 -0
- data/lib/imap/backup/setup/folder_chooser.rb +3 -3
- data/lib/imap/backup/setup/helpers.rb +2 -2
- data/lib/imap/backup/setup.rb +5 -4
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +41 -22
- data/lib/imap/backup/uploader.rb +46 -8
- data/lib/imap/backup/utils.rb +1 -1
- data/lib/imap/backup/version.rb +3 -3
- data/lib/imap/backup.rb +0 -2
- metadata +31 -105
- data/lib/imap/backup/serializer/mbox_store.rb +0 -217
- data/spec/features/backup_spec.rb +0 -108
- data/spec/features/configuration/minimal_configuration.rb +0 -15
- data/spec/features/configuration/missing_configuration.rb +0 -14
- data/spec/features/folders_spec.rb +0 -36
- data/spec/features/helper.rb +0 -2
- data/spec/features/local/list_accounts_spec.rb +0 -12
- data/spec/features/local/list_emails_spec.rb +0 -21
- data/spec/features/local/list_folders_spec.rb +0 -21
- data/spec/features/local/show_an_email_spec.rb +0 -34
- data/spec/features/migrate_spec.rb +0 -35
- data/spec/features/remote/list_account_folders_spec.rb +0 -16
- data/spec/features/restore_spec.rb +0 -162
- data/spec/features/status_spec.rb +0 -43
- data/spec/features/support/aruba.rb +0 -77
- data/spec/features/support/backup_directory.rb +0 -43
- data/spec/features/support/email_server.rb +0 -110
- data/spec/features/support/shared/connection_context.rb +0 -14
- data/spec/features/support/shared/message_fixtures.rb +0 -16
- data/spec/fixtures/connection.yml +0 -7
- data/spec/spec_helper.rb +0 -15
- data/spec/support/fixtures.rb +0 -11
- data/spec/support/higline_test_helpers.rb +0 -8
- data/spec/support/silence_logging.rb +0 -7
- data/spec/unit/email/mboxrd/message_spec.rb +0 -177
- data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
- data/spec/unit/email/provider/base_spec.rb +0 -11
- data/spec/unit/email/provider/fastmail_spec.rb +0 -7
- data/spec/unit/email/provider/gmail_spec.rb +0 -7
- data/spec/unit/email/provider_spec.rb +0 -27
- data/spec/unit/imap/backup/account/connection_spec.rb +0 -405
- data/spec/unit/imap/backup/account/folder_spec.rb +0 -251
- data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -47
- data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
- data/spec/unit/imap/backup/cli/local_spec.rb +0 -81
- data/spec/unit/imap/backup/cli/utils_spec.rb +0 -62
- data/spec/unit/imap/backup/client/default_spec.rb +0 -22
- data/spec/unit/imap/backup/configuration_spec.rb +0 -238
- data/spec/unit/imap/backup/downloader_spec.rb +0 -44
- data/spec/unit/imap/backup/logger_spec.rb +0 -48
- data/spec/unit/imap/backup/migrator_spec.rb +0 -58
- data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +0 -45
- data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -222
- data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +0 -329
- data/spec/unit/imap/backup/setup/account_spec.rb +0 -366
- data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
- data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
- data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
- data/spec/unit/imap/backup/setup_spec.rb +0 -301
- data/spec/unit/imap/backup/uploader_spec.rb +0 -54
- data/spec/unit/imap/backup/utils_spec.rb +0 -92
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
require "features/helper"
|
|
2
|
-
|
|
3
|
-
RSpec.describe "Migration", type: :aruba, docker: true do
|
|
4
|
-
let(:email) { "me@example.com" }
|
|
5
|
-
let(:folder) { "my_folder" }
|
|
6
|
-
let(:source_account) do
|
|
7
|
-
{
|
|
8
|
-
username: email,
|
|
9
|
-
local_path: File.join(config_path, email.gsub("@", "_"))
|
|
10
|
-
}
|
|
11
|
-
end
|
|
12
|
-
let(:destination_account) { fixture("connection") }
|
|
13
|
-
|
|
14
|
-
before do
|
|
15
|
-
create_config(accounts: [source_account, destination_account])
|
|
16
|
-
store_email(email: email, folder: folder, subject: "Ciao")
|
|
17
|
-
run_command_and_stop("imap-backup migrate #{email} #{destination_account[:username]}")
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
after do
|
|
21
|
-
delete_emails(folder)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "copies email to the destination account" do
|
|
25
|
-
messages = server_messages(folder)
|
|
26
|
-
expected = <<~MESSAGE.gsub("\n", "\r\n")
|
|
27
|
-
From: sender@example.com
|
|
28
|
-
Subject: Ciao
|
|
29
|
-
|
|
30
|
-
body
|
|
31
|
-
|
|
32
|
-
MESSAGE
|
|
33
|
-
expect(messages[0]["BODY[]"]).to eq(expected)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require "features/helper"
|
|
2
|
-
|
|
3
|
-
RSpec.describe "List account folders", type: :aruba do
|
|
4
|
-
let(:account) do
|
|
5
|
-
fixture("connection")
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
before do
|
|
9
|
-
create_config(accounts: [account])
|
|
10
|
-
run_command_and_stop("imap-backup remote folders #{account[:username]}")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "lists folders" do
|
|
14
|
-
expect(last_command_started).to have_output(/"INBOX"/)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
require "features/helper"
|
|
2
|
-
|
|
3
|
-
RSpec.describe "restore", type: :aruba, docker: true do
|
|
4
|
-
include_context "imap-backup connection"
|
|
5
|
-
include_context "message-fixtures"
|
|
6
|
-
|
|
7
|
-
let(:local_backup_path) { File.expand_path("~/backup") }
|
|
8
|
-
let(:folder) { "my-stuff" }
|
|
9
|
-
let(:messages_as_mbox) do
|
|
10
|
-
message_as_mbox_entry(msg1) + message_as_mbox_entry(msg2)
|
|
11
|
-
end
|
|
12
|
-
let(:messages_as_server_messages) do
|
|
13
|
-
[message_as_server_message(msg1), message_as_server_message(msg2)]
|
|
14
|
-
end
|
|
15
|
-
let(:message_uids) { [msg1[:uid], msg2[:uid]] }
|
|
16
|
-
let(:existing_imap_content) { imap_data(uid_validity, message_uids).to_json }
|
|
17
|
-
let(:uid_validity) { 1234 }
|
|
18
|
-
|
|
19
|
-
let!(:pre) {}
|
|
20
|
-
let!(:setup) do
|
|
21
|
-
create_directory local_backup_path
|
|
22
|
-
File.write(imap_path(folder), existing_imap_content)
|
|
23
|
-
File.write(mbox_path(folder), messages_as_mbox)
|
|
24
|
-
create_config(accounts: [account.to_h])
|
|
25
|
-
|
|
26
|
-
run_command_and_stop("imap-backup restore #{account.username}")
|
|
27
|
-
end
|
|
28
|
-
let(:cleanup) do
|
|
29
|
-
server_delete_folder folder
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
after { cleanup }
|
|
33
|
-
|
|
34
|
-
context "when the folder doesn't exist" do
|
|
35
|
-
it "restores messages" do
|
|
36
|
-
messages = server_messages(folder).map { |m| server_message_to_body(m) }
|
|
37
|
-
expect(messages).to eq(messages_as_server_messages)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "updates local uids to match the new server ones" do
|
|
41
|
-
updated_imap_content = imap_parsed(folder)
|
|
42
|
-
expect(server_uids(folder)).to eq(updated_imap_content[:uids])
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it "sets the backup uid_validity to match the new folder" do
|
|
46
|
-
updated_imap_content = imap_parsed(folder)
|
|
47
|
-
expect(updated_imap_content[:uid_validity]).
|
|
48
|
-
to eq(server_uid_validity(folder))
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context "when the folder exists" do
|
|
53
|
-
let(:email3) { send_email folder, msg3 }
|
|
54
|
-
|
|
55
|
-
context "when the uid_validity matches" do
|
|
56
|
-
let(:pre) do
|
|
57
|
-
server_create_folder folder
|
|
58
|
-
email3
|
|
59
|
-
uid_validity
|
|
60
|
-
end
|
|
61
|
-
let(:messages_as_server_messages) do
|
|
62
|
-
[
|
|
63
|
-
message_as_server_message(msg3),
|
|
64
|
-
message_as_server_message(msg1),
|
|
65
|
-
message_as_server_message(msg2)
|
|
66
|
-
]
|
|
67
|
-
end
|
|
68
|
-
let(:uid_validity) { server_uid_validity(folder) }
|
|
69
|
-
|
|
70
|
-
it "appends to the existing folder" do
|
|
71
|
-
messages = server_messages(folder).map { |m| server_message_to_body(m) }
|
|
72
|
-
expect(messages).to eq(messages_as_server_messages)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
context "when the uid_validity doesn't match" do
|
|
77
|
-
context "when the folder is empty" do
|
|
78
|
-
let(:pre) do
|
|
79
|
-
server_create_folder folder
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it "sets the backup uid_validity to match the folder" do
|
|
83
|
-
updated_imap_content = imap_parsed(folder)
|
|
84
|
-
expect(updated_imap_content[:uid_validity]).
|
|
85
|
-
to eq(server_uid_validity(folder))
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "uploads to the new folder" do
|
|
89
|
-
messages = server_messages(folder).map do |m|
|
|
90
|
-
server_message_to_body(m)
|
|
91
|
-
end
|
|
92
|
-
expect(messages).to eq(messages_as_server_messages)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
context "when the folder has content" do
|
|
97
|
-
let(:new_folder) { "#{folder}-#{uid_validity}" }
|
|
98
|
-
let(:cleanup) do
|
|
99
|
-
server_delete_folder new_folder
|
|
100
|
-
super()
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
let(:pre) do
|
|
104
|
-
server_create_folder folder
|
|
105
|
-
email3
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it "renames the backup" do
|
|
109
|
-
expect(mbox_content(new_folder)).to eq(messages_as_mbox)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it "leaves the existing folder as is" do
|
|
113
|
-
messages = server_messages(folder).map do |m|
|
|
114
|
-
server_message_to_body(m)
|
|
115
|
-
end
|
|
116
|
-
expect(messages).to eq([message_as_server_message(msg3)])
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it "creates the new folder" do
|
|
120
|
-
expect(server_folders.map(&:name)).to include(new_folder)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
it "sets the backup uid_validity to match the new folder" do
|
|
124
|
-
updated_imap_content = imap_parsed(new_folder)
|
|
125
|
-
expect(updated_imap_content[:uid_validity]).
|
|
126
|
-
to eq(server_uid_validity(new_folder))
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
it "uploads to the new folder" do
|
|
130
|
-
messages = server_messages(new_folder).map do |m|
|
|
131
|
-
server_message_to_body(m)
|
|
132
|
-
end
|
|
133
|
-
expect(messages).to eq(messages_as_server_messages)
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
context "when non-Unicode encodings are used" do
|
|
140
|
-
let(:server_message) do
|
|
141
|
-
message_as_server_message(msg_iso8859)
|
|
142
|
-
end
|
|
143
|
-
let(:messages_as_mbox) do
|
|
144
|
-
message_as_mbox_entry(msg_iso8859)
|
|
145
|
-
end
|
|
146
|
-
let(:message_uids) { [uid_iso8859] }
|
|
147
|
-
let(:uid_validity) { server_uid_validity(folder) }
|
|
148
|
-
|
|
149
|
-
let(:pre) do
|
|
150
|
-
server_create_folder folder
|
|
151
|
-
uid_validity
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
it "maintains encodings" do
|
|
155
|
-
message =
|
|
156
|
-
server_messages(folder).
|
|
157
|
-
first["BODY[]"]
|
|
158
|
-
|
|
159
|
-
expect(message).to eq(server_message)
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
require "features/helper"
|
|
2
|
-
require "imap/backup/cli/status"
|
|
3
|
-
|
|
4
|
-
RSpec.describe "status", type: :feature, docker: true do
|
|
5
|
-
include_context "imap-backup connection"
|
|
6
|
-
include_context "message-fixtures"
|
|
7
|
-
|
|
8
|
-
context "when there are non-backed-up messages" do
|
|
9
|
-
let(:options) do
|
|
10
|
-
{accounts: "address@example.org"}
|
|
11
|
-
end
|
|
12
|
-
let(:folder) { "my-stuff" }
|
|
13
|
-
let(:backup_folders) { [{name: folder}] }
|
|
14
|
-
let(:email1) { send_email folder, msg1 }
|
|
15
|
-
let(:output) { StringIO.new }
|
|
16
|
-
|
|
17
|
-
before do
|
|
18
|
-
allow(Imap::Backup::CLI::Accounts).to receive(:new) { [account] }
|
|
19
|
-
server_create_folder folder
|
|
20
|
-
email1
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
around do |example|
|
|
24
|
-
stdout = $stdout
|
|
25
|
-
$stdout = output
|
|
26
|
-
example.run
|
|
27
|
-
$stdout = stdout
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
after do
|
|
31
|
-
FileUtils.rm_rf local_backup_path
|
|
32
|
-
delete_emails folder
|
|
33
|
-
server_delete_folder folder
|
|
34
|
-
connection.disconnect
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it "prints the number" do
|
|
38
|
-
Imap::Backup::CLI::Status.new(options).run
|
|
39
|
-
|
|
40
|
-
expect(output.string).to eq("address@example.org\nmy-stuff: 1\n")
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
require "aruba/rspec"
|
|
2
|
-
|
|
3
|
-
require_relative "backup_directory"
|
|
4
|
-
|
|
5
|
-
Aruba.configure do |config|
|
|
6
|
-
config.home_directory = File.expand_path("./tmp/home")
|
|
7
|
-
config.allow_absolute_paths = true
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module ConfigurationHelpers
|
|
11
|
-
def config_path
|
|
12
|
-
File.expand_path("~/.imap-backup")
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def create_config(accounts:, debug: false)
|
|
16
|
-
pathname = File.join(config_path, "config.json")
|
|
17
|
-
save_data = {
|
|
18
|
-
version: Imap::Backup::Configuration::VERSION,
|
|
19
|
-
accounts: accounts,
|
|
20
|
-
debug: debug
|
|
21
|
-
}
|
|
22
|
-
FileUtils.mkdir_p config_path
|
|
23
|
-
File.open(pathname, "w") { |f| f.write(JSON.pretty_generate(save_data)) }
|
|
24
|
-
FileUtils.chmod(0o600, pathname)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
module StoreHelpers
|
|
29
|
-
def store_email(
|
|
30
|
-
email:, folder:,
|
|
31
|
-
uid: 1,
|
|
32
|
-
from: "sender@example.com",
|
|
33
|
-
subject: "The Subject",
|
|
34
|
-
body: "body"
|
|
35
|
-
)
|
|
36
|
-
account = config.accounts.find { |a| a.username == email }
|
|
37
|
-
raise "Account not found" if !account
|
|
38
|
-
FileUtils.mkdir_p account.local_path
|
|
39
|
-
store = Imap::Backup::Serializer::MboxStore.new(account.local_path, folder)
|
|
40
|
-
store.uid_validity = "42" if !store.uid_validity
|
|
41
|
-
serialized = to_serialized(from: from, subject: subject, body: body)
|
|
42
|
-
store.add(uid, serialized)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def to_serialized(from:, subject:, body:)
|
|
46
|
-
body_and_headers = <<~BODY
|
|
47
|
-
From: #{from}
|
|
48
|
-
Subject: #{subject}
|
|
49
|
-
|
|
50
|
-
#{body}
|
|
51
|
-
BODY
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def config
|
|
55
|
-
Imap::Backup::Configuration.new(
|
|
56
|
-
File.expand_path("~/.imap-backup/config.json")
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
RSpec.configure do |config|
|
|
62
|
-
config.include ConfigurationHelpers, type: :aruba
|
|
63
|
-
config.include StoreHelpers, type: :aruba
|
|
64
|
-
config.include BackupDirectoryHelpers, type: :aruba
|
|
65
|
-
|
|
66
|
-
config.before(:suite) do
|
|
67
|
-
FileUtils.rm_rf "./tmp/home"
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
config.before(:example, type: :aruba) do
|
|
71
|
-
set_environment_variable("COVERAGE", "aruba")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
config.after do
|
|
75
|
-
FileUtils.rm_rf "./tmp/home"
|
|
76
|
-
end
|
|
77
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
module BackupDirectoryHelpers
|
|
2
|
-
def message_as_mbox_entry(options)
|
|
3
|
-
from = fixture("connection")[:username]
|
|
4
|
-
subject = options[:subject]
|
|
5
|
-
body = options[:body]
|
|
6
|
-
body_and_headers = <<~BODY
|
|
7
|
-
From: #{from}
|
|
8
|
-
Subject: #{subject}
|
|
9
|
-
|
|
10
|
-
#{body}
|
|
11
|
-
BODY
|
|
12
|
-
|
|
13
|
-
"From #{from}\n#{body_and_headers}\n"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def imap_data(uid_validity, uids)
|
|
17
|
-
{
|
|
18
|
-
version: 2,
|
|
19
|
-
uid_validity: uid_validity,
|
|
20
|
-
uids: uids
|
|
21
|
-
}
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def mbox_content(name)
|
|
25
|
-
File.read(mbox_path(name))
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def mbox_path(name)
|
|
29
|
-
File.join(local_backup_path, "#{name}.mbox")
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def imap_path(name)
|
|
33
|
-
File.join(local_backup_path, "#{name}.imap")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def imap_content(name)
|
|
37
|
-
File.read(imap_path(name))
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def imap_parsed(name)
|
|
41
|
-
JSON.parse(imap_content(name), symbolize_names: true)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
module EmailServerHelpers
|
|
2
|
-
REQUESTED_ATTRIBUTES = ["BODY[]"].freeze
|
|
3
|
-
DEFAULT_EMAIL = "address@example.org".freeze
|
|
4
|
-
|
|
5
|
-
def send_email(folder, options)
|
|
6
|
-
message = message_as_server_message(options)
|
|
7
|
-
imap.append(folder, message, nil, nil)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def message_as_server_message(options)
|
|
11
|
-
from = options[:from] || DEFAULT_EMAIL
|
|
12
|
-
subject = options[:subject]
|
|
13
|
-
body = options[:body]
|
|
14
|
-
|
|
15
|
-
<<~MESSAGE.gsub("\n", "\r\n")
|
|
16
|
-
From: #{from}
|
|
17
|
-
Subject: #{subject}
|
|
18
|
-
|
|
19
|
-
#{body}
|
|
20
|
-
|
|
21
|
-
MESSAGE
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def server_messages(folder)
|
|
25
|
-
server_uids(folder).map do |uid|
|
|
26
|
-
server_fetch_email(folder, uid)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def server_message_to_body(message)
|
|
31
|
-
message["BODY[]"]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def server_fetch_email(folder, uid)
|
|
35
|
-
examine folder
|
|
36
|
-
|
|
37
|
-
fetch_data_items = imap.uid_fetch([uid.to_i], REQUESTED_ATTRIBUTES)
|
|
38
|
-
return nil if fetch_data_items.nil?
|
|
39
|
-
|
|
40
|
-
fetch_data_item = fetch_data_items[0]
|
|
41
|
-
fetch_data_item.attr
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def delete_emails(folder)
|
|
45
|
-
imap.select(folder)
|
|
46
|
-
uids = imap.uid_search(["ALL"]).sort
|
|
47
|
-
imap.store(1..uids.size, "+FLAGS", [:Deleted])
|
|
48
|
-
imap.expunge
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def examine(folder)
|
|
52
|
-
imap.examine(folder)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def server_uids(folder)
|
|
56
|
-
examine(folder)
|
|
57
|
-
imap.uid_search(["ALL"]).sort
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def server_uid_validity(folder)
|
|
61
|
-
examine(folder)
|
|
62
|
-
imap.responses["UIDVALIDITY"][0]
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def server_folders
|
|
66
|
-
imap.list(root, "*")
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def root
|
|
70
|
-
root_info = imap.list("", "")[0]
|
|
71
|
-
root_info.name
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def server_create_folder(folder)
|
|
75
|
-
imap.create(folder)
|
|
76
|
-
imap.disconnect
|
|
77
|
-
@imap = nil
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def server_rename_folder(from, to)
|
|
81
|
-
imap.rename(from, to)
|
|
82
|
-
imap.disconnect
|
|
83
|
-
@imap = nil
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def server_delete_folder(folder)
|
|
87
|
-
imap.delete folder
|
|
88
|
-
imap.disconnect
|
|
89
|
-
rescue StandardError => e
|
|
90
|
-
ensure
|
|
91
|
-
@imap = nil
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def imap
|
|
95
|
-
@imap ||=
|
|
96
|
-
begin
|
|
97
|
-
connection = fixture("connection")
|
|
98
|
-
imap = Net::IMAP.new(
|
|
99
|
-
connection[:server], connection[:connection_options]
|
|
100
|
-
)
|
|
101
|
-
imap.login(connection[:username], connection[:password])
|
|
102
|
-
imap
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
RSpec.configure do |config|
|
|
108
|
-
config.include EmailServerHelpers, type: :aruba
|
|
109
|
-
config.include EmailServerHelpers, type: :feature
|
|
110
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
shared_context "imap-backup connection" do
|
|
2
|
-
let(:local_backup_path) { Dir.mktmpdir(nil, "tmp") }
|
|
3
|
-
let(:default_connection) { fixture("connection") }
|
|
4
|
-
let(:backup_folders) { nil }
|
|
5
|
-
let(:account) do
|
|
6
|
-
Imap::Backup::Account.new(
|
|
7
|
-
default_connection.merge(
|
|
8
|
-
local_path: local_backup_path,
|
|
9
|
-
folders: backup_folders
|
|
10
|
-
)
|
|
11
|
-
)
|
|
12
|
-
end
|
|
13
|
-
let(:connection) { Imap::Backup::Account::Connection.new(account) }
|
|
14
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
shared_context "message-fixtures" do
|
|
2
|
-
let(:uid1) { 123 }
|
|
3
|
-
let(:uid2) { 345 }
|
|
4
|
-
let(:uid3) { 567 }
|
|
5
|
-
let(:uid_iso8859) { 890 }
|
|
6
|
-
let(:msg1) { {uid: uid1, subject: "Test 1", body: "body 1\nHi"} }
|
|
7
|
-
let(:msg2) { {uid: uid2, subject: "Test 2", body: "body 2"} }
|
|
8
|
-
let(:msg3) { {uid: uid3, subject: "Test 3", body: "body 3"} }
|
|
9
|
-
let(:msg_iso8859) do
|
|
10
|
-
{
|
|
11
|
-
uid: uid_iso8859,
|
|
12
|
-
subject: "iso8859 Body",
|
|
13
|
-
body: "Ma, perchè?".encode(Encoding::ISO_8859_1).force_encoding("binary")
|
|
14
|
-
}
|
|
15
|
-
end
|
|
16
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
require "rspec"
|
|
2
|
-
|
|
3
|
-
$LOAD_PATH << File.expand_path("../lib", __dir__)
|
|
4
|
-
|
|
5
|
-
support_glob = File.join(__dir__, "support", "**", "*.rb")
|
|
6
|
-
Dir[support_glob].sort.each { |f| require f }
|
|
7
|
-
|
|
8
|
-
require "simplecov"
|
|
9
|
-
|
|
10
|
-
SimpleCov.command_name "RSpec tests"
|
|
11
|
-
|
|
12
|
-
require "imap/backup"
|
|
13
|
-
require "imap/backup/cli"
|
|
14
|
-
|
|
15
|
-
silence_logging
|
data/spec/support/fixtures.rb
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
require "erb"
|
|
2
|
-
require "yaml"
|
|
3
|
-
|
|
4
|
-
def fixture(name)
|
|
5
|
-
spec_root = File.expand_path("..", File.dirname(__FILE__))
|
|
6
|
-
fixture_path = File.join(spec_root, "fixtures", "#{name}.yml")
|
|
7
|
-
content = File.read(fixture_path)
|
|
8
|
-
template = ERB.new(content)
|
|
9
|
-
yaml = template.result(binding)
|
|
10
|
-
YAML.safe_load(yaml, [Symbol])
|
|
11
|
-
end
|