imap-backup 14.4.4 → 14.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +67 -137
- data/docs/documentation.md +19 -0
- data/imap-backup.gemspec +1 -1
- data/lib/imap/backup/account/backup.rb +2 -0
- data/lib/imap/backup/account/backup_folders.rb +7 -1
- data/lib/imap/backup/account/client_factory.rb +1 -0
- data/lib/imap/backup/account/folder.rb +26 -0
- data/lib/imap/backup/account/folder_backup.rb +4 -1
- data/lib/imap/backup/account/folder_ensurer.rb +3 -0
- data/lib/imap/backup/account/local_only_folder_deleter.rb +3 -1
- data/lib/imap/backup/account/restore.rb +2 -0
- data/lib/imap/backup/account/serialized_folders.rb +31 -1
- data/lib/imap/backup/account.rb +34 -18
- data/lib/imap/backup/cli/backup.rb +3 -0
- data/lib/imap/backup/cli/folder_enumerator.rb +6 -0
- data/lib/imap/backup/cli/helpers.rb +13 -0
- data/lib/imap/backup/cli/local/check.rb +3 -0
- data/lib/imap/backup/cli/local.rb +14 -1
- data/lib/imap/backup/cli/remote.rb +7 -0
- data/lib/imap/backup/cli/restore.rb +4 -0
- data/lib/imap/backup/cli/setup.rb +3 -0
- data/lib/imap/backup/cli/single/backup.rb +3 -0
- data/lib/imap/backup/cli/single.rb +4 -0
- data/lib/imap/backup/cli/stats.rb +3 -0
- data/lib/imap/backup/cli/transfer.rb +8 -0
- data/lib/imap/backup/cli/utils.rb +7 -1
- data/lib/imap/backup/cli.rb +8 -0
- data/lib/imap/backup/client/apple_mail.rb +2 -0
- data/lib/imap/backup/client/automatic_login_wrapper.rb +9 -1
- data/lib/imap/backup/client/default.rb +15 -4
- data/lib/imap/backup/configuration.rb +13 -0
- data/lib/imap/backup/configuration_not_found.rb +1 -0
- data/lib/imap/backup/downloader.rb +4 -0
- data/lib/imap/backup/email/mboxrd/message.rb +14 -0
- data/lib/imap/backup/email/provider/apple_mail.rb +2 -0
- data/lib/imap/backup/email/provider/base.rb +3 -3
- data/lib/imap/backup/email/provider/fastmail.rb +2 -0
- data/lib/imap/backup/email/provider/gmail.rb +2 -0
- data/lib/imap/backup/email/provider/purelymail.rb +2 -0
- data/lib/imap/backup/email/provider/unknown.rb +2 -6
- data/lib/imap/backup/email/provider.rb +5 -0
- data/lib/imap/backup/file_mode.rb +2 -0
- data/lib/imap/backup/flag_refresher.rb +4 -0
- data/lib/imap/backup/local_only_message_deleter.rb +2 -0
- data/lib/imap/backup/logger.rb +18 -0
- data/lib/imap/backup/migrator.rb +3 -0
- data/lib/imap/backup/mirror/map.rb +21 -0
- data/lib/imap/backup/mirror.rb +8 -0
- data/lib/imap/backup/naming.rb +10 -1
- data/lib/imap/backup/retry_on_error.rb +9 -0
- data/lib/imap/backup/serializer/appender.rb +9 -0
- data/lib/imap/backup/serializer/delayed_metadata_serializer.rb +4 -0
- data/lib/imap/backup/serializer/folder_maker.rb +1 -0
- data/lib/imap/backup/serializer/imap.rb +38 -2
- data/lib/imap/backup/serializer/integrity_checker.rb +1 -0
- data/lib/imap/backup/serializer/mbox.rb +26 -0
- data/lib/imap/backup/serializer/message.rb +13 -0
- data/lib/imap/backup/serializer/message_enumerator.rb +10 -2
- data/lib/imap/backup/serializer/permission_checker.rb +6 -0
- data/lib/imap/backup/serializer/transaction.rb +18 -0
- data/lib/imap/backup/serializer/unused_name_finder.rb +4 -0
- data/lib/imap/backup/serializer/version2_migrator.rb +4 -0
- data/lib/imap/backup/serializer.rb +56 -2
- data/lib/imap/backup/setup/account/header.rb +6 -0
- data/lib/imap/backup/setup/account.rb +6 -0
- data/lib/imap/backup/setup/asker.rb +16 -0
- data/lib/imap/backup/setup/backup_path.rb +6 -0
- data/lib/imap/backup/setup/connection_tester.rb +5 -0
- data/lib/imap/backup/setup/email_changer.rb +6 -0
- data/lib/imap/backup/setup/folder_chooser.rb +4 -0
- data/lib/imap/backup/setup/global_options/download_strategy_chooser.rb +4 -0
- data/lib/imap/backup/setup/global_options.rb +4 -0
- data/lib/imap/backup/setup/helpers.rb +3 -0
- data/lib/imap/backup/setup.rb +5 -0
- data/lib/imap/backup/text/sanitizer.rb +9 -0
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +8 -1
- data/lib/imap/backup/uploader.rb +5 -0
- data/lib/imap/backup/version.rb +7 -2
- metadata +11 -13
- data/docs/api.md +0 -20
- data/docs/development.md +0 -110
- data/docs/migrate-server-keep-address.md +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee294a8f4d7c0af90c725939b3f4cd7826ac521194460af3446e7cf5378629f4
|
4
|
+
data.tar.gz: c67cac7ddfb2448a9cb22b642b53be02b157959d51f3677bc37ec891da2471c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1b2f9affe114ea775b4f7f7d4d2db4349e03b3ccb842885b3423c28c2b84ff6e8872b224a520654e0cef8eb353e9f0ea268e9d0dcda2666b07709f5071a0db7
|
7
|
+
data.tar.gz: 2feab585634685c45606d6e4668e52190af3fd193cf3c8468ea5b306a8834257c2944ca4c668ee5e1f9423ebfb3cf605de9d6c8052a983d57f3fe0df07d105c8
|
data/README.md
CHANGED
@@ -1,201 +1,131 @@
|
|
1
|
+
# imap-backup API Documentation
|
2
|
+
|
1
3
|
![Version](https://img.shields.io/gem/v/imap-backup?label=Version&logo=rubygems)
|
2
4
|
[![Build Status](https://github.com/joeyates/imap-backup/actions/workflows/main.yml/badge.svg)][CI Status]
|
3
5
|
![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/joeyates/b54fe758bfb405c04bef72dad293d707/raw/coverage.json)
|
4
6
|
![License](https://img.shields.io/github/license/joeyates/imap-backup?color=brightgreen&label=License)
|
5
7
|
[![Stars](https://img.shields.io/github/stars/joeyates/imap-backup?style=social)][GitHub Stars]
|
8
|
+
![Activity](https://img.shields.io/github/last-commit/joeyates/imap-backup/main)
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
Backup, restore and migrate email accounts.
|
10
|
-
|
11
|
-
# Quick Start
|
12
|
-
|
13
|
-
```sh
|
14
|
-
brew install imap-backup # for macOS
|
15
|
-
gem install imap-backup --no-document # for Linux
|
16
|
-
imap-backup setup
|
17
|
-
imap-backup
|
18
|
-
```
|
19
|
-
|
20
|
-
# Modes
|
21
|
-
|
22
|
-
There are two types of backups:
|
23
|
-
|
24
|
-
* Keep all (the default) - progressively saves a local copy of all emails,
|
25
|
-
* Mirror - adds and deletes emails from the local copy to keep it up to date with the account.
|
10
|
+
[CI Status]: https://github.com/joeyates/imap-backup/actions/workflows/main.yml
|
11
|
+
[GitHub Stars]: https://github.com/joeyates/imap-backup/stargazers "GitHub Stars"
|
26
12
|
|
27
|
-
|
13
|
+
This is the developer documentation for imap-backup's **code**.
|
28
14
|
|
29
|
-
|
30
|
-
* Mirror - make a destination account match the local copy. This action can be repeated.
|
31
|
-
* Restore - push the local copy back to the original account.
|
15
|
+
Usage documentation is on [GitHub](https://github.com/joeyates/imap-backup).
|
32
16
|
|
33
|
-
|
17
|
+
You can get an overview of the program's structure from the
|
18
|
+
{file:ARCHITECTURE.md ARCHITECTURE} file.
|
34
19
|
|
35
|
-
|
20
|
+
The {file:CHANGELOG.md CHANGELOG} has a history of the changes to the program.
|
36
21
|
|
37
|
-
|
22
|
+
# Design Goals
|
38
23
|
|
39
|
-
|
40
|
-
|
24
|
+
* Secure - use a local configuration file protected by permissions
|
25
|
+
* Restartable - calculate start point based on already downloaded messages
|
26
|
+
* Standalone - do not rely on an email client or MTA
|
41
27
|
|
42
|
-
|
43
|
-
we'll use `./my-data` here.
|
28
|
+
# Repository
|
44
29
|
|
45
|
-
|
30
|
+
After cloning the repo, run the following command to get
|
31
|
+
better `git blame` output:
|
46
32
|
|
47
33
|
```sh
|
48
|
-
|
49
|
-
imap-backup single backup \
|
50
|
-
--email me@example.com --password mysecret --server imap.example.com \
|
51
|
-
--path /data/me_example.com
|
34
|
+
git config --local blame.ignoreRevsFile .git-blame-ignore-revs
|
52
35
|
```
|
53
36
|
|
54
|
-
|
37
|
+
# Testing
|
55
38
|
|
56
|
-
|
39
|
+
## Feature Specs
|
57
40
|
|
58
|
-
|
59
|
-
|
41
|
+
Specs under `specs/features` are integration specs.
|
42
|
+
Some of these specs run against two local IMAP servers
|
43
|
+
controlled by Podman (or Docker) Compose.
|
60
44
|
|
61
|
-
|
45
|
+
Start them before running the test suite
|
62
46
|
|
63
47
|
```sh
|
64
|
-
|
65
|
-
imap-backup setup -c /config/imap-backup.json
|
48
|
+
$ podman-compose -f dev/compose.yml up -d
|
66
49
|
```
|
67
50
|
|
68
|
-
|
51
|
+
or, with Docker
|
69
52
|
|
70
53
|
```sh
|
71
|
-
docker
|
72
|
-
imap-backup backup -c /config/imap-backup.json
|
54
|
+
$ docker-compose -f dev/compose.yml up -d
|
73
55
|
```
|
74
56
|
|
75
|
-
|
76
|
-
## Homebrew (macOS)
|
77
|
-
|
78
|
-
![Homebrew installs](https://img.shields.io/homebrew/installs/dm/imap-backup?label=Homebrew%20installs)
|
79
|
-
|
80
|
-
If you have [Homebrew](https://brew.sh/), do this:
|
57
|
+
Then, run all specs
|
81
58
|
|
82
59
|
```sh
|
83
|
-
|
60
|
+
$ rspec
|
84
61
|
```
|
85
62
|
|
86
|
-
|
63
|
+
To exclude container-based tests
|
87
64
|
|
88
65
|
```sh
|
89
|
-
|
66
|
+
$ rspec --tag ~container
|
90
67
|
```
|
91
68
|
|
92
|
-
|
93
|
-
|
94
|
-
## From Source Code
|
95
|
-
|
96
|
-
If you want to use imap-backup directly from the source code, see [here](docs/installation/source.md).
|
97
|
-
|
98
|
-
# Setup
|
99
|
-
|
100
|
-
Normally you will want to backup a number of email accounts.
|
101
|
-
Doing so requires the creation of a config file.
|
102
|
-
|
103
|
-
You do this via a menu-driven command line program:
|
104
|
-
|
105
|
-
Run:
|
69
|
+
To run **just** the feature specs
|
106
70
|
|
107
71
|
```sh
|
108
|
-
|
72
|
+
rspec spec/features/**/*_spec.rb
|
109
73
|
```
|
110
74
|
|
111
|
-
|
112
|
-
you can pass all the necessary parameters directly to the `single backup` command
|
113
|
-
(see the [`single backup`](docs/commands/single-backup.md) docs).
|
114
|
-
|
115
|
-
## GMail
|
116
|
-
|
117
|
-
To use imap-backup with GMail, Office 365 and other services that require
|
118
|
-
OAuth2 authentication, you can use [email-oauth2-proxy](https://github.com/simonrob/email-oauth2-proxy).
|
119
|
-
See [this blog post about using imap-backup with email-oauth2-proxy](https://joeyates.info/posts/back-up-gmail-accounts-with-imap-backup-using-email-oauth2-proxy/).
|
75
|
+
## Full Test Run
|
120
76
|
|
121
|
-
|
122
|
-
|
123
|
-
Manually, from the command line:
|
77
|
+
The full test run includes RSpec specs **and** Rubocop checks
|
124
78
|
|
125
79
|
```sh
|
126
|
-
|
80
|
+
rake
|
127
81
|
```
|
128
82
|
|
129
|
-
|
83
|
+
# Test Debugging
|
130
84
|
|
131
|
-
|
132
|
-
|
85
|
+
The feature specs are run 'out of process' via the Aruba gem.
|
86
|
+
In order to see debugging output from the process,
|
87
|
+
use `last_command_started.output`.
|
133
88
|
|
134
|
-
#
|
89
|
+
# Older Rubies
|
135
90
|
|
136
|
-
|
137
|
-
|
138
|
-
* [`local check`](docs/commands/local-check.md)
|
139
|
-
* [`local folders`](docs/commands/local-folders.md)
|
140
|
-
* [`local list`](docs/commands/local-list.md)
|
141
|
-
* [`local show`](docs/commands/local-show.md)
|
142
|
-
* [`migrate`](docs/commands/migrate.md)
|
143
|
-
* [`mirror`](docs/commands/mirror.md)
|
144
|
-
* [`remote folders`](docs/commands/remote-folders.md)
|
145
|
-
* [`restore`](docs/commands/restore.md)
|
146
|
-
* [`setup`](docs/commands/setup.md)
|
147
|
-
* [`single backup`](docs/commands/single-backup.md)
|
148
|
-
* [`utils export-to-thunderbird`](docs/commands/utils-export-to-thunderbird.md)
|
149
|
-
* [`utils ignore-history`](docs/commands/utils-ignore-history.md)
|
91
|
+
A Containerfile is available to allow testing with all available Ruby versions,
|
92
|
+
see the README in the `dev` directory.
|
150
93
|
|
151
|
-
|
94
|
+
# Performance Specs
|
152
95
|
|
153
96
|
```sh
|
154
|
-
|
97
|
+
PERFORMANCE=1 rspec --order=defined
|
155
98
|
```
|
156
99
|
|
157
|
-
|
158
|
-
|
159
|
-
```sh
|
160
|
-
imap-backup help COMMAND
|
161
|
-
```
|
100
|
+
Beware: the performance spec (just backup for now) takes a very
|
101
|
+
long time to run, approximately 24 hours!
|
162
102
|
|
163
|
-
#
|
103
|
+
# Access Docker imap server
|
164
104
|
|
165
|
-
|
166
|
-
|
105
|
+
```ruby
|
106
|
+
require "net/imap"
|
107
|
+
require_relative "spec/features/support/30_email_server_helpers"
|
167
108
|
|
168
|
-
|
109
|
+
include EmailServerHelpers
|
169
110
|
|
170
|
-
|
171
|
-
* Account setting "Multi-fetch size".
|
111
|
+
test_connection = test_server_connection_parameters
|
172
112
|
|
173
|
-
|
113
|
+
test_imap = Net::IMAP.new(test_connection[:server], test_connection[:connection_options])
|
114
|
+
test_imap.login(test_connection[:username], test_connection[:password])
|
174
115
|
|
175
|
-
#
|
116
|
+
message = "From: #{test_connection[:username]}\nSubject: Some Subject\n\nHello!\n"
|
117
|
+
response = test_imap.append("INBOX", message, nil, nil)
|
176
118
|
|
177
|
-
|
119
|
+
test_imap.examine("INBOX")
|
120
|
+
uids = test_imap.uid_search(["ALL"]).sort
|
178
121
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
# Development
|
183
|
-
|
184
|
-
![Activity](https://img.shields.io/github/last-commit/joeyates/imap-backup/main)
|
185
|
-
|
186
|
-
See the [Development documentation](./docs/development.md) for notes
|
187
|
-
on development and testing.
|
188
|
-
|
189
|
-
See [the CHANGELOG](./CHANGELOG.md) for a list of changes that have been
|
190
|
-
made in each release.
|
122
|
+
fetch_data_items = test_imap.uid_fetch(uids, ["BODY[]"])
|
123
|
+
```
|
191
124
|
|
192
|
-
|
193
|
-
* [Code Documentation]
|
194
|
-
* [Rubygem]
|
195
|
-
* [CI Status]
|
125
|
+
# Contributing
|
196
126
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
127
|
+
1. Fork it
|
128
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
129
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
130
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
131
|
+
5. Create new Pull Request
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Documentation
|
2
|
+
|
3
|
+
This project uses [yard](https://yardoc.org/) to generate its documentation.
|
4
|
+
|
5
|
+
# Development
|
6
|
+
|
7
|
+
Run an autoreloading document viewer
|
8
|
+
|
9
|
+
```
|
10
|
+
yard server --reload
|
11
|
+
```
|
12
|
+
|
13
|
+
# Coverage
|
14
|
+
|
15
|
+
See what's not documented
|
16
|
+
|
17
|
+
```
|
18
|
+
yard stats --list-undoc
|
19
|
+
```
|
data/imap-backup.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_runtime_dependency "os"
|
28
28
|
gem.add_runtime_dependency "rake"
|
29
29
|
gem.add_runtime_dependency "thor", "~> 1.1"
|
30
|
-
gem.add_runtime_dependency "thunderbird", "
|
30
|
+
gem.add_runtime_dependency "thunderbird", "0.3.0"
|
31
31
|
|
32
32
|
gem.metadata = {
|
33
33
|
"rubygems_mfa_required" => "true"
|
@@ -5,7 +5,7 @@ module Imap; end
|
|
5
5
|
module Imap::Backup
|
6
6
|
class Account; end
|
7
7
|
|
8
|
-
#
|
8
|
+
# Enumerates over the account folders that are to be backed up
|
9
9
|
class Account::BackupFolders
|
10
10
|
include Enumerable
|
11
11
|
|
@@ -14,6 +14,9 @@ module Imap::Backup
|
|
14
14
|
@account = account
|
15
15
|
end
|
16
16
|
|
17
|
+
# Runs the enumeration
|
18
|
+
# @yieldparam folder [Account::Folder] the online folder
|
19
|
+
# @return [void]
|
17
20
|
def each(&block)
|
18
21
|
return enum_for(:each) if !block
|
19
22
|
|
@@ -39,6 +42,9 @@ module Imap::Backup
|
|
39
42
|
names.each { |name| block.call(Account::Folder.new(client, name)) }
|
40
43
|
end
|
41
44
|
|
45
|
+
# Runs a map operation over the folders
|
46
|
+
# @yieldparam folder [Account::Folder] the online folder
|
47
|
+
# @return The results of the map operation
|
42
48
|
def map(&block)
|
43
49
|
each.map do |folder|
|
44
50
|
block.call(folder)
|
@@ -12,12 +12,15 @@ module Imap::Backup
|
|
12
12
|
|
13
13
|
# Handles access to a folder on an IMAP server
|
14
14
|
class Account::Folder
|
15
|
+
# An error that is thrown if a requestd folder does not exist
|
15
16
|
class FolderNotFound < StandardError; end
|
16
17
|
|
17
18
|
extend Forwardable
|
18
19
|
include RetryOnError
|
19
20
|
|
21
|
+
# @return [Client::Default]
|
20
22
|
attr_reader :client
|
23
|
+
# @return [String] the name of the folder
|
21
24
|
attr_reader :name
|
22
25
|
|
23
26
|
def initialize(client, name)
|
@@ -26,6 +29,7 @@ module Imap::Backup
|
|
26
29
|
@uid_validity = nil
|
27
30
|
end
|
28
31
|
|
32
|
+
# @raise any error that occurs more than 10 times
|
29
33
|
def exist?
|
30
34
|
previous_level = Imap::Backup::Logger.logger.level
|
31
35
|
previous_debug = Net::IMAP.debug
|
@@ -42,6 +46,8 @@ module Imap::Backup
|
|
42
46
|
Net::IMAP.debug = previous_debug
|
43
47
|
end
|
44
48
|
|
49
|
+
# Creates the folder on the server
|
50
|
+
# @return [void]
|
45
51
|
def create
|
46
52
|
return if exist?
|
47
53
|
|
@@ -50,6 +56,8 @@ module Imap::Backup
|
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
59
|
+
# @raise any error that occurs more than 10 times
|
60
|
+
# @return [Integer] the folder's UID validity
|
53
61
|
def uid_validity
|
54
62
|
@uid_validity ||=
|
55
63
|
begin
|
@@ -58,6 +66,8 @@ module Imap::Backup
|
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
69
|
+
# @raise any error that occurs more than 10 times
|
70
|
+
# @return [Array<Integer>] the folders message UIDs
|
61
71
|
def uids
|
62
72
|
examine
|
63
73
|
client.uid_search(["ALL"]).sort
|
@@ -75,6 +85,8 @@ module Imap::Backup
|
|
75
85
|
[]
|
76
86
|
end
|
77
87
|
|
88
|
+
# @raise any error that occurs more than 10 times
|
89
|
+
# @return [Array<Hash>, nil] the requested messages
|
78
90
|
def fetch_multi(uids, attr = [BODY_ATTRIBUTE, "FLAGS"])
|
79
91
|
examine
|
80
92
|
fetch_data_items =
|
@@ -96,6 +108,8 @@ module Imap::Backup
|
|
96
108
|
nil
|
97
109
|
end
|
98
110
|
|
111
|
+
# Uploads a message
|
112
|
+
# @return [void]
|
99
113
|
def append(message)
|
100
114
|
body = message.imap_body
|
101
115
|
date = message.date&.to_time
|
@@ -106,17 +120,23 @@ module Imap::Backup
|
|
106
120
|
end
|
107
121
|
end
|
108
122
|
|
123
|
+
# Deletes multiple messages
|
124
|
+
# @return [void]
|
109
125
|
def delete_multi(uids)
|
110
126
|
add_flags(uids, [:Deleted])
|
111
127
|
client.expunge
|
112
128
|
end
|
113
129
|
|
130
|
+
# Sets one or more flags on a group of messages
|
131
|
+
# @return [void]
|
114
132
|
def set_flags(uids, flags)
|
115
133
|
client.select(utf7_encoded_name)
|
116
134
|
flags.reject! { |f| f == :Recent }
|
117
135
|
client.uid_store(uids, "FLAGS", flags)
|
118
136
|
end
|
119
137
|
|
138
|
+
# Adds one or more flags to a group of messages
|
139
|
+
# @return [void]
|
120
140
|
def add_flags(uids, flags)
|
121
141
|
# Use read-write access, via `select`
|
122
142
|
client.select(utf7_encoded_name)
|
@@ -124,11 +144,15 @@ module Imap::Backup
|
|
124
144
|
client.uid_store(uids, "+FLAGS", flags)
|
125
145
|
end
|
126
146
|
|
147
|
+
# Removes one or more flags from a group of messages
|
148
|
+
# @return [void]
|
127
149
|
def remove_flags(uids, flags)
|
128
150
|
client.select(utf7_encoded_name)
|
129
151
|
client.uid_store(uids, "-FLAGS", flags)
|
130
152
|
end
|
131
153
|
|
154
|
+
# Deletes all messages from the folder
|
155
|
+
# @return [void]
|
132
156
|
def clear
|
133
157
|
existing = uids
|
134
158
|
return if existing.empty?
|
@@ -137,6 +161,8 @@ module Imap::Backup
|
|
137
161
|
client.expunge
|
138
162
|
end
|
139
163
|
|
164
|
+
# @raise any error that occurs more than 10 times
|
165
|
+
# @return [Array<Integer>] the UIDs of messages with the 'UNSEEN' flag
|
140
166
|
def unseen(uids)
|
141
167
|
messages = uids.map(&:to_s).join(",")
|
142
168
|
examine
|
@@ -10,7 +10,7 @@ module Imap; end
|
|
10
10
|
module Imap::Backup
|
11
11
|
class Account; end
|
12
12
|
|
13
|
-
#
|
13
|
+
# Implements backup for a single folder
|
14
14
|
class Account::FolderBackup
|
15
15
|
def initialize(account:, folder:, refresh: false)
|
16
16
|
@account = account
|
@@ -18,6 +18,9 @@ module Imap::Backup
|
|
18
18
|
@refresh = refresh
|
19
19
|
end
|
20
20
|
|
21
|
+
# Runs the backup
|
22
|
+
# @raise [RuntimeError] if the configured download strategy is incorrect
|
23
|
+
# @return [void]
|
21
24
|
def run
|
22
25
|
folder_ok = folder_ok?
|
23
26
|
return if !folder_ok
|
@@ -12,6 +12,9 @@ module Imap::Backup
|
|
12
12
|
@account = account
|
13
13
|
end
|
14
14
|
|
15
|
+
# Creates the account's base directory and sets its permissions
|
16
|
+
# @raise [RuntimeError] is the account's backup path is not set
|
17
|
+
# @return [void]
|
15
18
|
def run
|
16
19
|
raise "The backup path for #{account.username} is not set" if !account.local_path
|
17
20
|
|
@@ -14,13 +14,15 @@ module Imap::Backup
|
|
14
14
|
@account = account
|
15
15
|
end
|
16
16
|
|
17
|
+
# Runs the deletion operation
|
18
|
+
# @return [void]
|
17
19
|
def run
|
18
20
|
backup_folders = Account::BackupFolders.new(
|
19
21
|
client: account.client, account: account
|
20
22
|
)
|
21
23
|
wanted = backup_folders.map(&:name)
|
22
24
|
serialized_folders = Account::SerializedFolders.new(account: account)
|
23
|
-
serialized_folders.
|
25
|
+
serialized_folders.each_key do |serializer|
|
24
26
|
serializer.delete if !wanted.include?(serializer.folder)
|
25
27
|
end
|
26
28
|
end
|
@@ -9,7 +9,7 @@ module Imap; end
|
|
9
9
|
module Imap::Backup
|
10
10
|
class Account; end
|
11
11
|
|
12
|
-
# Enumerates over
|
12
|
+
# Enumerates over an account's backed-up folders
|
13
13
|
class Account::SerializedFolders
|
14
14
|
include Enumerable
|
15
15
|
|
@@ -17,6 +17,10 @@ module Imap::Backup
|
|
17
17
|
@account = account
|
18
18
|
end
|
19
19
|
|
20
|
+
# Runs the enumeration over local serializers and remote folders
|
21
|
+
# @yieldparam serializer [Serializer] the folder's serializer
|
22
|
+
# @yieldparam folder [Account::Folder] the online folder
|
23
|
+
# @return [void]
|
20
24
|
def each(&block)
|
21
25
|
return enum_for(:each) if !block
|
22
26
|
|
@@ -28,6 +32,32 @@ module Imap::Backup
|
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
35
|
+
# Runs the enumeration over each local serializer
|
36
|
+
# @yieldparam serializer [Serializer] the folder's serializer
|
37
|
+
# @return [void]
|
38
|
+
def each_key(&block)
|
39
|
+
return enum_for(:each_key) if !block
|
40
|
+
|
41
|
+
glob.each do |path|
|
42
|
+
name = path.relative_path_from(base).to_s[0..-6]
|
43
|
+
serializer = Serializer.new(account.local_path, name)
|
44
|
+
block.call(serializer)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Runs the enumeration over each remote folder
|
49
|
+
# @yieldparam folder [Account::Folder] the online folder
|
50
|
+
# @return [void]
|
51
|
+
def each_value(&block)
|
52
|
+
return enum_for(:each_value) if !block
|
53
|
+
|
54
|
+
glob.each do |path|
|
55
|
+
name = path.relative_path_from(base).to_s[0..-6]
|
56
|
+
folder = Account::Folder.new(account.client, name)
|
57
|
+
block.call(folder)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
31
61
|
private
|
32
62
|
|
33
63
|
attr_reader :account
|