imap-backup 15.0.2 → 15.0.3.rc1
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/lib/imap/backup/account/backup.rb +11 -5
- data/lib/imap/backup/account/folder.rb +7 -8
- data/lib/imap/backup/account/folder_backup.rb +8 -4
- data/lib/imap/backup/cli/backup.rb +3 -0
- data/lib/imap/backup/client/default.rb +3 -0
- data/lib/imap/backup/downloader.rb +24 -4
- data/lib/imap/backup/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef0c787a6f2a954caddfc9a5c329333781ad650bf1782feb28cc69e74aeba077
|
4
|
+
data.tar.gz: 23387da9df55557ab56dd46bdeef6608f7af4e80434a02c21767d080598583cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7432a214ec8dd20758786550785be876f208f1bc9b76f7f60f75b30abf800b2bc4c9fca655370576fff0dea4675d1a298c4c3e8743449774ae90d914aa635805
|
7
|
+
data.tar.gz: 461488fe00ea29917415845c2fd7a231ffc6f3646638c1ad64c23f74f96acc5c2581f7fb3adc04a3410d5dbec67eb36a417d4b02b31e827ab95870172ab52922
|
@@ -18,27 +18,33 @@ module Imap::Backup
|
|
18
18
|
# Runs the backup
|
19
19
|
# @return [void]
|
20
20
|
def run
|
21
|
-
Logger.logger.info "Running backup of account
|
21
|
+
Logger.logger.info "Running backup of account '#{account.username}'"
|
22
22
|
# start the connection so we get logging messages in the right order
|
23
23
|
account.client.login
|
24
24
|
|
25
|
-
|
26
|
-
Account::LocalOnlyFolderDeleter.new(account: account).run if account.mirror_mode
|
25
|
+
run_pre_backup_tasks
|
27
26
|
backup_folders = Account::BackupFolders.new(
|
28
27
|
client: account.client, account: account
|
29
|
-
)
|
28
|
+
).to_a
|
30
29
|
if backup_folders.none?
|
31
|
-
Logger.logger.warn "
|
30
|
+
Logger.logger.warn "No folders found to backup for account '#{account.username}'"
|
32
31
|
return
|
33
32
|
end
|
33
|
+
Logger.logger.debug "Starting backup of #{backup_folders.count} folders"
|
34
34
|
backup_folders.each do |folder|
|
35
35
|
Account::FolderBackup.new(account: account, folder: folder, refresh: refresh).run
|
36
36
|
end
|
37
|
+
Logger.logger.debug "Backup of account '#{account.username}' complete"
|
37
38
|
end
|
38
39
|
|
39
40
|
private
|
40
41
|
|
41
42
|
attr_reader :account
|
42
43
|
attr_reader :refresh
|
44
|
+
|
45
|
+
def run_pre_backup_tasks
|
46
|
+
Account::FolderEnsurer.new(account: account).run
|
47
|
+
Account::LocalOnlyFolderDeleter.new(account: account).run if account.mirror_mode
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
@@ -31,19 +31,15 @@ module Imap::Backup
|
|
31
31
|
|
32
32
|
# @raise any error that occurs more than 10 times
|
33
33
|
def exist?
|
34
|
-
|
35
|
-
previous_debug = Net::IMAP.debug
|
36
|
-
Imap::Backup::Logger.logger.level = ::Logger::Severity::UNKNOWN
|
37
|
-
Net::IMAP.debug = false
|
34
|
+
Logger.logger.debug "Checking whether folder '#{name}' exists"
|
38
35
|
retry_on_error(errors: EXAMINE_RETRY_CLASSES) do
|
39
36
|
examine
|
40
37
|
end
|
38
|
+
Logger.logger.debug "Folder '#{name}' exists"
|
41
39
|
true
|
42
40
|
rescue FolderNotFound
|
41
|
+
Logger.logger.debug "Folder '#{name}' does not exist"
|
43
42
|
false
|
44
|
-
ensure
|
45
|
-
Imap::Backup::Logger.logger.level = previous_level
|
46
|
-
Net::IMAP.debug = previous_debug
|
47
43
|
end
|
48
44
|
|
49
45
|
# Creates the folder on the server
|
@@ -69,8 +65,11 @@ module Imap::Backup
|
|
69
65
|
# @raise any error that occurs more than 10 times
|
70
66
|
# @return [Array<Integer>] the folders message UIDs
|
71
67
|
def uids
|
68
|
+
Logger.logger.debug "Fetching UIDs for folder '#{name}'"
|
72
69
|
examine
|
73
|
-
client.uid_search(["ALL"]).sort
|
70
|
+
result = client.uid_search(["ALL"]).sort
|
71
|
+
Logger.logger.debug "#{result.count} UIDs found for folder '#{name}'"
|
72
|
+
result
|
74
73
|
rescue FolderNotFound
|
75
74
|
[]
|
76
75
|
rescue NoMethodError
|
@@ -22,11 +22,11 @@ module Imap::Backup
|
|
22
22
|
# @raise [RuntimeError] if the configured download strategy is incorrect
|
23
23
|
# @return [void]
|
24
24
|
def run
|
25
|
+
Logger.logger.debug "Running backup for folder '#{folder.name}'"
|
26
|
+
|
25
27
|
folder_ok = folder_ok?
|
26
28
|
return if !folder_ok
|
27
29
|
|
28
|
-
Logger.logger.debug "[#{folder.name}] running backup"
|
29
|
-
|
30
30
|
serializer.apply_uid_validity(folder.uid_validity)
|
31
31
|
|
32
32
|
serializer.transaction do
|
@@ -36,6 +36,7 @@ module Imap::Backup
|
|
36
36
|
# After the transaction the serializer will have any appended messages
|
37
37
|
# so we can check differences between the server and the local backup
|
38
38
|
LocalOnlyMessageDeleter.new(folder, raw_serializer).run if account.mirror_mode
|
39
|
+
Logger.logger.debug "Backup for folder '#{folder.name}' complete"
|
39
40
|
end
|
40
41
|
|
41
42
|
private
|
@@ -46,10 +47,13 @@ module Imap::Backup
|
|
46
47
|
|
47
48
|
def folder_ok?
|
48
49
|
begin
|
49
|
-
|
50
|
+
if !folder.exist?
|
51
|
+
Logger.logger.info "Skipping backup for folder '#{folder.name}' as it does not exist"
|
52
|
+
return false
|
53
|
+
end
|
50
54
|
rescue Encoding::UndefinedConversionError
|
51
55
|
message = "Skipping backup for '#{folder.name}' " \
|
52
|
-
"as it is not UTF-7 encoded correctly"
|
56
|
+
"as it's name is not UTF-7 encoded correctly"
|
53
57
|
Logger.logger.info message
|
54
58
|
return false
|
55
59
|
end
|
@@ -24,6 +24,7 @@ module Imap::Backup
|
|
24
24
|
# @return [void]
|
25
25
|
no_commands do
|
26
26
|
def run
|
27
|
+
Logger.logger.debug "Loading configuration"
|
27
28
|
config = load_config(**options)
|
28
29
|
exit_code = nil
|
29
30
|
accounts = requested_accounts(config)
|
@@ -31,6 +32,7 @@ module Imap::Backup
|
|
31
32
|
Logger.logger.warn "No matching accounts found to backup"
|
32
33
|
return
|
33
34
|
end
|
35
|
+
Logger.logger.debug "Starting backup of #{accounts.count} accounts"
|
34
36
|
accounts.each do |account|
|
35
37
|
backup = Account::Backup.new(account: account, refresh: refresh)
|
36
38
|
backup.run
|
@@ -43,6 +45,7 @@ module Imap::Backup
|
|
43
45
|
Logger.logger.error message
|
44
46
|
next
|
45
47
|
end
|
48
|
+
Logger.logger.debug "Backup complete"
|
46
49
|
exit(exit_code) if exit_code
|
47
50
|
end
|
48
51
|
end
|
@@ -27,6 +27,7 @@ module Imap::Backup
|
|
27
27
|
# @return [Array<String>] the account folders
|
28
28
|
def list
|
29
29
|
root = provider_root
|
30
|
+
Logger.logger.debug "Listing all account folders"
|
30
31
|
mailbox_lists = imap.list(root, "*")
|
31
32
|
|
32
33
|
return [] if mailbox_lists.nil?
|
@@ -105,7 +106,9 @@ module Imap::Backup
|
|
105
106
|
# in the reference.
|
106
107
|
def provider_root
|
107
108
|
@provider_root ||= begin
|
109
|
+
Logger.logger.debug "Fetching provider root"
|
108
110
|
root_info = imap.list("", "")[0]
|
111
|
+
Logger.logger.debug "Provider root is '#{root_info.name}'"
|
109
112
|
root_info.name
|
110
113
|
end
|
111
114
|
end
|
@@ -19,7 +19,19 @@ module Imap::Backup
|
|
19
19
|
# Runs the downloader
|
20
20
|
# @return [void]
|
21
21
|
def run
|
22
|
-
|
22
|
+
debug("#{serializer_uids.count} already messages already downloaded")
|
23
|
+
debug("#{folder_uids.count} messages on server")
|
24
|
+
local_only_count = (serializer_uids - folder_uids).count
|
25
|
+
if local_only_count.positive?
|
26
|
+
debug("#{local_only_count} downloaded messages no longer on server")
|
27
|
+
end
|
28
|
+
|
29
|
+
if uids.none?
|
30
|
+
debug("no new messages on server — skipping")
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
info("#{uids.count} new messages")
|
23
35
|
|
24
36
|
uids.each_slice(multi_fetch_size).with_index do |block, i|
|
25
37
|
multifetch_failed = download_block(block, i)
|
@@ -62,8 +74,8 @@ module Imap::Backup
|
|
62
74
|
end
|
63
75
|
if uids_and_bodies.nil?
|
64
76
|
if multi_fetch_size > 1
|
65
|
-
|
66
|
-
debug("Multi fetch failed for UIDs #{
|
77
|
+
uid_list = block.join(", ")
|
78
|
+
debug("Multi fetch failed for UIDs #{uid_list}, switching to single fetches")
|
67
79
|
return true
|
68
80
|
else
|
69
81
|
debug("Fetch failed for UID #{block[0]} - skipping")
|
@@ -96,8 +108,16 @@ module Imap::Backup
|
|
96
108
|
error(e)
|
97
109
|
end
|
98
110
|
|
111
|
+
def folder_uids
|
112
|
+
@folder_uids ||= folder.uids
|
113
|
+
end
|
114
|
+
|
115
|
+
def serializer_uids
|
116
|
+
@serializer_uids ||= serializer.uids
|
117
|
+
end
|
118
|
+
|
99
119
|
def uids
|
100
|
-
@uids ||=
|
120
|
+
@uids ||= folder_uids - serializer_uids
|
101
121
|
end
|
102
122
|
|
103
123
|
def debug(message)
|
data/lib/imap/backup/version.rb
CHANGED
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: 15.0.
|
4
|
+
version: 15.0.3.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|