imap-backup 6.0.0.rc2 → 6.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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/imap-backup.gemspec +5 -1
  3. data/lib/cli_coverage.rb +11 -11
  4. data/lib/email/provider/base.rb +2 -0
  5. data/lib/email/provider/unknown.rb +2 -0
  6. data/lib/email/provider.rb +2 -0
  7. data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
  8. data/lib/imap/backup/account/connection/client_factory.rb +54 -0
  9. data/lib/imap/backup/account/connection/folder_names.rb +26 -0
  10. data/lib/imap/backup/account/connection.rb +11 -95
  11. data/lib/imap/backup/account/folder.rb +9 -6
  12. data/lib/imap/backup/account.rb +3 -5
  13. data/lib/imap/backup/cli/backup.rb +1 -3
  14. data/lib/imap/backup/cli/helpers.rb +24 -22
  15. data/lib/imap/backup/cli/local.rb +20 -13
  16. data/lib/imap/backup/cli/migrate.rb +4 -10
  17. data/lib/imap/backup/cli/restore.rb +8 -7
  18. data/lib/imap/backup/cli/setup.rb +10 -8
  19. data/lib/imap/backup/cli/stats.rb +78 -0
  20. data/lib/imap/backup/cli/status.rb +2 -2
  21. data/lib/imap/backup/cli/utils.rb +4 -6
  22. data/lib/imap/backup/cli.rb +24 -3
  23. data/lib/imap/backup/configuration.rb +9 -11
  24. data/lib/imap/backup/downloader.rb +48 -30
  25. data/lib/imap/backup/migrator.rb +5 -5
  26. data/lib/imap/backup/sanitizer.rb +3 -2
  27. data/lib/imap/backup/serializer/appender.rb +49 -0
  28. data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
  29. data/lib/imap/backup/serializer/unused_name_finder.rb +27 -0
  30. data/lib/imap/backup/serializer.rb +24 -78
  31. data/lib/imap/backup/setup/account/header.rb +75 -0
  32. data/lib/imap/backup/setup/account.rb +14 -91
  33. data/lib/imap/backup/setup/asker.rb +4 -15
  34. data/lib/imap/backup/setup/backup_path.rb +41 -0
  35. data/lib/imap/backup/setup/email.rb +45 -0
  36. data/lib/imap/backup/setup/folder_chooser.rb +3 -3
  37. data/lib/imap/backup/setup/helpers.rb +1 -1
  38. data/lib/imap/backup/setup.rb +5 -4
  39. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +39 -20
  40. data/lib/imap/backup/uploader.rb +46 -8
  41. data/lib/imap/backup/utils.rb +1 -1
  42. data/lib/imap/backup/version.rb +1 -1
  43. data/lib/imap/backup.rb +0 -1
  44. metadata +31 -134
  45. data/spec/features/backup_spec.rb +0 -100
  46. data/spec/features/configuration/minimal_configuration.rb +0 -15
  47. data/spec/features/configuration/missing_configuration.rb +0 -14
  48. data/spec/features/folders_spec.rb +0 -36
  49. data/spec/features/helper.rb +0 -2
  50. data/spec/features/local/list_accounts_spec.rb +0 -12
  51. data/spec/features/local/list_emails_spec.rb +0 -21
  52. data/spec/features/local/list_folders_spec.rb +0 -21
  53. data/spec/features/local/show_an_email_spec.rb +0 -34
  54. data/spec/features/migrate_spec.rb +0 -35
  55. data/spec/features/remote/list_account_folders_spec.rb +0 -16
  56. data/spec/features/restore_spec.rb +0 -162
  57. data/spec/features/status_spec.rb +0 -43
  58. data/spec/features/support/aruba.rb +0 -78
  59. data/spec/features/support/backup_directory.rb +0 -43
  60. data/spec/features/support/email_server.rb +0 -110
  61. data/spec/features/support/shared/connection_context.rb +0 -14
  62. data/spec/features/support/shared/message_fixtures.rb +0 -16
  63. data/spec/fixtures/connection.yml +0 -7
  64. data/spec/spec_helper.rb +0 -15
  65. data/spec/support/fixtures.rb +0 -11
  66. data/spec/support/higline_test_helpers.rb +0 -8
  67. data/spec/support/silence_logging.rb +0 -7
  68. data/spec/unit/email/mboxrd/message_spec.rb +0 -177
  69. data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
  70. data/spec/unit/email/provider/base_spec.rb +0 -11
  71. data/spec/unit/email/provider/fastmail_spec.rb +0 -7
  72. data/spec/unit/email/provider/gmail_spec.rb +0 -7
  73. data/spec/unit/email/provider_spec.rb +0 -27
  74. data/spec/unit/imap/backup/account/connection_spec.rb +0 -433
  75. data/spec/unit/imap/backup/account/folder_spec.rb +0 -261
  76. data/spec/unit/imap/backup/account_spec.rb +0 -246
  77. data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -58
  78. data/spec/unit/imap/backup/cli/backup_spec.rb +0 -19
  79. data/spec/unit/imap/backup/cli/folders_spec.rb +0 -39
  80. data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
  81. data/spec/unit/imap/backup/cli/local_spec.rb +0 -100
  82. data/spec/unit/imap/backup/cli/migrate_spec.rb +0 -80
  83. data/spec/unit/imap/backup/cli/restore_spec.rb +0 -67
  84. data/spec/unit/imap/backup/cli/setup_spec.rb +0 -17
  85. data/spec/unit/imap/backup/cli/utils_spec.rb +0 -125
  86. data/spec/unit/imap/backup/cli_spec.rb +0 -93
  87. data/spec/unit/imap/backup/client/apple_mail_spec.rb +0 -9
  88. data/spec/unit/imap/backup/client/default_spec.rb +0 -22
  89. data/spec/unit/imap/backup/configuration_spec.rb +0 -238
  90. data/spec/unit/imap/backup/downloader_spec.rb +0 -96
  91. data/spec/unit/imap/backup/logger_spec.rb +0 -48
  92. data/spec/unit/imap/backup/migrator_spec.rb +0 -58
  93. data/spec/unit/imap/backup/sanitizer_spec.rb +0 -42
  94. data/spec/unit/imap/backup/serializer/directory_spec.rb +0 -37
  95. data/spec/unit/imap/backup/serializer/imap_spec.rb +0 -218
  96. data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +0 -45
  97. data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -101
  98. data/spec/unit/imap/backup/serializer_spec.rb +0 -296
  99. data/spec/unit/imap/backup/setup/account_spec.rb +0 -461
  100. data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
  101. data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
  102. data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
  103. data/spec/unit/imap/backup/setup/helpers_spec.rb +0 -15
  104. data/spec/unit/imap/backup/setup_spec.rb +0 -301
  105. data/spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb +0 -116
  106. data/spec/unit/imap/backup/uploader_spec.rb +0 -54
  107. data/spec/unit/imap/backup/utils_spec.rb +0 -92
  108. data/spec/unit/retry_on_error_spec.rb +0 -34
@@ -0,0 +1,75 @@
1
+ require "imap/backup/setup/helpers"
2
+
3
+ module Imap::Backup
4
+ class Setup; end
5
+ class Setup::Account; end
6
+
7
+ class Setup::Account::Header
8
+ attr_reader :account
9
+ attr_reader :menu
10
+
11
+ def initialize(menu:, account:)
12
+ @menu = menu
13
+ @account = account
14
+ end
15
+
16
+ def run
17
+ menu.header = <<~HEADER.chomp
18
+ #{helpers.title_prefix} Account#{modified_flag}
19
+
20
+ email #{space}#{account.username}
21
+ password#{space}#{masked_password}
22
+ path #{space}#{local_path}
23
+ folders #{space}#{folders.map { |f| f[:name] }.join(', ')}#{multi_fetch_size}
24
+ server #{space}#{account.server}#{connection_options}
25
+
26
+ Choose an action
27
+ HEADER
28
+ end
29
+
30
+ private
31
+
32
+ def folders
33
+ account.folders || []
34
+ end
35
+
36
+ def helpers
37
+ Setup::Helpers.new
38
+ end
39
+
40
+ def modified_flag
41
+ account.modified? ? "*" : ""
42
+ end
43
+
44
+ def multi_fetch_size
45
+ "\nmulti-fetch #{account.multi_fetch_size}" if account.multi_fetch_size > 1
46
+ end
47
+
48
+ def connection_options
49
+ return nil if !account.connection_options
50
+
51
+ escaped = JSON.generate(account.connection_options)
52
+ escaped.gsub!('"', '\"')
53
+ "\nconnection options '#{escaped}'"
54
+ end
55
+
56
+ def space
57
+ account.connection_options ? " " * 12 : " " * 4
58
+ end
59
+
60
+ def masked_password
61
+ if (account.password == "") || account.password.nil?
62
+ "(unset)"
63
+ else
64
+ account.password.gsub(/./, "x")
65
+ end
66
+ end
67
+
68
+ def local_path
69
+ # In order to handle backslashes, as Highline effectively
70
+ # does an eval (!) on its templates, we need to doubly
71
+ # escape them
72
+ account.local_path.gsub("\\", "\\\\\\\\")
73
+ end
74
+ end
75
+ end
@@ -1,11 +1,19 @@
1
- require "imap/backup/setup/helpers"
1
+ require "imap/backup/setup/account/header"
2
+ require "imap/backup/setup/backup_path"
3
+ require "imap/backup/setup/email"
2
4
 
3
5
  module Imap::Backup
4
6
  class Setup; end
5
7
 
6
- Setup::Account = Struct.new(:config, :account, :highline) do
8
+ class Setup::Account
9
+ attr_reader :account
10
+ attr_reader :config
11
+ attr_reader :highline
12
+
7
13
  def initialize(config, account, highline)
8
- super
14
+ @account = account
15
+ @config = config
16
+ @highline = highline
9
17
  end
10
18
 
11
19
  def run
@@ -37,54 +45,12 @@ module Imap::Backup
37
45
  end
38
46
 
39
47
  def header(menu)
40
- modified = account.modified? ? "*" : ""
41
-
42
- if account.multi_fetch_size > 1
43
- multi_fetch_size = "\nmulti-fetch #{account.multi_fetch_size}"
44
- end
45
-
46
- if account.connection_options
47
- escaped =
48
- JSON.generate(account.connection_options)
49
- connection_options =
50
- "\nconnection options '#{escaped}'"
51
- space = " " * 12
52
- else
53
- connection_options = nil
54
- space = " " * 4
55
- end
56
-
57
- menu.header = <<~HEADER.chomp
58
- #{helpers.title_prefix} Account#{modified}
59
-
60
- email #{space}#{account.username}
61
- password#{space}#{masked_password}
62
- path #{space}#{account.local_path}
63
- folders #{space}#{folders.map { |f| f[:name] }.join(', ')}#{multi_fetch_size}
64
- server #{space}#{account.server}#{connection_options}
65
-
66
- Choose an action
67
- HEADER
48
+ Setup::Account::Header.new(menu: menu, account: account).run
68
49
  end
69
50
 
70
51
  def modify_email(menu)
71
52
  menu.choice("modify email") do
72
- username = Setup::Asker.email(username)
73
- Kernel.puts "username: #{username}"
74
- other_accounts = config.accounts.reject { |a| a == account }
75
- others = other_accounts.map { |a| a.username }
76
- Kernel.puts "others: #{others.inspect}"
77
- if others.include?(username)
78
- Kernel.puts(
79
- "There is already an account set up with that email address"
80
- )
81
- else
82
- account.username = username
83
- default = default_server(username)
84
- if default && (account.server.nil? || (account.server == ""))
85
- account.server = default
86
- end
87
- end
53
+ Setup::Email.new(account: account, config: config).run
88
54
  end
89
55
  end
90
56
 
@@ -96,25 +62,9 @@ module Imap::Backup
96
62
  end
97
63
  end
98
64
 
99
- def path_modification_validator(path)
100
- same = config.accounts.find do |a|
101
- a.username != account.username && a.local_path == path
102
- end
103
- if same
104
- Kernel.puts "The path '#{path}' is used to backup " \
105
- "the account '#{same.username}'"
106
- false
107
- else
108
- true
109
- end
110
- end
111
-
112
65
  def modify_backup_path(menu)
113
66
  menu.choice("modify backup path") do
114
- existing = account.local_path.clone
115
- account.local_path = Setup::Asker.backup_path(
116
- account.local_path, ->(path) { path_modification_validator(path) }
117
- )
67
+ Setup::BackupPath.new(account: account, config: config).run
118
68
  end
119
69
  end
120
70
 
@@ -169,32 +119,5 @@ module Imap::Backup
169
119
  end
170
120
  end
171
121
  end
172
-
173
- def folders
174
- account.folders || []
175
- end
176
-
177
- def masked_password
178
- if (account.password == "") || account.password.nil?
179
- "(unset)"
180
- else
181
- account.password.gsub(/./, "x")
182
- end
183
- end
184
-
185
- def default_server(username)
186
- provider = Email::Provider.for_address(username)
187
-
188
- if provider.is_a?(Email::Provider::Unknown)
189
- Kernel.puts "Can't decide provider for email address '#{username}'"
190
- return nil
191
- end
192
-
193
- provider.host
194
- end
195
-
196
- def helpers
197
- Setup::Helpers.new
198
- end
199
122
  end
200
123
  end
@@ -1,11 +1,13 @@
1
1
  module Imap::Backup
2
2
  class Setup; end
3
3
 
4
- Setup::Asker = Struct.new(:highline) do
4
+ class Setup::Asker
5
5
  EMAIL_MATCHER = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i.freeze
6
6
 
7
+ attr_reader :highline
8
+
7
9
  def initialize(highline)
8
- super
10
+ @highline = highline
9
11
  end
10
12
 
11
13
  def email(default = "")
@@ -30,15 +32,6 @@ module Imap::Backup
30
32
  password
31
33
  end
32
34
 
33
- def backup_path(default, validator)
34
- highline.ask("backup directory: ") do |q|
35
- q.default = default
36
- q.readline = true
37
- q.validate = validator
38
- q.responses[:not_valid] = "Choose a different directory "
39
- end
40
- end
41
-
42
35
  def self.email(default = "")
43
36
  new(Setup.highline).email(default)
44
37
  end
@@ -46,9 +39,5 @@ module Imap::Backup
46
39
  def self.password
47
40
  new(Setup.highline).password
48
41
  end
49
-
50
- def self.backup_path(default, validator)
51
- new(Setup.highline).backup_path(default, validator)
52
- end
53
42
  end
54
43
  end
@@ -0,0 +1,41 @@
1
+ module Imap::Backup
2
+ class Setup; end
3
+
4
+ class Setup::BackupPath
5
+ attr_reader :account
6
+ attr_reader :config
7
+
8
+ def initialize(account:, config:)
9
+ @account = account
10
+ @config = config
11
+ end
12
+
13
+ def run
14
+ account.local_path = highline.ask("backup directory: ") do |q|
15
+ q.default = account.local_path
16
+ q.readline = true
17
+ q.validate = ->(path) { path_modification_validator(path) }
18
+ q.responses[:not_valid] = "Choose a different directory "
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def highline
25
+ Setup.highline
26
+ end
27
+
28
+ def path_modification_validator(path)
29
+ same = config.accounts.find do |a|
30
+ a.username != account.username && a.local_path == path
31
+ end
32
+ if same
33
+ Kernel.puts "The path '#{path}' is used to backup " \
34
+ "the account '#{same.username}'"
35
+ false
36
+ else
37
+ true
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,45 @@
1
+ require "email/provider"
2
+
3
+ module Imap::Backup
4
+ class Setup; end
5
+
6
+ class Setup::Email
7
+ attr_reader :account
8
+ attr_reader :config
9
+
10
+ def initialize(account:, config:)
11
+ @account = account
12
+ @config = config
13
+ end
14
+
15
+ def run
16
+ username = Setup::Asker.email(account.username)
17
+ other_accounts = config.accounts.reject { |a| a == account }
18
+ others = other_accounts.map(&:username)
19
+ if others.include?(username)
20
+ Kernel.puts(
21
+ "There is already an account set up with that email address"
22
+ )
23
+ else
24
+ account.username = username
25
+ if account.server.nil? || (account.server == "")
26
+ default = default_server(username)
27
+ account.server = default if default
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def default_server(username)
35
+ provider = Email::Provider.for_address(username)
36
+
37
+ if provider.is_a?(Email::Provider::Unknown)
38
+ Kernel.puts "Can't decide provider for email address '#{username}'"
39
+ return nil
40
+ end
41
+
42
+ provider.host
43
+ end
44
+ end
45
+ end
@@ -12,13 +12,13 @@ module Imap::Backup
12
12
 
13
13
  def run
14
14
  if connection.nil?
15
- Imap::Backup::Logger.logger.warn "Connection failed"
15
+ Logger.logger.warn "Connection failed"
16
16
  highline.ask "Press a key "
17
17
  return
18
18
  end
19
19
 
20
20
  if imap_folders.nil?
21
- Imap::Backup::Logger.logger.warn "Unable to get folder list"
21
+ Logger.logger.warn "Unable to get folder list"
22
22
  highline.ask "Press a key "
23
23
  return
24
24
  end
@@ -90,7 +90,7 @@ module Imap::Backup
90
90
 
91
91
  def toggle_selection(folder_name)
92
92
  if selected?(folder_name)
93
- new_list = account.folders.select { |f| f[:name] != folder_name }
93
+ new_list = account.folders.reject { |f| f[:name] == folder_name }
94
94
  account.folders = new_list
95
95
  else
96
96
  existing = account.folders || []
@@ -5,7 +5,7 @@ module Imap::Backup
5
5
 
6
6
  class Setup::Helpers
7
7
  def title_prefix
8
- "imap-backup "
8
+ "imap-backup -"
9
9
  end
10
10
 
11
11
  def version
@@ -1,5 +1,6 @@
1
1
  require "highline"
2
2
 
3
+ require "email/provider"
3
4
  require "imap/backup/account"
4
5
  require "imap/backup/setup/helpers"
5
6
 
@@ -36,7 +37,7 @@ module Imap::Backup
36
37
  config.save
37
38
  throw :done
38
39
  end
39
- menu.choice("exit without saving changes") { throw :done }
40
+ menu.choice("exit without saving changes") { throw :done }
40
41
  else
41
42
  menu.choice("quit") { throw :done }
42
43
  end
@@ -67,7 +68,7 @@ module Imap::Backup
67
68
  new_setting = !config.debug?
68
69
  menu.choice(menu_item) do
69
70
  config.debug = new_setting
70
- Imap::Backup::Logger.setup_logging(config)
71
+ Logger.setup_logging(config)
71
72
  end
72
73
  end
73
74
 
@@ -76,13 +77,13 @@ module Imap::Backup
76
77
  end
77
78
 
78
79
  def default_account_config(username)
79
- ::Imap::Backup::Account.new(
80
+ Imap::Backup::Account.new(
80
81
  username: username,
81
82
  password: "",
82
83
  local_path: File.join(config.path, username.tr("@", "_")),
83
84
  folders: []
84
85
  ).tap do |a|
85
- server = Email::Provider.for_address(username)
86
+ server = ::Email::Provider.for_address(username)
86
87
  a.server = server.host if server.host
87
88
  end
88
89
  end
@@ -21,28 +21,51 @@ module Imap::Backup
21
21
  local_folder_ok = local_folder.set_up
22
22
  return false if !local_folder_ok
23
23
 
24
- if local_folder.msf_exists?
25
- if force
26
- Kernel.puts "Deleting '#{local_folder.msf_path}' as --force option was supplied"
27
- File.unlink local_folder.msf_path
28
- else
29
- Kernel.puts "Skipping export of '#{serializer.folder}' as '#{local_folder.msf_path}' exists"
30
- return false
31
- end
24
+ skip_for_msf = check_msf
25
+ return false if skip_for_msf
26
+
27
+ skip_for_local_folder = check_local_folder
28
+ return false if skip_for_local_folder
29
+
30
+ copy_messages
31
+
32
+ true
33
+ end
34
+
35
+ private
36
+
37
+ def check_local_folder
38
+ return false if !local_folder.exists?
39
+
40
+ if force
41
+ Kernel.puts "Overwriting '#{local_folder.path}' as --force option was supplied"
42
+ return false
32
43
  end
33
44
 
34
- if local_folder.exists?
35
- if force
36
- Kernel.puts "Overwriting '#{local_folder.path}' as --force option was supplied"
37
- else
38
- Kernel.puts "Skipping export of '#{serializer.folder}' as '#{local_folder.path}' exists"
39
- return false
40
- end
45
+ Kernel.puts "Skipping export of '#{serializer.folder}' as '#{local_folder.path}' exists"
46
+ true
47
+ end
48
+
49
+ def check_msf
50
+ return false if !local_folder.msf_exists?
51
+
52
+ if force
53
+ Kernel.puts "Deleting '#{local_folder.msf_path}' as --force option was supplied"
54
+ File.unlink local_folder.msf_path
55
+ return false
41
56
  end
42
57
 
58
+ Kernel.puts(
59
+ "Skipping export of '#{serializer.folder}' " \
60
+ "as '#{local_folder.msf_path}' exists"
61
+ )
62
+ true
63
+ end
64
+
65
+ def copy_messages
43
66
  File.open(local_folder.full_path, "w") do |f|
44
67
  enumerator = Serializer::MboxEnumerator.new(serializer.mbox_pathname)
45
- enumerator.each.with_index do |raw, i|
68
+ enumerator.each do |raw|
46
69
  clean = Email::Mboxrd::Message.clean_serialized(raw)
47
70
  timestamp = Time.now.strftime("%a %b %d %H:%M:%S %Y")
48
71
  thunderbird_fom_line = "From - #{timestamp}"
@@ -50,12 +73,8 @@ module Imap::Backup
50
73
  f.write output
51
74
  end
52
75
  end
53
-
54
- true
55
76
  end
56
77
 
57
- private
58
-
59
78
  def local_folder
60
79
  @local_folder ||= begin
61
80
  top_level_folders = [EXPORT_PREFIX, email]
@@ -9,27 +9,65 @@ module Imap::Backup
9
9
  end
10
10
 
11
11
  def run
12
- count = missing_uids.count
12
+ if folder.uids.any?
13
+ rename_serialized_folder
14
+ else
15
+ folder.create
16
+ serializer.force_uid_validity(folder.uid_validity)
17
+ end
18
+
13
19
  return if count.zero?
14
20
 
15
- Imap::Backup::Logger.logger.debug "[#{folder.name}] #{count} to restore"
21
+ Logger.logger.debug "[#{folder.name}] #{count} to restore"
16
22
  serializer.each_message(missing_uids).with_index do |(uid, message), i|
17
- next if message.nil?
23
+ upload_message uid, message, i + 1
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def upload_message(uid, message, index)
30
+ return if message.nil?
18
31
 
19
- log_prefix = "[#{folder.name}] uid: #{uid} (#{i + 1}/#{count}) -"
20
- Imap::Backup::Logger.logger.debug(
21
- "#{log_prefix} #{message.supplied_body.size} bytes"
22
- )
32
+ log_prefix = "[#{folder.name}] uid: #{uid} (#{index}/#{count}) -"
33
+ Logger.logger.debug(
34
+ "#{log_prefix} #{message.supplied_body.size} bytes"
35
+ )
23
36
 
37
+ begin
24
38
  new_uid = folder.append(message)
25
39
  serializer.update_uid(uid, new_uid)
40
+ rescue StandardError => e
41
+ Logger.logger.warn "#{log_prefix} append error: #{e}"
26
42
  end
27
43
  end
28
44
 
29
- private
45
+ def count
46
+ @count ||= missing_uids.count
47
+ end
30
48
 
31
49
  def missing_uids
32
50
  serializer.uids - folder.uids
33
51
  end
52
+
53
+ def rename_serialized_folder
54
+ Logger.logger.debug(
55
+ "There's already a '#{folder.name}' folder with emails"
56
+ )
57
+
58
+ # Rename the local folder to a unique name
59
+ new_name = serializer.apply_uid_validity(folder.uid_validity)
60
+
61
+ return if !new_name
62
+
63
+ # Restore the renamed folder
64
+ Logger.logger.debug(
65
+ "Backup '#{serializer.folder}' renamed and restored to '#{new_name}'"
66
+ )
67
+ @folder = Account::Folder.new(folder.connection, new_name)
68
+ folder.create
69
+ @serializer = Serializer.new(serializer.path, new_name)
70
+ serializer.force_uid_validity(@folder.uid_validity)
71
+ end
34
72
  end
35
73
  end
@@ -11,7 +11,7 @@ module Imap::Backup
11
11
 
12
12
  message = format(
13
13
  "Permissions on '%<filename>s' " \
14
- "should be 0%<limit>o, not 0%<actual>o",
14
+ "should be 0%<limit>o, not 0%<actual>o",
15
15
  filename: filename, limit: limit, actual: actual
16
16
  )
17
17
  raise message
@@ -4,6 +4,6 @@ module Imap::Backup
4
4
  MAJOR = 6
5
5
  MINOR = 0
6
6
  REVISION = 0
7
- PRE = "rc2".freeze
7
+ PRE = nil
8
8
  VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
9
9
  end
data/lib/imap/backup.rb CHANGED
@@ -14,7 +14,6 @@ require "imap/backup/setup/asker"
14
14
  require "imap/backup/setup/connection_tester"
15
15
  require "imap/backup/setup/folder_chooser"
16
16
  require "imap/backup/version"
17
- require "email/provider"
18
17
 
19
18
  module Imap::Backup
20
19
  class ConfigurationNotFound < StandardError; end