imap-backup 4.0.2 → 4.0.3

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -1
  3. data/docs/development.md +1 -2
  4. data/imap-backup.gemspec +1 -0
  5. data/lib/email/provider/apple_mail.rb +7 -0
  6. data/lib/email/provider/default.rb +12 -0
  7. data/lib/email/provider/fastmail.rb +7 -0
  8. data/lib/email/provider/gmail.rb +7 -0
  9. data/lib/email/provider.rb +16 -26
  10. data/lib/imap/backup/account/connection.rb +19 -29
  11. data/lib/imap/backup/account/folder.rb +9 -10
  12. data/lib/imap/backup/cli/helpers.rb +1 -0
  13. data/lib/imap/backup/cli/local.rb +4 -1
  14. data/lib/imap/backup/cli/utils.rb +16 -5
  15. data/lib/imap/backup/client/apple_mail.rb +11 -0
  16. data/lib/imap/backup/client/default.rb +51 -0
  17. data/lib/imap/backup/configuration/account.rb +3 -1
  18. data/lib/imap/backup/configuration/connection_tester.rb +1 -1
  19. data/lib/imap/backup/configuration/store.rb +10 -5
  20. data/lib/imap/backup/downloader.rb +3 -4
  21. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +12 -25
  22. data/lib/imap/backup/version.rb +1 -1
  23. data/lib/thunderbird/install.rb +16 -0
  24. data/lib/thunderbird/local_folder.rb +33 -65
  25. data/lib/thunderbird/profiles.rb +18 -10
  26. data/lib/thunderbird/subdirectory.rb +96 -0
  27. data/lib/thunderbird/{local_folder_placeholder.rb → subdirectory_placeholder.rb} +4 -4
  28. data/lib/thunderbird.rb +10 -2
  29. data/spec/features/restore_spec.rb +1 -1
  30. data/spec/features/support/email_server.rb +2 -2
  31. data/spec/unit/email/provider/apple_mail_spec.rb +7 -0
  32. data/spec/unit/email/provider/default_spec.rb +17 -0
  33. data/spec/unit/email/provider/fastmail_spec.rb +7 -0
  34. data/spec/unit/email/provider/gmail_spec.rb +7 -0
  35. data/spec/unit/email/provider_spec.rb +12 -25
  36. data/spec/unit/imap/backup/account/connection_spec.rb +26 -51
  37. data/spec/unit/imap/backup/account/folder_spec.rb +22 -22
  38. data/spec/unit/imap/backup/cli/utils_spec.rb +2 -2
  39. data/spec/unit/imap/backup/client/default_spec.rb +22 -0
  40. data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +3 -3
  41. data/spec/unit/imap/backup/configuration/store_spec.rb +25 -12
  42. data/spec/unit/imap/backup/downloader_spec.rb +1 -2
  43. metadata +57 -26
  44. data/lib/thunderbird/mailbox.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14c0bd789a2532461bbfbe92dd3bb2466228fe0d14b676c308f766a5c62941cf
4
- data.tar.gz: 06203ea6c126b17b26f784f2f91f3dd72d1bfd431fe100428931d624de85c53e
3
+ metadata.gz: 139120639e68abb1555421c5c63f28a6ede222f95767f86a52e3b8d548ceaf99
4
+ data.tar.gz: ef9ef718e09d4b812085c3e72f374f922ae760d318322fa2237d742aec826e37
5
5
  SHA512:
6
- metadata.gz: a4de838badaaf992ae6ff46d590bb782810f4dae83aeeb9bd1495525bddfc396341374e18c51bec2e71a1cf66135335f2e21bdd6632ced9f64bc81f93f4eafe1
7
- data.tar.gz: 20cc1c12289c753a3814205fd7cf125a2b234b567301a37f88da65b7f86b26a66274209fc8e2218975877f6568df3d991f1db03f76fe4262c8415adc3a59d6e6
6
+ metadata.gz: 3d7447ca37c7f2134ea7254fe90640ce3f6db6599a287b5b07796236d614e887cd05614045a57d8fb2b729d9e2da357f4cb42b083303dbfe1c3dc4b92b3b3dbd
7
+ data.tar.gz: 77ea7b8ba366c8416a6cef3c707b8942d4f3261f138c603b98128d2f43079880e12f241c8672a2f301c035204ccd68bc8a6bbbc6dce8d5d9590ecbd4c490844c
data/README.md CHANGED
@@ -134,7 +134,15 @@ in the configuration file.
134
134
 
135
135
  The directory ~/.imap-backup, the configuration file and all backup
136
136
  directories have their access permissions set to only allow access
137
- by your user.
137
+ by your user. This is not done on Windows - see below.
138
+
139
+ ## Windows
140
+
141
+ Due to the complexity of managing permissions on Windows,
142
+ directory and file access permissions are not set explicity.
143
+
144
+ A pull request that implements permissions management on Windows
145
+ would be welcome!
138
146
 
139
147
  # Run Backup
140
148
 
data/docs/development.md CHANGED
@@ -41,8 +41,7 @@ response = imap.append("INBOX", message, nil, nil)
41
41
  imap.examine("INBOX")
42
42
  uids = imap.uid_search(["ALL"]).sort
43
43
 
44
- REQUESTED_ATTRIBUTES = ["RFC822", "FLAGS", "INTERNALDATE"].freeze
45
- fetch_data_items = imap.uid_fetch(uids, REQUESTED_ATTRIBUTES)
44
+ fetch_data_items = imap.uid_fetch(uids, ["BODY[]"])
46
45
  ```
47
46
 
48
47
  # Contributing
data/imap-backup.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |gem|
24
24
 
25
25
  gem.add_runtime_dependency "highline"
26
26
  gem.add_runtime_dependency "mail"
27
+ gem.add_runtime_dependency "os"
27
28
  gem.add_runtime_dependency "rake"
28
29
  gem.add_runtime_dependency "thor", "~> 1.1"
29
30
 
@@ -0,0 +1,7 @@
1
+ require "email/provider/default"
2
+
3
+ class Email::Provider::AppleMail < Email::Provider::Default
4
+ def host
5
+ "imap.mail.me.com"
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Email; end
2
+ class Email::Provider; end
3
+
4
+ class Email::Provider::Default
5
+ # We don't know how to guess the IMAP server
6
+ def host
7
+ end
8
+
9
+ def options
10
+ {port: 993, ssl: {ssl_version: :TLSv1_2}}
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ require "email/provider/default"
2
+
3
+ class Email::Provider::Fastmail < Email::Provider::Default
4
+ def host
5
+ "imap.fastmail.com"
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "email/provider/default"
2
+
3
+ class Email::Provider::GMail < Email::Provider::Default
4
+ def host
5
+ "imap.gmail.com"
6
+ end
7
+ end
@@ -1,37 +1,27 @@
1
+ require "email/provider/default"
2
+ require "email/provider/apple_mail"
3
+ require "email/provider/fastmail"
4
+ require "email/provider/gmail"
5
+
1
6
  module Email; end
2
7
 
3
8
  class Email::Provider
4
- GMAIL_IMAP_SERVER = "imap.gmail.com".freeze
5
-
6
9
  def self.for_address(address)
7
10
  case
8
11
  when address.end_with?("@fastmail.com")
9
- new(:fastmail)
10
- when address.end_with?("@gmail.com")
11
- new(:gmail)
12
+ Email::Provider::Fastmail.new
12
13
  when address.end_with?("@fastmail.fm")
13
- new(:fastmail)
14
+ Email::Provider::Fastmail.new
15
+ when address.end_with?("@gmail.com")
16
+ Email::Provider::GMail.new
17
+ when address.end_with?("@icloud.com")
18
+ Email::Provider::AppleMail.new
19
+ when address.end_with?("@mac.com")
20
+ Email::Provider::AppleMail.new
21
+ when address.end_with?("@me.com")
22
+ Email::Provider::AppleMail.new
14
23
  else
15
- new(:default)
16
- end
17
- end
18
-
19
- attr_reader :provider
20
-
21
- def initialize(provider)
22
- @provider = provider
23
- end
24
-
25
- def options
26
- {port: 993, ssl: {ssl_version: :TLSv1_2}}
27
- end
28
-
29
- def host
30
- case provider
31
- when :gmail
32
- GMAIL_IMAP_SERVER
33
- when :fastmail
34
- "imap.fastmail.com"
24
+ Email::Provider::Default.new
35
25
  end
36
26
  end
37
27
  end
@@ -1,4 +1,5 @@
1
- require "net/imap"
1
+ require "imap/backup/client/apple_mail"
2
+ require "imap/backup/client/default"
2
3
 
3
4
  require "retry_on_error"
4
5
 
@@ -29,17 +30,15 @@ module Imap::Backup
29
30
  def folders
30
31
  @folders ||=
31
32
  begin
32
- root = provider_root
33
- mailbox_lists = imap.list(root, "*")
33
+ folders = client.list
34
34
 
35
- if mailbox_lists.nil?
35
+ if folders.empty?
36
36
  message = "Unable to get folder list for account #{username}"
37
37
  Imap::Backup.logger.info message
38
38
  raise message
39
39
  end
40
40
 
41
- utf7_encoded = mailbox_lists.map(&:name)
42
- utf7_encoded.map { |n| Net::IMAP.decode_utf7(n) }
41
+ folders
43
42
  end
44
43
  end
45
44
 
@@ -54,7 +53,7 @@ module Imap::Backup
54
53
  def run_backup
55
54
  Imap::Backup.logger.debug "Running backup of account: #{username}"
56
55
  # start the connection so we get logging messages in the right order
57
- imap
56
+ client
58
57
  each_folder do |folder, serializer|
59
58
  next if !folder.exist?
60
59
 
@@ -89,34 +88,36 @@ module Imap::Backup
89
88
  end
90
89
 
91
90
  def disconnect
92
- imap.disconnect if @imap
91
+ client.disconnect if @client
93
92
  end
94
93
 
95
94
  def reconnect
96
95
  disconnect
97
- @imap = nil
96
+ @client = nil
98
97
  end
99
98
 
100
- def imap
101
- @imap ||=
99
+ def client
100
+ @client ||=
102
101
  retry_on_error(errors: LOGIN_RETRY_CLASSES) do
103
102
  options = provider_options
104
103
  Imap::Backup.logger.debug(
105
104
  "Creating IMAP instance: #{server}, options: #{options.inspect}"
106
105
  )
107
- imap = Net::IMAP.new(server, options)
106
+ client =
107
+ if provider.is_a?(Email::Provider::AppleMail)
108
+ Client::AppleMail.new(server, options)
109
+ else
110
+ Client::Default.new(server, options)
111
+ end
108
112
  Imap::Backup.logger.debug "Logging in: #{username}/#{masked_password}"
109
- imap.login(username, password)
113
+ client.login(username, password)
110
114
  Imap::Backup.logger.debug "Login complete"
111
- imap
115
+ client
112
116
  end
113
117
  end
114
118
 
115
119
  def server
116
- return @server if @server
117
- return nil if provider.nil?
118
-
119
- @server = provider.host
120
+ @server ||= provider.host
120
121
  end
121
122
 
122
123
  private
@@ -186,16 +187,5 @@ module Imap::Backup
186
187
  def provider_options
187
188
  provider.options.merge(connection_options)
188
189
  end
189
-
190
- # 6.3.8. LIST Command
191
- # An empty ("" string) mailbox name argument is a special request to
192
- # return the hierarchy delimiter and the root name of the name given
193
- # in the reference.
194
- def provider_root
195
- return @provider_root if @provider_root
196
-
197
- root_info = imap.list("", "")[0]
198
- @provider_root = root_info.name
199
- end
200
190
  end
201
191
  end
@@ -11,13 +11,13 @@ module Imap::Backup
11
11
  extend Forwardable
12
12
  include RetryOnError
13
13
 
14
- REQUESTED_ATTRIBUTES = %w[RFC822 FLAGS INTERNALDATE].freeze
14
+ BODY_ATTRIBUTE = "BODY[]".freeze
15
15
  UID_FETCH_RETRY_CLASSES = [EOFError].freeze
16
16
 
17
17
  attr_reader :connection
18
18
  attr_reader :name
19
19
 
20
- delegate imap: :connection
20
+ delegate client: :connection
21
21
 
22
22
  def initialize(connection, name)
23
23
  @connection = connection
@@ -40,20 +40,20 @@ module Imap::Backup
40
40
  def create
41
41
  return if exist?
42
42
 
43
- imap.create(utf7_encoded_name)
43
+ client.create(utf7_encoded_name)
44
44
  end
45
45
 
46
46
  def uid_validity
47
47
  @uid_validity ||=
48
48
  begin
49
49
  examine
50
- imap.responses["UIDVALIDITY"][-1]
50
+ client.responses["UIDVALIDITY"][-1]
51
51
  end
52
52
  end
53
53
 
54
54
  def uids
55
55
  examine
56
- imap.uid_search(["ALL"]).sort
56
+ client.uid_search(["ALL"]).sort
57
57
  rescue FolderNotFound
58
58
  []
59
59
  rescue NoMethodError
@@ -72,15 +72,14 @@ module Imap::Backup
72
72
  examine
73
73
  fetch_data_items =
74
74
  retry_on_error(errors: UID_FETCH_RETRY_CLASSES) do
75
- imap.uid_fetch([uid.to_i], REQUESTED_ATTRIBUTES)
75
+ client.uid_fetch([uid.to_i], [BODY_ATTRIBUTE])
76
76
  end
77
77
  return nil if fetch_data_items.nil?
78
78
 
79
79
  fetch_data_item = fetch_data_items[0]
80
80
  attributes = fetch_data_item.attr
81
- return nil if !attributes.key?("RFC822")
82
81
 
83
- attributes
82
+ attributes[BODY_ATTRIBUTE]
84
83
  rescue FolderNotFound
85
84
  nil
86
85
  end
@@ -88,14 +87,14 @@ module Imap::Backup
88
87
  def append(message)
89
88
  body = message.imap_body
90
89
  date = message.date&.to_time
91
- response = imap.append(utf7_encoded_name, body, nil, date)
90
+ response = client.append(utf7_encoded_name, body, nil, date)
92
91
  extract_uid(response)
93
92
  end
94
93
 
95
94
  private
96
95
 
97
96
  def examine
98
- imap.examine(utf7_encoded_name)
97
+ client.examine(utf7_encoded_name)
99
98
  rescue Net::IMAP::NoResponseError
100
99
  Imap::Backup.logger.warn "Folder '#{name}' does not exist on server"
101
100
  raise FolderNotFound, "Folder '#{name}' does not exist on server"
@@ -9,6 +9,7 @@ module Imap::Backup::CLI::Helpers
9
9
  connections = Imap::Backup::Configuration::List.new
10
10
  account = connections.accounts.find { |a| a[:username] == email }
11
11
  raise "#{email} is not a configured account" if !account
12
+
12
13
  account
13
14
  end
14
15
 
@@ -28,7 +28,10 @@ module Imap::Backup
28
28
  raise "Folder '#{folder_name}' not found" if !folder_serializer
29
29
 
30
30
  max_subject = 60
31
- Kernel.puts format("%-10<uid>s %-#{max_subject}<subject>s - %<date>s", {uid: "UID", subject: "Subject", date: "Date"})
31
+ Kernel.puts format(
32
+ "%-10<uid>s %-#{max_subject}<subject>s - %<date>s",
33
+ {uid: "UID", subject: "Subject", date: "Date"}
34
+ )
32
35
  Kernel.puts "-" * (12 + max_subject + 28)
33
36
 
34
37
  uids = folder_serializer.uids
@@ -5,7 +5,7 @@ module Imap::Backup
5
5
  include Thor::Actions
6
6
  include CLI::Helpers
7
7
 
8
- FAKE_EMAIL = "fake@email.com"
8
+ FAKE_EMAIL = "fake@email.com".freeze
9
9
 
10
10
  desc "ignore-history EMAIL", "Skip downloading emails up to today for all configured folders"
11
11
  def ignore_history(email)
@@ -13,15 +13,18 @@ module Imap::Backup
13
13
 
14
14
  connection.local_folders.each do |serializer, folder|
15
15
  next if !folder.exist?
16
+
16
17
  do_ignore_folder_history(folder, serializer)
17
18
  end
18
19
  end
19
20
 
20
- desc "export-to-thunderbird EMAIL [OPTIONS]",
21
+ desc(
22
+ "export-to-thunderbird EMAIL [OPTIONS]",
21
23
  <<~DOC
22
24
  [Experimental] Copy backed up emails to Thunderbird.
23
25
  A folder called 'imap-backup/EMAIL' is created under 'Local Folders'.
24
26
  DOC
27
+ )
25
28
  method_option(
26
29
  "force",
27
30
  type: :boolean,
@@ -50,7 +53,7 @@ module Imap::Backup
50
53
  end
51
54
  end
52
55
 
53
- connection.local_folders.each do |serializer, folder|
56
+ connection.local_folders.each do |serializer, _folder|
54
57
  Thunderbird::MailboxExporter.new(
55
58
  email, serializer, profile, force: force
56
59
  ).run
@@ -76,10 +79,18 @@ module Imap::Backup
76
79
  end
77
80
 
78
81
  def thunderbird_profile(name = nil)
82
+ profiles = Thunderbird::Profiles.new
79
83
  if name
80
- Thunderbird::Profiles.new.profile(name)
84
+ profiles.profile(name)
81
85
  else
82
- Thunderbird::Profiles.new.default
86
+ if profiles.installs.count > 1
87
+ raise <<~MESSAGE
88
+ Thunderbird has multiple installs, so no default profile exists.
89
+ Please supply a profile name
90
+ MESSAGE
91
+ end
92
+
93
+ profiles.installs[0].default
83
94
  end
84
95
  end
85
96
  end
@@ -0,0 +1,11 @@
1
+ require "imap/backup/client/default"
2
+
3
+ module Imap::Backup
4
+ class Client::AppleMail < Client::Default
5
+ # With Apple Mails's IMAP, passing "/" to list
6
+ # results in an empty list
7
+ def provider_root
8
+ ""
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,51 @@
1
+ require "forwardable"
2
+ require "net/imap"
3
+
4
+ module Imap::Backup
5
+ module Client; end
6
+
7
+ class Client::Default
8
+ extend Forwardable
9
+ def_delegators :imap, *%i(
10
+ append authenticate create disconnect examine
11
+ login responses uid_fetch uid_search
12
+ )
13
+
14
+ attr_reader :args
15
+
16
+ def initialize(*args)
17
+ @args = args
18
+ end
19
+
20
+ def list
21
+ root = provider_root
22
+ mailbox_lists = imap.list(root, "*")
23
+
24
+ return [] if mailbox_lists.nil?
25
+
26
+ mailbox_lists.map { |ml| extract_name(ml) }
27
+ end
28
+
29
+ private
30
+
31
+ def imap
32
+ @imap ||= Net::IMAP.new(*args)
33
+ end
34
+
35
+ def extract_name(mailbox_list)
36
+ utf7_encoded = mailbox_list.name
37
+ Net::IMAP.decode_utf7(utf7_encoded)
38
+ end
39
+
40
+ # 6.3.8. LIST Command
41
+ # An empty ("" string) mailbox name argument is a special request to
42
+ # return the hierarchy delimiter and the root name of the name given
43
+ # in the reference.
44
+ def provider_root
45
+ @provider_root ||= begin
46
+ root_info = imap.list("", "")[0]
47
+ root_info.name
48
+ end
49
+ end
50
+ end
51
+ end
@@ -147,10 +147,12 @@ module Imap::Backup
147
147
 
148
148
  def default_server(username)
149
149
  provider = Email::Provider.for_address(username)
150
- if provider.provider == :default
150
+
151
+ if provider.is_a?(Email::Provider::Default)
151
152
  Kernel.puts "Can't decide provider for email address '#{username}'"
152
153
  return nil
153
154
  end
155
+
154
156
  provider.host
155
157
  end
156
158
  end
@@ -3,7 +3,7 @@ module Imap::Backup
3
3
 
4
4
  module Configuration::ConnectionTester
5
5
  def self.test(account)
6
- Account::Connection.new(account).imap
6
+ Account::Connection.new(account).client
7
7
  "Connection successful"
8
8
  rescue Net::IMAP::NoResponseError
9
9
  "No response"
@@ -1,4 +1,5 @@
1
1
  require "json"
2
+ require "os"
2
3
 
3
4
  module Imap::Backup
4
5
  module Configuration; end
@@ -25,11 +26,12 @@ module Imap::Backup
25
26
  end
26
27
 
27
28
  def save
28
- mkdir_private path
29
+ FileUtils.mkdir(path) if !File.directory?(path)
30
+ make_private(path) if !windows?
29
31
  remove_modified_flags
30
32
  remove_deleted_accounts
31
33
  File.open(pathname, "w") { |f| f.write(JSON.pretty_generate(data)) }
32
- FileUtils.chmod 0o600, pathname
34
+ FileUtils.chmod(0o600, pathname) if !windows?
33
35
  end
34
36
 
35
37
  def accounts
@@ -54,7 +56,7 @@ module Imap::Backup
54
56
  @data ||=
55
57
  begin
56
58
  if File.exist?(pathname)
57
- Utils.check_permissions pathname, 0o600
59
+ Utils.check_permissions(pathname, 0o600) if !windows?
58
60
  contents = File.read(pathname)
59
61
  data = JSON.parse(contents, symbolize_names: true)
60
62
  else
@@ -73,9 +75,12 @@ module Imap::Backup
73
75
  accounts.reject! { |a| a[:delete] }
74
76
  end
75
77
 
76
- def mkdir_private(path)
77
- FileUtils.mkdir(path) if !File.directory?(path)
78
+ def make_private(path)
78
79
  FileUtils.chmod(0o700, path) if Utils.mode(path) != 0o700
79
80
  end
81
+
82
+ def windows?
83
+ OS.windows?
84
+ end
80
85
  end
81
86
  end
@@ -13,16 +13,15 @@ module Imap::Backup
13
13
  count = uids.count
14
14
  Imap::Backup.logger.debug "[#{folder.name}] #{count} new messages"
15
15
  uids.each.with_index do |uid, i|
16
- message = folder.fetch(uid)
16
+ body = folder.fetch(uid)
17
17
  log_prefix = "[#{folder.name}] uid: #{uid} (#{i + 1}/#{count}) -"
18
- if message.nil?
18
+ if body.nil?
19
19
  Imap::Backup.logger.debug("#{log_prefix} not available - skipped")
20
20
  next
21
21
  end
22
22
  Imap::Backup.logger.debug(
23
- "#{log_prefix} #{message['RFC822'].size} bytes"
23
+ "#{log_prefix} #{body.size} bytes"
24
24
  )
25
- body = message["RFC822"]
26
25
  serializer.save(uid, body)
27
26
  end
28
27
  end
@@ -1,10 +1,9 @@
1
1
  require "thunderbird/local_folder"
2
- require "thunderbird/mailbox"
3
2
  require "thunderbird/profiles"
4
3
 
5
4
  module Imap::Backup
6
5
  class Thunderbird::MailboxExporter
7
- EXPORT_PREFIX = "imap-backup"
6
+ EXPORT_PREFIX = "imap-backup".freeze
8
7
 
9
8
  attr_reader :email
10
9
  attr_reader :serializer
@@ -19,28 +18,29 @@ module Imap::Backup
19
18
  end
20
19
 
21
20
  def run
22
- local_folder.set_up
21
+ local_folder_ok = local_folder.set_up
22
+ return if !local_folder_ok
23
23
 
24
- if mailbox.msf_exists?
24
+ if local_folder.msf_exists?
25
25
  if force
26
- Kernel.puts "Deleting '#{mailbox.msf_path}' as --force option was supplied"
27
- File.unlink mailbox.msf_path
26
+ Kernel.puts "Deleting '#{local_folder.msf_path}' as --force option was supplied"
27
+ File.unlink local_folder.msf_path
28
28
  else
29
- Kernel.puts "Skipping export of '#{folder.name}' as '#{mailbox.msf_path}' exists"
29
+ Kernel.puts "Skipping export of '#{serializer.folder}' as '#{local_folder.msf_path}' exists"
30
30
  return false
31
31
  end
32
32
  end
33
33
 
34
- if mailbox.exists?
34
+ if local_folder.exists?
35
35
  if force
36
- Kernel.puts "Overwriting '#{mailbox.path}' as --force option was supplied"
36
+ Kernel.puts "Overwriting '#{local_folder.path}' as --force option was supplied"
37
37
  else
38
- Kernel.puts "Skipping export of '#{folder.name}' as '#{mailbox.path}' exists"
38
+ Kernel.puts "Skipping export of '#{serializer.folder}' as '#{local_folder.path}' exists"
39
39
  return false
40
40
  end
41
41
  end
42
42
 
43
- FileUtils.cp serializer.mbox_pathname, mailbox.path
43
+ FileUtils.cp serializer.mbox_pathname, local_folder.full_path
44
44
 
45
45
  true
46
46
  end
@@ -49,23 +49,10 @@ module Imap::Backup
49
49
 
50
50
  def local_folder
51
51
  @local_folder ||= begin
52
- folder_path = File.dirname(serializer.folder)
53
52
  top_level_folders = [EXPORT_PREFIX, email]
54
- prefixed_folder_path =
55
- if folder_path == "."
56
- File.join(top_level_folders)
57
- else
58
- File.join(top_level_folders, folder_path)
59
- end
53
+ prefixed_folder_path = File.join(top_level_folders, serializer.folder)
60
54
  Thunderbird::LocalFolder.new(profile, prefixed_folder_path)
61
55
  end
62
56
  end
63
-
64
- def mailbox
65
- @mailbox ||= begin
66
- mailbox_name = File.basename(serializer.folder)
67
- Thunderbird::Mailbox.new(local_folder, mailbox_name)
68
- end
69
- end
70
57
  end
71
58
  end
@@ -3,7 +3,7 @@ module Imap; end
3
3
  module Imap::Backup
4
4
  MAJOR = 4
5
5
  MINOR = 0
6
- REVISION = 2
6
+ REVISION = 3
7
7
  PRE = nil
8
8
  VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
9
9
  end
@@ -0,0 +1,16 @@
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