imap-backup 9.3.2 → 10.0.0
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 +65 -0
- data/lib/imap/backup/account/{connection/backup_folders.rb → backup_folders.rb} +12 -5
- data/lib/imap/backup/account/{connection/client_factory.rb → client_factory.rb} +11 -11
- data/lib/imap/backup/account/folder.rb +8 -14
- data/lib/imap/backup/account/folder_ensurer.rb +24 -0
- data/lib/imap/backup/account/local_only_folder_deleter.rb +26 -0
- data/lib/imap/backup/account/restore.rb +20 -0
- data/lib/imap/backup/account/serialized_folders.rb +41 -0
- data/lib/imap/backup/account.rb +16 -4
- data/lib/imap/backup/cli/backup.rb +6 -7
- data/lib/imap/backup/cli/folder_enumerator.rb +1 -1
- data/lib/imap/backup/cli/helpers.rb +15 -15
- data/lib/imap/backup/cli/local.rb +31 -19
- data/lib/imap/backup/cli/mirror.rb +1 -1
- data/lib/imap/backup/cli/remote.rb +8 -8
- data/lib/imap/backup/cli/restore.rb +10 -14
- data/lib/imap/backup/cli/stats.rb +8 -3
- data/lib/imap/backup/cli/utils.rb +14 -5
- data/lib/imap/backup/cli.rb +0 -9
- data/lib/imap/backup/client/default.rb +28 -5
- data/lib/imap/backup/configuration.rb +8 -2
- data/lib/imap/backup/downloader.rb +4 -1
- data/lib/imap/backup/file_mode.rb +16 -0
- data/lib/imap/backup/mirror.rb +1 -2
- data/lib/imap/backup/serializer/directory.rb +6 -4
- data/lib/imap/backup/serializer/folder_maker.rb +33 -0
- data/lib/imap/backup/serializer/permission_checker.rb +26 -0
- data/lib/imap/backup/serializer.rb +1 -1
- data/lib/imap/backup/setup/connection_tester.rb +1 -7
- data/lib/imap/backup/setup/folder_chooser.rb +9 -9
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +34 -7
- data/lib/imap/backup/uploader.rb +1 -1
- data/lib/imap/backup/version.rb +3 -3
- data/lib/imap/backup.rb +0 -2
- metadata +12 -7
- data/lib/imap/backup/account/connection/folder_names.rb +0 -26
- data/lib/imap/backup/account/connection.rb +0 -136
- data/lib/imap/backup/utils.rb +0 -40
@@ -1,136 +0,0 @@
|
|
1
|
-
require "imap/backup/client/apple_mail"
|
2
|
-
require "imap/backup/client/default"
|
3
|
-
require "imap/backup/account/connection/backup_folders"
|
4
|
-
require "imap/backup/account/connection/client_factory"
|
5
|
-
require "imap/backup/account/connection/folder_names"
|
6
|
-
require "imap/backup/flag_refresher"
|
7
|
-
require "imap/backup/local_only_message_deleter"
|
8
|
-
require "imap/backup/serializer/directory"
|
9
|
-
|
10
|
-
module Imap::Backup
|
11
|
-
class Account; end
|
12
|
-
|
13
|
-
class Account::Connection
|
14
|
-
attr_reader :account
|
15
|
-
|
16
|
-
def initialize(account)
|
17
|
-
@account = account
|
18
|
-
reset
|
19
|
-
end
|
20
|
-
|
21
|
-
def folder_names
|
22
|
-
@folder_names ||= Account::Connection::FolderNames.new(client: client, account: account).run
|
23
|
-
end
|
24
|
-
|
25
|
-
def backup_folders
|
26
|
-
@backup_folders ||=
|
27
|
-
Account::Connection::BackupFolders.new(client: client, account: account).run
|
28
|
-
end
|
29
|
-
|
30
|
-
def namespaces
|
31
|
-
client.namespace
|
32
|
-
end
|
33
|
-
|
34
|
-
def run_backup(refresh: false)
|
35
|
-
Logger.logger.info "Running backup of account: #{account.username}"
|
36
|
-
# start the connection so we get logging messages in the right order
|
37
|
-
client
|
38
|
-
ensure_account_folder
|
39
|
-
if account.mirror_mode
|
40
|
-
# Delete serialized folders that are not to be backed up
|
41
|
-
wanted = backup_folders.map(&:name)
|
42
|
-
local_folders do |serializer, _folder|
|
43
|
-
serializer.delete if !wanted.include?(serializer.folder)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
each_folder do |folder, serializer|
|
47
|
-
begin
|
48
|
-
next if !folder.exist?
|
49
|
-
rescue Encoding::UndefinedConversionError
|
50
|
-
message = "Skipping backup for '#{folder.name}' " \
|
51
|
-
"as it is not UTF-7 encoded correctly"
|
52
|
-
Logger.logger.info message
|
53
|
-
next
|
54
|
-
end
|
55
|
-
|
56
|
-
Logger.logger.debug "[#{folder.name}] running backup"
|
57
|
-
serializer.apply_uid_validity(folder.uid_validity)
|
58
|
-
begin
|
59
|
-
Downloader.new(
|
60
|
-
folder,
|
61
|
-
serializer,
|
62
|
-
multi_fetch_size: account.multi_fetch_size,
|
63
|
-
reset_seen_flags_after_fetch: account.reset_seen_flags_after_fetch
|
64
|
-
).run
|
65
|
-
if account.mirror_mode
|
66
|
-
Logger.logger.info "Mirror mode - Deleting messages only present locally"
|
67
|
-
LocalOnlyMessageDeleter.new(folder, serializer).run
|
68
|
-
end
|
69
|
-
FlagRefresher.new(folder, serializer).run if account.mirror_mode || refresh
|
70
|
-
rescue Net::IMAP::ByeResponseError
|
71
|
-
reconnect
|
72
|
-
retry
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def local_folders
|
78
|
-
return enum_for(:local_folders) if !block_given?
|
79
|
-
|
80
|
-
ensure_account_folder
|
81
|
-
glob = File.join(account.local_path, "**", "*.imap")
|
82
|
-
base = Pathname.new(account.local_path)
|
83
|
-
Pathname.glob(glob) do |path|
|
84
|
-
name = path.relative_path_from(base).to_s[0..-6]
|
85
|
-
serializer = Serializer.new(account.local_path, name)
|
86
|
-
folder = Account::Folder.new(self, name)
|
87
|
-
yield serializer, folder
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def restore
|
92
|
-
local_folders do |serializer, folder|
|
93
|
-
Uploader.new(folder, serializer).run
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def disconnect
|
98
|
-
client.disconnect if @client
|
99
|
-
reset
|
100
|
-
end
|
101
|
-
|
102
|
-
def reconnect
|
103
|
-
disconnect
|
104
|
-
end
|
105
|
-
|
106
|
-
def reset
|
107
|
-
@backup_folders = nil
|
108
|
-
@client = nil
|
109
|
-
@folder_names = nil
|
110
|
-
end
|
111
|
-
|
112
|
-
# TODO: make this private
|
113
|
-
def client
|
114
|
-
@client ||= Account::Connection::ClientFactory.new(account: account).run
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
def each_folder
|
120
|
-
backup_folders.each do |folder|
|
121
|
-
serializer = Serializer.new(account.local_path, folder.name)
|
122
|
-
yield folder, serializer
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def ensure_account_folder
|
127
|
-
raise "The backup path for #{account.username} is not set" if !account.local_path
|
128
|
-
|
129
|
-
Utils.make_folder(
|
130
|
-
File.dirname(account.local_path),
|
131
|
-
File.basename(account.local_path),
|
132
|
-
Serializer::Directory::DIRECTORY_PERMISSIONS
|
133
|
-
)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
data/lib/imap/backup/utils.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
|
3
|
-
module Imap::Backup
|
4
|
-
module Utils
|
5
|
-
def self.check_permissions(filename, limit)
|
6
|
-
actual = mode(filename)
|
7
|
-
return nil if actual.nil?
|
8
|
-
|
9
|
-
mask = ~limit & 0o777
|
10
|
-
return if (actual & mask).zero?
|
11
|
-
|
12
|
-
message = format(
|
13
|
-
"Permissions on '%<filename>s' " \
|
14
|
-
"should be 0%<limit>o, not 0%<actual>o",
|
15
|
-
filename: filename, limit: limit, actual: actual
|
16
|
-
)
|
17
|
-
raise message
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.mode(filename)
|
21
|
-
return nil if !File.exist?(filename)
|
22
|
-
|
23
|
-
stat = File.stat(filename)
|
24
|
-
stat.mode & 0o777
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.make_folder(base_path, path, permissions)
|
28
|
-
parts = path.split("/")
|
29
|
-
return if parts.empty?
|
30
|
-
|
31
|
-
full_path = File.join(base_path, path)
|
32
|
-
FileUtils.mkdir_p full_path
|
33
|
-
path = base_path
|
34
|
-
parts.each do |part|
|
35
|
-
path = File.join(path, part)
|
36
|
-
FileUtils.chmod permissions, path
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|