imap-backup 14.4.4 → 14.4.5
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 +67 -137
- data/docs/documentation.md +19 -0
- 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 +2 -0
- data/lib/imap/backup/account/restore.rb +2 -0
- data/lib/imap/backup/account/serialized_folders.rb +5 -1
- data/lib/imap/backup/account.rb +15 -11
- 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 +13 -0
- 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 +6 -0
- 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 +2 -0
- 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 +7 -0
- data/lib/imap/backup/uploader.rb +5 -0
- data/lib/imap/backup/version.rb +6 -1
- metadata +3 -5
- 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: e492fd50201bbf2424231905b4cdb6fe3d44d99fa446c624b851c9ef50eb686f
|
4
|
+
data.tar.gz: e2ed159ec5e92e7d97a685093456491afe94d34e70702d4e7a0449cf150009dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0f4acc27fa79b789c83298af7788c01e9b8c837aa5086d1675e98b7ef80abd7fe1b3decb4b36c3f586126f7d9dc54499358bc05f7e65e0de3cbc29207233188
|
7
|
+
data.tar.gz: e036ad78bff71f98012907444f5eb36c56e01f3a3a8d2f37fbb0b06f5c1850eaddd26a4be86a8581a8f25e322731eac06a25a18853ac4433a2793cbd603b8727
|
data/README.md
CHANGED
@@ -1,201 +1,131 @@
|
|
1
|
+
# imap-backup API Documentation
|
2
|
+
|
1
3
|

|
2
4
|
[][CI Status]
|
3
5
|

|
4
6
|

|
5
7
|
[][GitHub Stars]
|
8
|
+

|
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
|
-

|
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 ~docker
|
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
|
-

|
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
|
+
```
|
@@ -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
|
|
@@ -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
|
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
|
|
data/lib/imap/backup/account.rb
CHANGED
@@ -14,10 +14,9 @@ module Imap::Backup
|
|
14
14
|
# The username of the account (usually the same as the email address)
|
15
15
|
# @return [String]
|
16
16
|
attr_reader :username
|
17
|
-
#
|
17
|
+
# @return [String] password of the Account
|
18
18
|
attr_reader :password
|
19
|
-
#
|
20
|
-
# @return [String]
|
19
|
+
# @return [String] the path where backups will be saved
|
21
20
|
attr_reader :local_path
|
22
21
|
# @overload folders
|
23
22
|
# The list of folders that have been configured for the Account
|
@@ -38,6 +37,7 @@ module Imap::Backup
|
|
38
37
|
attr_reader :folder_blacklist
|
39
38
|
# Should all emails be backed up progressively, or should emails
|
40
39
|
# which are deleted from the server be deleted locally?
|
40
|
+
# @return [Boolean]
|
41
41
|
attr_reader :mirror_mode
|
42
42
|
# The address of the IMAP server
|
43
43
|
# @return [String]
|
@@ -61,8 +61,6 @@ module Imap::Backup
|
|
61
61
|
# mark messages as '\Seen' when accessed).
|
62
62
|
# @return [Boolean]
|
63
63
|
attr_reader :reset_seen_flags_after_fetch
|
64
|
-
# Tracks changes to the Account's attributes
|
65
|
-
attr_reader :changes
|
66
64
|
|
67
65
|
def initialize(options)
|
68
66
|
@username = options[:username]
|
@@ -123,6 +121,7 @@ module Imap::Backup
|
|
123
121
|
end
|
124
122
|
|
125
123
|
# Resets the store of changes, indicating that the current state is the saved state
|
124
|
+
# @return [void]
|
126
125
|
def clear_changes
|
127
126
|
@changes = {}
|
128
127
|
end
|
@@ -134,16 +133,12 @@ module Imap::Backup
|
|
134
133
|
@marked_for_deletion = true
|
135
134
|
end
|
136
135
|
|
137
|
-
#
|
138
|
-
#
|
139
|
-
# @return [Boolean]
|
136
|
+
# @return [Boolean] whether the account has been flagged for deletion during setup
|
140
137
|
def marked_for_deletion?
|
141
138
|
@marked_for_deletion
|
142
139
|
end
|
143
140
|
|
144
|
-
#
|
145
|
-
#
|
146
|
-
# @return [Hash]
|
141
|
+
# @return [Hash] all Account data for serialization
|
147
142
|
def to_h
|
148
143
|
h = {username: @username, password: @password}
|
149
144
|
h[:local_path] = @local_path if @local_path
|
@@ -180,24 +175,30 @@ module Imap::Backup
|
|
180
175
|
update(:local_path, value)
|
181
176
|
end
|
182
177
|
|
178
|
+
# @raise [RuntimeError] if the supplied value is not an Array
|
179
|
+
# @return [void]
|
183
180
|
def folders=(value)
|
184
181
|
raise "folders must be an Array" if !value.is_a?(Array)
|
185
182
|
|
186
183
|
update(:folders, value)
|
187
184
|
end
|
188
185
|
|
186
|
+
# @return [void]
|
189
187
|
def folder_blacklist=(value)
|
190
188
|
update(:folder_blacklist, value)
|
191
189
|
end
|
192
190
|
|
191
|
+
# @return [void]
|
193
192
|
def mirror_mode=(value)
|
194
193
|
update(:mirror_mode, value)
|
195
194
|
end
|
196
195
|
|
196
|
+
# @return [void]
|
197
197
|
def server=(value)
|
198
198
|
update(:server, value)
|
199
199
|
end
|
200
200
|
|
201
|
+
# @return [void]
|
201
202
|
def connection_options=(value)
|
202
203
|
parsed =
|
203
204
|
if value == ""
|
@@ -232,12 +233,15 @@ module Imap::Backup
|
|
232
233
|
update(:multi_fetch_size, parsed)
|
233
234
|
end
|
234
235
|
|
236
|
+
# @return [void]
|
235
237
|
def reset_seen_flags_after_fetch=(value)
|
236
238
|
update(:reset_seen_flags_after_fetch, value)
|
237
239
|
end
|
238
240
|
|
239
241
|
private
|
240
242
|
|
243
|
+
attr_reader :changes
|
244
|
+
|
241
245
|
def update(field, value)
|
242
246
|
key = :"@#{field}"
|
243
247
|
if changes[field]
|
@@ -10,6 +10,7 @@ module Imap; end
|
|
10
10
|
module Imap::Backup
|
11
11
|
class CLI < Thor; end
|
12
12
|
|
13
|
+
# Runs backups of configured accounts
|
13
14
|
class CLI::Backup < Thor
|
14
15
|
include Thor::Actions
|
15
16
|
include CLI::Helpers
|
@@ -19,6 +20,8 @@ module Imap::Backup
|
|
19
20
|
@options = options
|
20
21
|
end
|
21
22
|
|
23
|
+
# @!method run
|
24
|
+
# @return [void]
|
22
25
|
no_commands do
|
23
26
|
def run
|
24
27
|
config = load_config(**options)
|
@@ -9,6 +9,7 @@ module Imap; end
|
|
9
9
|
module Imap::Backup
|
10
10
|
class CLI < Thor; end
|
11
11
|
|
12
|
+
# Implements a folder enumerator for backed-up accounts
|
12
13
|
class CLI::FolderEnumerator
|
13
14
|
def initialize(
|
14
15
|
destination:,
|
@@ -26,6 +27,11 @@ module Imap::Backup
|
|
26
27
|
@source_prefix = source_prefix
|
27
28
|
end
|
28
29
|
|
30
|
+
# Enumerates backed-up folders
|
31
|
+
# When called without a block, returns an Enumerator
|
32
|
+
# @yieldparam serializer [Serializer] the folder's serializer
|
33
|
+
# @yieldparam folder [Account::Folder] the online folder
|
34
|
+
# @return [Enumerator, void]
|
29
35
|
def each
|
30
36
|
return enum_for(:each) if !block_given?
|
31
37
|
|