imap-backup 9.3.2 → 10.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/imap/backup/account/backup.rb +65 -0
  3. data/lib/imap/backup/account/{connection/backup_folders.rb → backup_folders.rb} +12 -5
  4. data/lib/imap/backup/account/{connection/client_factory.rb → client_factory.rb} +11 -11
  5. data/lib/imap/backup/account/folder.rb +8 -14
  6. data/lib/imap/backup/account/folder_ensurer.rb +24 -0
  7. data/lib/imap/backup/account/local_only_folder_deleter.rb +26 -0
  8. data/lib/imap/backup/account/restore.rb +20 -0
  9. data/lib/imap/backup/account/serialized_folders.rb +41 -0
  10. data/lib/imap/backup/account.rb +16 -4
  11. data/lib/imap/backup/cli/backup.rb +6 -7
  12. data/lib/imap/backup/cli/folder_enumerator.rb +1 -1
  13. data/lib/imap/backup/cli/helpers.rb +15 -15
  14. data/lib/imap/backup/cli/local.rb +31 -19
  15. data/lib/imap/backup/cli/mirror.rb +1 -1
  16. data/lib/imap/backup/cli/remote.rb +8 -8
  17. data/lib/imap/backup/cli/restore.rb +10 -14
  18. data/lib/imap/backup/cli/stats.rb +8 -3
  19. data/lib/imap/backup/cli/utils.rb +14 -5
  20. data/lib/imap/backup/cli.rb +0 -9
  21. data/lib/imap/backup/client/default.rb +28 -5
  22. data/lib/imap/backup/configuration.rb +8 -2
  23. data/lib/imap/backup/downloader.rb +4 -1
  24. data/lib/imap/backup/file_mode.rb +16 -0
  25. data/lib/imap/backup/mirror.rb +1 -2
  26. data/lib/imap/backup/serializer/directory.rb +6 -4
  27. data/lib/imap/backup/serializer/folder_maker.rb +33 -0
  28. data/lib/imap/backup/serializer/permission_checker.rb +26 -0
  29. data/lib/imap/backup/serializer.rb +1 -1
  30. data/lib/imap/backup/setup/connection_tester.rb +1 -7
  31. data/lib/imap/backup/setup/folder_chooser.rb +9 -9
  32. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +34 -7
  33. data/lib/imap/backup/uploader.rb +1 -1
  34. data/lib/imap/backup/version.rb +3 -3
  35. data/lib/imap/backup.rb +0 -2
  36. metadata +12 -7
  37. data/lib/imap/backup/account/connection/folder_names.rb +0 -26
  38. data/lib/imap/backup/account/connection.rb +0 -136
  39. 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
@@ -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