imap-backup 5.0.0 → 6.0.0.rc2

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -7
  3. data/bin/imap-backup +4 -0
  4. data/docs/development.md +10 -4
  5. data/imap-backup.gemspec +2 -7
  6. data/lib/cli_coverage.rb +18 -0
  7. data/lib/imap/backup/account/connection.rb +7 -11
  8. data/lib/imap/backup/account/folder.rb +0 -16
  9. data/lib/imap/backup/account.rb +31 -11
  10. data/lib/imap/backup/cli/folders.rb +3 -3
  11. data/lib/imap/backup/cli/migrate.rb +3 -3
  12. data/lib/imap/backup/cli/restore.rb +20 -4
  13. data/lib/imap/backup/cli/utils.rb +2 -2
  14. data/lib/imap/backup/cli.rb +6 -7
  15. data/lib/imap/backup/configuration.rb +1 -11
  16. data/lib/imap/backup/downloader.rb +13 -9
  17. data/lib/imap/backup/serializer/directory.rb +37 -0
  18. data/lib/imap/backup/serializer/imap.rb +120 -0
  19. data/lib/imap/backup/serializer/mbox.rb +23 -94
  20. data/lib/imap/backup/serializer/mbox_enumerator.rb +2 -0
  21. data/lib/imap/backup/serializer.rb +180 -3
  22. data/lib/imap/backup/setup/account.rb +52 -29
  23. data/lib/imap/backup/setup/helpers.rb +1 -1
  24. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +1 -1
  25. data/lib/imap/backup/version.rb +2 -2
  26. data/lib/imap/backup.rb +0 -1
  27. data/spec/features/backup_spec.rb +22 -29
  28. data/spec/features/restore_spec.rb +8 -6
  29. data/spec/features/support/aruba.rb +12 -3
  30. data/spec/features/support/backup_directory.rb +0 -4
  31. data/spec/features/support/email_server.rb +0 -1
  32. data/spec/spec_helper.rb +4 -9
  33. data/spec/unit/imap/backup/account/connection_spec.rb +36 -8
  34. data/spec/unit/imap/backup/account/folder_spec.rb +18 -16
  35. data/spec/unit/imap/backup/account_spec.rb +246 -0
  36. data/spec/unit/imap/backup/cli/accounts_spec.rb +12 -1
  37. data/spec/unit/imap/backup/cli/backup_spec.rb +19 -0
  38. data/spec/unit/imap/backup/cli/folders_spec.rb +39 -0
  39. data/spec/unit/imap/backup/cli/local_spec.rb +26 -7
  40. data/spec/unit/imap/backup/cli/migrate_spec.rb +80 -0
  41. data/spec/unit/imap/backup/cli/restore_spec.rb +67 -0
  42. data/spec/unit/imap/backup/cli/setup_spec.rb +17 -0
  43. data/spec/unit/imap/backup/cli/utils_spec.rb +68 -5
  44. data/spec/unit/imap/backup/cli_spec.rb +93 -0
  45. data/spec/unit/imap/backup/client/apple_mail_spec.rb +9 -0
  46. data/spec/unit/imap/backup/configuration_spec.rb +2 -2
  47. data/spec/unit/imap/backup/downloader_spec.rb +60 -8
  48. data/spec/unit/imap/backup/logger_spec.rb +1 -1
  49. data/spec/unit/imap/backup/migrator_spec.rb +1 -1
  50. data/spec/unit/imap/backup/sanitizer_spec.rb +42 -0
  51. data/spec/unit/imap/backup/serializer/directory_spec.rb +37 -0
  52. data/spec/unit/imap/backup/serializer/imap_spec.rb +218 -0
  53. data/spec/unit/imap/backup/serializer/mbox_spec.rb +62 -183
  54. data/spec/unit/imap/backup/serializer_spec.rb +296 -0
  55. data/spec/unit/imap/backup/setup/account_spec.rb +120 -25
  56. data/spec/unit/imap/backup/setup/helpers_spec.rb +15 -0
  57. data/spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb +116 -0
  58. data/spec/unit/imap/backup/uploader_spec.rb +1 -1
  59. data/spec/unit/retry_on_error_spec.rb +34 -0
  60. metadata +44 -37
  61. data/lib/imap/backup/serializer/mbox_store.rb +0 -217
  62. data/lib/thunderbird/install.rb +0 -16
  63. data/lib/thunderbird/local_folder.rb +0 -65
  64. data/lib/thunderbird/profile.rb +0 -30
  65. data/lib/thunderbird/profiles.rb +0 -71
  66. data/lib/thunderbird/subdirectory.rb +0 -93
  67. data/lib/thunderbird/subdirectory_placeholder.rb +0 -21
  68. data/lib/thunderbird.rb +0 -14
  69. data/spec/gather_rspec_coverage.rb +0 -1
  70. data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +0 -329
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: 5.0.0
4
+ version: 6.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-06 00:00:00.000000000 Z
11
+ date: 2022-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -81,13 +81,13 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.1'
83
83
  - !ruby/object:Gem::Dependency
84
- name: aruba
84
+ name: thunderbird
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: 0.0.0
90
- type: :development
90
+ type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
@@ -95,19 +95,19 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.0.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: codeclimate-test-reporter
98
+ name: aruba
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 0.4.8
103
+ version: 0.0.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: 0.4.8
110
+ version: 0.0.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: pry-byebug
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: 3.0.0
139
- - !ruby/object:Gem::Dependency
140
- name: rspec_junit_formatter
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: rubocop-rspec
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -193,6 +179,7 @@ files:
193
179
  - docs/restore.md
194
180
  - docs/setup.md
195
181
  - imap-backup.gemspec
182
+ - lib/cli_coverage.rb
196
183
  - lib/email/mboxrd/message.rb
197
184
  - lib/email/provider.rb
198
185
  - lib/email/provider/apple_mail.rb
@@ -224,9 +211,10 @@ files:
224
211
  - lib/imap/backup/migrator.rb
225
212
  - lib/imap/backup/sanitizer.rb
226
213
  - lib/imap/backup/serializer.rb
214
+ - lib/imap/backup/serializer/directory.rb
215
+ - lib/imap/backup/serializer/imap.rb
227
216
  - lib/imap/backup/serializer/mbox.rb
228
217
  - lib/imap/backup/serializer/mbox_enumerator.rb
229
- - lib/imap/backup/serializer/mbox_store.rb
230
218
  - lib/imap/backup/setup.rb
231
219
  - lib/imap/backup/setup/account.rb
232
220
  - lib/imap/backup/setup/asker.rb
@@ -238,13 +226,6 @@ files:
238
226
  - lib/imap/backup/utils.rb
239
227
  - lib/imap/backup/version.rb
240
228
  - lib/retry_on_error.rb
241
- - lib/thunderbird.rb
242
- - lib/thunderbird/install.rb
243
- - lib/thunderbird/local_folder.rb
244
- - lib/thunderbird/profile.rb
245
- - lib/thunderbird/profiles.rb
246
- - lib/thunderbird/subdirectory.rb
247
- - lib/thunderbird/subdirectory_placeholder.rb
248
229
  - spec/features/backup_spec.rb
249
230
  - spec/features/configuration/minimal_configuration.rb
250
231
  - spec/features/configuration/missing_configuration.rb
@@ -264,7 +245,6 @@ files:
264
245
  - spec/features/support/shared/connection_context.rb
265
246
  - spec/features/support/shared/message_fixtures.rb
266
247
  - spec/fixtures/connection.yml
267
- - spec/gather_rspec_coverage.rb
268
248
  - spec/spec_helper.rb
269
249
  - spec/support/fixtures.rb
270
250
  - spec/support/higline_test_helpers.rb
@@ -277,25 +257,39 @@ files:
277
257
  - spec/unit/email/provider_spec.rb
278
258
  - spec/unit/imap/backup/account/connection_spec.rb
279
259
  - spec/unit/imap/backup/account/folder_spec.rb
260
+ - spec/unit/imap/backup/account_spec.rb
280
261
  - spec/unit/imap/backup/cli/accounts_spec.rb
262
+ - spec/unit/imap/backup/cli/backup_spec.rb
263
+ - spec/unit/imap/backup/cli/folders_spec.rb
281
264
  - spec/unit/imap/backup/cli/helpers_spec.rb
282
265
  - spec/unit/imap/backup/cli/local_spec.rb
266
+ - spec/unit/imap/backup/cli/migrate_spec.rb
267
+ - spec/unit/imap/backup/cli/restore_spec.rb
268
+ - spec/unit/imap/backup/cli/setup_spec.rb
283
269
  - spec/unit/imap/backup/cli/utils_spec.rb
270
+ - spec/unit/imap/backup/cli_spec.rb
271
+ - spec/unit/imap/backup/client/apple_mail_spec.rb
284
272
  - spec/unit/imap/backup/client/default_spec.rb
285
273
  - spec/unit/imap/backup/configuration_spec.rb
286
274
  - spec/unit/imap/backup/downloader_spec.rb
287
275
  - spec/unit/imap/backup/logger_spec.rb
288
276
  - spec/unit/imap/backup/migrator_spec.rb
277
+ - spec/unit/imap/backup/sanitizer_spec.rb
278
+ - spec/unit/imap/backup/serializer/directory_spec.rb
279
+ - spec/unit/imap/backup/serializer/imap_spec.rb
289
280
  - spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb
290
281
  - spec/unit/imap/backup/serializer/mbox_spec.rb
291
- - spec/unit/imap/backup/serializer/mbox_store_spec.rb
282
+ - spec/unit/imap/backup/serializer_spec.rb
292
283
  - spec/unit/imap/backup/setup/account_spec.rb
293
284
  - spec/unit/imap/backup/setup/asker_spec.rb
294
285
  - spec/unit/imap/backup/setup/connection_tester_spec.rb
295
286
  - spec/unit/imap/backup/setup/folder_chooser_spec.rb
287
+ - spec/unit/imap/backup/setup/helpers_spec.rb
296
288
  - spec/unit/imap/backup/setup_spec.rb
289
+ - spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb
297
290
  - spec/unit/imap/backup/uploader_spec.rb
298
291
  - spec/unit/imap/backup/utils_spec.rb
292
+ - spec/unit/retry_on_error_spec.rb
299
293
  homepage: https://github.com/joeyates/imap-backup
300
294
  licenses:
301
295
  - MIT
@@ -311,9 +305,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
311
305
  version: '2.5'
312
306
  required_rubygems_version: !ruby/object:Gem::Requirement
313
307
  requirements:
314
- - - ">="
308
+ - - ">"
315
309
  - !ruby/object:Gem::Version
316
- version: '0'
310
+ version: 1.3.1
317
311
  requirements: []
318
312
  rubygems_version: 3.1.6
319
313
  signing_key:
@@ -321,18 +315,27 @@ specification_version: 4
321
315
  summary: Backup GMail (or other IMAP) accounts to disk
322
316
  test_files:
323
317
  - spec/spec_helper.rb
318
+ - spec/unit/imap/backup/account_spec.rb
319
+ - spec/unit/imap/backup/serializer/imap_spec.rb
320
+ - spec/unit/imap/backup/serializer/directory_spec.rb
324
321
  - spec/unit/imap/backup/serializer/mbox_spec.rb
325
- - spec/unit/imap/backup/serializer/mbox_store_spec.rb
326
322
  - spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb
323
+ - spec/unit/imap/backup/cli_spec.rb
327
324
  - spec/unit/imap/backup/setup_spec.rb
328
325
  - spec/unit/imap/backup/logger_spec.rb
329
326
  - spec/unit/imap/backup/configuration_spec.rb
330
327
  - spec/unit/imap/backup/setup/account_spec.rb
331
328
  - spec/unit/imap/backup/setup/connection_tester_spec.rb
332
329
  - spec/unit/imap/backup/setup/asker_spec.rb
330
+ - spec/unit/imap/backup/setup/helpers_spec.rb
333
331
  - spec/unit/imap/backup/setup/folder_chooser_spec.rb
332
+ - spec/unit/imap/backup/cli/folders_spec.rb
333
+ - spec/unit/imap/backup/cli/setup_spec.rb
334
+ - spec/unit/imap/backup/cli/backup_spec.rb
335
+ - spec/unit/imap/backup/cli/restore_spec.rb
334
336
  - spec/unit/imap/backup/cli/helpers_spec.rb
335
337
  - spec/unit/imap/backup/cli/accounts_spec.rb
338
+ - spec/unit/imap/backup/cli/migrate_spec.rb
336
339
  - spec/unit/imap/backup/cli/utils_spec.rb
337
340
  - spec/unit/imap/backup/cli/local_spec.rb
338
341
  - spec/unit/imap/backup/downloader_spec.rb
@@ -341,7 +344,12 @@ test_files:
341
344
  - spec/unit/imap/backup/account/folder_spec.rb
342
345
  - spec/unit/imap/backup/account/connection_spec.rb
343
346
  - spec/unit/imap/backup/utils_spec.rb
347
+ - spec/unit/imap/backup/serializer_spec.rb
344
348
  - spec/unit/imap/backup/client/default_spec.rb
349
+ - spec/unit/imap/backup/client/apple_mail_spec.rb
350
+ - spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb
351
+ - spec/unit/imap/backup/sanitizer_spec.rb
352
+ - spec/unit/retry_on_error_spec.rb
345
353
  - spec/unit/email/mboxrd/message_spec.rb
346
354
  - spec/unit/email/provider/gmail_spec.rb
347
355
  - spec/unit/email/provider/apple_mail_spec.rb
@@ -370,4 +378,3 @@ test_files:
370
378
  - spec/support/silence_logging.rb
371
379
  - spec/support/higline_test_helpers.rb
372
380
  - spec/fixtures/connection.yml
373
- - spec/gather_rspec_coverage.rb
@@ -1,217 +0,0 @@
1
- require "json"
2
-
3
- require "email/mboxrd/message"
4
- require "imap/backup/serializer/mbox_enumerator"
5
-
6
- module Imap::Backup
7
- class Serializer::MboxStore
8
- CURRENT_VERSION = 2
9
-
10
- attr_reader :folder
11
- attr_reader :path
12
- attr_reader :loaded
13
-
14
- def initialize(path, folder)
15
- @path = path
16
- @folder = folder
17
- @loaded = false
18
- @uids = nil
19
- @uid_validity = nil
20
- end
21
-
22
- def exist?
23
- mbox_exist? && imap_exist?
24
- end
25
-
26
- def uid_validity
27
- do_load if !loaded
28
- @uid_validity
29
- end
30
-
31
- def uid_validity=(value)
32
- do_load if !loaded
33
- @uid_validity = value
34
- @uids ||= []
35
- write_imap_file
36
- end
37
-
38
- def uids
39
- do_load if !loaded
40
- @uids || []
41
- end
42
-
43
- def add(uid, body)
44
- do_load if !loaded
45
- raise "Can't add messages without uid_validity" if !uid_validity
46
-
47
- uid = uid.to_i
48
- if uids.include?(uid)
49
- Imap::Backup::Logger.logger.debug(
50
- "[#{folder}] message #{uid} already downloaded - skipping"
51
- )
52
- return
53
- end
54
-
55
- mboxrd_message = Email::Mboxrd::Message.new(body)
56
- mbox = nil
57
- begin
58
- mbox = File.open(mbox_pathname, "ab")
59
- mbox.write mboxrd_message.to_serialized
60
- @uids << uid
61
- write_imap_file
62
- rescue StandardError => e
63
- message = <<-ERROR.gsub(/^\s*/m, "")
64
- [#{folder}] failed to save message #{uid}:
65
- #{body}. #{e}:
66
- #{e.backtrace.join("\n")}"
67
- ERROR
68
- Imap::Backup::Logger.logger.warn message
69
- ensure
70
- mbox&.close
71
- end
72
- end
73
-
74
- def load(uid_maybe_string)
75
- do_load if !loaded
76
- uid = uid_maybe_string.to_i
77
- message_index = uids.find_index(uid)
78
- return nil if message_index.nil?
79
-
80
- load_nth(message_index)
81
- end
82
-
83
- def each_message(required_uids)
84
- return enum_for(:each_message, required_uids) if !block_given?
85
-
86
- indexes = required_uids.each.with_object({}) do |uid_maybe_string, acc|
87
- uid = uid_maybe_string.to_i
88
- index = uids.find_index(uid)
89
- acc[index] = uid if index
90
- end
91
- enumerator = Serializer::MboxEnumerator.new(mbox_pathname)
92
- enumerator.each.with_index do |raw, i|
93
- uid = indexes[i]
94
- next if !uid
95
-
96
- yield uid, Email::Mboxrd::Message.from_serialized(raw)
97
- end
98
- end
99
-
100
- def update_uid(old, new)
101
- index = uids.find_index(old.to_i)
102
- return if index.nil?
103
-
104
- uids[index] = new.to_i
105
- write_imap_file
106
- end
107
-
108
- def reset
109
- @uids = nil
110
- @uid_validity = nil
111
- @loaded = false
112
- delete_files
113
- write_blank_mbox_file
114
- end
115
-
116
- def rename(new_name)
117
- new_mbox_pathname = absolute_path("#{new_name}.mbox")
118
- new_imap_pathname = absolute_path("#{new_name}.imap")
119
- File.rename(mbox_pathname, new_mbox_pathname)
120
- File.rename(imap_pathname, new_imap_pathname)
121
- @folder = new_name
122
- end
123
-
124
- def mbox_pathname
125
- absolute_path("#{folder}.mbox")
126
- end
127
-
128
- def imap_pathname
129
- absolute_path("#{folder}.imap")
130
- end
131
-
132
- private
133
-
134
- def do_load
135
- data = imap_data
136
- if data
137
- @uids = data[:uids].map(&:to_i)
138
- @uid_validity = data[:uid_validity]
139
- @loaded = true
140
- else
141
- reset
142
- end
143
- end
144
-
145
- def imap_data
146
- return nil if !imap_ok?
147
-
148
- imap_data = nil
149
-
150
- begin
151
- imap_data = JSON.parse(File.read(imap_pathname), symbolize_names: true)
152
- rescue JSON::ParserError
153
- return nil
154
- end
155
-
156
- return nil if !imap_data.key?(:uids)
157
- return nil if !imap_data[:uids].is_a?(Array)
158
-
159
- imap_data
160
- end
161
-
162
- def imap_ok?
163
- return false if !exist?
164
- return false if !imap_looks_like_json?
165
-
166
- true
167
- end
168
-
169
- def load_nth(index)
170
- enumerator = Serializer::MboxEnumerator.new(mbox_pathname)
171
- enumerator.each.with_index do |raw, i|
172
- next if i != index
173
-
174
- return Email::Mboxrd::Message.from_serialized(raw)
175
- end
176
- nil
177
- end
178
-
179
- def imap_looks_like_json?
180
- return false if !imap_exist?
181
-
182
- content = File.read(imap_pathname)
183
- content.start_with?("{")
184
- end
185
-
186
- def write_imap_file
187
- imap_data = {
188
- version: CURRENT_VERSION,
189
- uid_validity: @uid_validity,
190
- uids: @uids
191
- }
192
- content = imap_data.to_json
193
- File.open(imap_pathname, "w") { |f| f.write content }
194
- end
195
-
196
- def write_blank_mbox_file
197
- File.open(mbox_pathname, "w") { |f| f.write "" }
198
- end
199
-
200
- def delete_files
201
- File.unlink(imap_pathname) if imap_exist?
202
- File.unlink(mbox_pathname) if mbox_exist?
203
- end
204
-
205
- def mbox_exist?
206
- File.exist?(mbox_pathname)
207
- end
208
-
209
- def imap_exist?
210
- File.exist?(imap_pathname)
211
- end
212
-
213
- def absolute_path(relative_path)
214
- File.join(path, relative_path)
215
- end
216
- end
217
- end
@@ -1,16 +0,0 @@
1
- require "thunderbird/profiles"
2
-
3
- class Thunderbird::Install
4
- attr_reader :title
5
- attr_reader :entries
6
-
7
- # entries are lines from profile.ini
8
- def initialize(title, entries)
9
- @title = title
10
- @entries = entries
11
- end
12
-
13
- def default
14
- Thunderbird::Profiles.new.profile_for_path(entries[:Default])
15
- end
16
- end
@@ -1,65 +0,0 @@
1
- require "thunderbird/profile"
2
- require "thunderbird/subdirectory"
3
-
4
- # A local folder is a file containing emails
5
- class Thunderbird::LocalFolder
6
- attr_reader :path
7
- attr_reader :profile
8
-
9
- def initialize(profile, path)
10
- @profile = profile
11
- @path = path
12
- end
13
-
14
- def set_up
15
- return if path_elements.empty?
16
-
17
- return true if !in_subdirectory?
18
-
19
- subdirectory.set_up
20
- end
21
-
22
- def full_path
23
- if in_subdirectory?
24
- File.join(subdirectory.full_path, folder_name)
25
- else
26
- folder_name
27
- end
28
- end
29
-
30
- def exists?
31
- File.exist?(full_path)
32
- end
33
-
34
- def msf_path
35
- "#{path}.msf"
36
- end
37
-
38
- def msf_exists?
39
- File.exist?(msf_path)
40
- end
41
-
42
- private
43
-
44
- def in_subdirectory?
45
- path_elements.count > 1
46
- end
47
-
48
- def subdirectory
49
- return nil if !in_subdirectory?
50
-
51
- Thunderbird::Subdirectory.new(profile, subdirectory_path)
52
- end
53
-
54
- def path_elements
55
- path.split(File::SEPARATOR)
56
- end
57
-
58
- def subdirectory_path
59
- File.join(path_elements[0..-2])
60
- end
61
-
62
- def folder_name
63
- path_elements[-1]
64
- end
65
- end
@@ -1,30 +0,0 @@
1
- require "thunderbird"
2
-
3
- class Thunderbird::Profile
4
- attr_reader :title
5
- attr_reader :entries
6
-
7
- # entries are lines from profile.ini
8
- def initialize(title, entries)
9
- @title = title
10
- @entries = entries
11
- end
12
-
13
- def root
14
- if relative?
15
- File.join(Thunderbird.new.data_path, entries[:Path])
16
- else
17
- entries[:Path]
18
- end
19
- end
20
-
21
- def local_folders_path
22
- File.join(root, "Mail", "Local Folders")
23
- end
24
-
25
- private
26
-
27
- def relative?
28
- entries[:IsRelative] == "1"
29
- end
30
- end
@@ -1,71 +0,0 @@
1
- require "thunderbird"
2
- require "thunderbird/install"
3
- require "thunderbird/profile"
4
-
5
- # http://kb.mozillazine.org/Profiles.ini_file
6
- class Thunderbird::Profiles
7
- def profile_for_path(path)
8
- title, entries = blocks.find { |_name, entries| entries[:Path] == path }
9
-
10
- Thunderbird::Profile.new(title, entries) if title
11
- end
12
-
13
- def profile(name)
14
- title, entries = blocks.find { |_name, entries| entries[:Name] == name }
15
-
16
- Thunderbird::Profile.new(title, entries) if title
17
- end
18
-
19
- def installs
20
- @installs ||= begin
21
- pairs = blocks.filter { |name, _entries| name.start_with?("Install") }
22
- pairs.map { |title, entries| Thunderbird::Install.new(title, entries) }
23
- end
24
- end
25
-
26
- private
27
-
28
- # Parse profiles.ini.
29
- # Blocks start with a title, e.g. '[Abc]'
30
- # and are followed by a number of lines
31
- def blocks
32
- @blocks ||= begin
33
- blocks = {}
34
- File.open(profiles_ini_path, "rb") do |f|
35
- title = nil
36
- entries = nil
37
-
38
- loop do
39
- line = f.gets
40
- if !line
41
- blocks[title] = entries if title
42
- break
43
- end
44
-
45
- line.chomp!
46
-
47
- # Is this line the start of a new block
48
- match = line.match(/\A\[([A-Za-z0-9]+)\]\z/)
49
- if match
50
- # Store what we got before this title as a new block
51
- blocks[title] = entries if title
52
-
53
- # Start a new block
54
- title = match[1]
55
- entries = {}
56
- elsif line != ""
57
- # Collect entries until we get to the next title
58
- key, value = line.split("=")
59
- entries[key.to_sym] = value
60
- end
61
- end
62
- end
63
-
64
- blocks
65
- end
66
- end
67
-
68
- def profiles_ini_path
69
- File.join(Thunderbird.new.data_path, "profiles.ini")
70
- end
71
- end
@@ -1,93 +0,0 @@
1
- require "thunderbird/subdirectory_placeholder"
2
-
3
- class Thunderbird::Subdirectory
4
- # `path` is the UI path, it doesn't have the '.sbd' extensions
5
- # that are present in the real, file system path
6
- attr_reader :path
7
- attr_reader :profile
8
-
9
- def initialize(profile, path)
10
- @profile = profile
11
- @path = path
12
- end
13
-
14
- def set_up
15
- raise "Cannot create a subdirectory without a path" if !sub_directory?
16
-
17
- if sub_sub_directory?
18
- parent_ok = parent.set_up
19
- return false if !parent_ok
20
- end
21
-
22
- ok = check
23
- return false if !ok
24
-
25
- FileUtils.mkdir_p full_path
26
- placeholder.touch
27
-
28
- true
29
- end
30
-
31
- # subdirectory relative path is 'Foo.sbd/Bar.sbd/Baz.sbd'
32
- def full_path
33
- relative_path = File.join(subdirectories)
34
- File.join(profile.local_folders_path, relative_path)
35
- end
36
-
37
- private
38
-
39
- def sub_directory?
40
- path_elements.any?
41
- end
42
-
43
- def sub_sub_directory?
44
- path_elements.count > 1
45
- end
46
-
47
- def parent
48
- return nil if !sub_sub_directory?
49
-
50
- self.class.new(profile, File.join(path_elements[0..-2]))
51
- end
52
-
53
- # placeholder relative path is 'Foo.sbd/Bar.sbd/Baz'
54
- def placeholder
55
- @placeholder = begin
56
- relative_path = File.join(subdirectories[0..-2], path_elements[-1])
57
- path = File.join(profile.local_folders_path, relative_path)
58
- Thunderbird::SubdirectoryPlaceholder.new(path)
59
- end
60
- end
61
-
62
- def path_elements
63
- path.split(File::SEPARATOR)
64
- end
65
-
66
- def exists?
67
- File.exist?(full_path)
68
- end
69
-
70
- def directory?
71
- File.directory?(full_path)
72
- end
73
-
74
- def subdirectories
75
- path_elements.map { |p| "#{p}.sbd" }
76
- end
77
-
78
- def check
79
- case
80
- when exists? && !placeholder.exists?
81
- Kernel.puts "Can't set up folder '#{full_path}': '#{full_path}' exists, but '#{placeholder.path}' is missing"
82
- false
83
- when placeholder.exists? && !placeholder.regular?
84
- Kernel.puts "Can't set up folder '#{full_path}': '#{placeholder.path}' exists, but it is not a regular file"
85
- false
86
- when exists? && !directory?
87
- Kernel.puts "Can't set up folder '#{full_path}': '#{full_path}' exists, but it is not a directory"
88
- false
89
- else
90
- true
91
- end
92
- end
93
- end