imap-backup 13.3.0 → 13.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52be0d33c65e865c04931e81821a563e8203a001a951b8ec6624f0fded2180aa
4
- data.tar.gz: 2fece56b157329aa6e8cd0bc73d66d5ec3c3923f126822977910dc904d955a1a
3
+ metadata.gz: b20d641221d0ad7716b1d5a52f28c80929197d4d22bcfdaab574061f5ba7640a
4
+ data.tar.gz: 3c6ae086014f6ec6568eb9c226e17928877f1d972898bd3ec0e139ba09983cfb
5
5
  SHA512:
6
- metadata.gz: 26c0c0434bf7743a3ce9b8b6c0f24b05b14682f4e52fcacf4813cec7a913df720f6413a066b25db810e04d4e18411cfbd79119430f37785186b3013757a2e76d
7
- data.tar.gz: 3f250c3272221488bb8b9c08b1f68198a1a6b3f45bd75c31ccc6b2284c0e2130d65bcd91783c6c85b65b4e1bbdbe09378a1ff15e595f8ab3ae016d2faeb53aee
6
+ metadata.gz: c85149c357c98f822dfe057e096094613f47f2ce31c039757798641145b158550b8ca43cd3e261fa655b769c850ddc08a8a333aaca24193d3c18c1392d4fd526
7
+ data.tar.gz: fdf5867043ad025ee8080f968f4d0c11df8b4fd2fd95c31bc2f68c34e0b79865a4ae5e7b700876185356c0f03aba9719bcd5cfe68cb1380a56a144b393f0d101
@@ -24,7 +24,7 @@ module Imap::Backup
24
24
  configured =
25
25
  case
26
26
  when account.folders&.any?
27
- account.folders.map { |af| af[:name] }
27
+ account.folders
28
28
  when account.folder_blacklist
29
29
  []
30
30
  else
@@ -1,6 +1,8 @@
1
1
  require "forwardable"
2
+ require "logger"
2
3
  require "net/imap"
3
4
 
5
+ require "imap/backup/logger"
4
6
  require "retry_on_error"
5
7
 
6
8
  module Imap; end
@@ -31,12 +33,19 @@ module Imap::Backup
31
33
  end
32
34
 
33
35
  def exist?
36
+ previous_level = Imap::Backup::Logger.logger.level
37
+ previous_debug = Net::IMAP.debug
38
+ Imap::Backup::Logger.logger.level = ::Logger::Severity::UNKNOWN
39
+ Net::IMAP.debug = false
34
40
  retry_on_error(errors: EXAMINE_RETRY_CLASSES) do
35
41
  examine
36
42
  end
37
43
  true
38
44
  rescue FolderNotFound
39
45
  false
46
+ ensure
47
+ Imap::Backup::Logger.logger.level = previous_level
48
+ Net::IMAP.debug = previous_debug
40
49
  end
41
50
 
42
51
  def create
@@ -68,7 +77,7 @@ module Imap::Backup
68
77
  'This is caused by `@responses["SEARCH"] being unset/undefined. ' \
69
78
  "Among others, Apple Mail servers send empty responses when " \
70
79
  "folders are empty, causing this error."
71
- Logger.logger.warn message
80
+ Imap::Backup::Logger.logger.warn message
72
81
  []
73
82
  end
74
83
 
@@ -150,7 +159,8 @@ module Imap::Backup
150
159
  def examine
151
160
  client.examine(utf7_encoded_name)
152
161
  rescue Net::IMAP::NoResponseError
153
- Logger.logger.warn "Folder '#{name}' does not exist on server"
162
+ Imap::Backup::Logger.logger.warn "Folder '#{name}' does not exist on server"
163
+ Imap::Backup::Logger.logger.warn caller.join("\n")
154
164
  raise FolderNotFound, "Folder '#{name}' does not exist on server"
155
165
  end
156
166
 
@@ -1,6 +1,7 @@
1
1
  require "thor"
2
2
 
3
3
  require "imap/backup/configuration"
4
+ require "imap/backup/configuration_not_found"
4
5
 
5
6
  module Imap; end
6
7
 
@@ -50,8 +51,13 @@ module Imap::Backup
50
51
  method_option(
51
52
  "verbose",
52
53
  type: :boolean,
53
- desc: "increase the amount of logging",
54
- aliases: ["-v"]
54
+ desc:
55
+ "increase the amount of logging. " \
56
+ "Without this option, the program gives minimal output. " \
57
+ "Using this option once gives more detailed output. " \
58
+ "Whereas, using this option twice also shows all IMAP network calls",
59
+ aliases: ["-v"],
60
+ repeatable: true
55
61
  )
56
62
  end
57
63
  end
@@ -1,6 +1,7 @@
1
1
  require "thor"
2
2
 
3
3
  require "imap/backup/logger"
4
+ require "imap/backup/version"
4
5
 
5
6
  module Imap; end
6
7
 
@@ -19,8 +20,6 @@ module Imap::Backup
19
20
 
20
21
  include Helpers
21
22
 
22
- VERSION_ARGUMENTS = %w(-v --version).freeze
23
-
24
23
  NAMESPACE_CONFIGURATION_DESCRIPTION = <<~DESC.freeze
25
24
  Some IMAP servers use namespaces (i.e. prefixes like "INBOX"),
26
25
  while others, while others concatenate the names of subfolders
@@ -44,9 +43,8 @@ module Imap::Backup
44
43
 
45
44
  default_task :backup
46
45
 
47
- def self.start(*args)
48
- version_argument = ARGV & VERSION_ARGUMENTS
49
- if version_argument.any?
46
+ def self.start(args)
47
+ if args.include?("--version")
50
48
  new.version
51
49
  exit 0
52
50
  end
@@ -171,6 +169,10 @@ module Imap::Backup
171
169
  a new file is created alongside the normal backup files (.imap and .mbox)
172
170
  This file has a '.mirror' extension. This file contains a mapping of
173
171
  the known UIDs on the source account to those on the destination account.
172
+
173
+ Some configuration may be necessary, as follows:
174
+
175
+ #{NAMESPACE_CONFIGURATION_DESCRIPTION}
174
176
  DESC
175
177
  config_option
176
178
  quiet_option
@@ -11,7 +11,8 @@ module Imap; end
11
11
  module Imap::Backup
12
12
  class Configuration
13
13
  CONFIGURATION_DIRECTORY = File.expand_path("~/.imap-backup")
14
- VERSION = "2.1".freeze
14
+ VERSION_2_1 = "2.1".freeze
15
+ VERSION = "2.2".freeze
15
16
  DEFAULT_STRATEGY = "delay_metadata".freeze
16
17
  DOWNLOAD_STRATEGIES = [
17
18
  {key: "direct", description: "write straight to disk"},
@@ -81,7 +82,7 @@ module Imap::Backup
81
82
  inject_global_attributes(accounts)
82
83
  end
83
84
 
84
- def download_strategy_modified
85
+ def download_strategy_modified?
85
86
  ensure_loaded!
86
87
 
87
88
  @download_strategy_modified
@@ -90,7 +91,7 @@ module Imap::Backup
90
91
  def modified?
91
92
  ensure_loaded!
92
93
 
93
- return true if download_strategy_modified
94
+ return true if download_strategy_modified?
94
95
 
95
96
  accounts.any? { |a| a.modified? || a.marked_for_deletion? }
96
97
  end
@@ -121,12 +122,30 @@ module Imap::Backup
121
122
  else
122
123
  DEFAULT_STRATEGY
123
124
  end
124
- data
125
+ if data[:version] == VERSION_2_1
126
+ dehashify_folders(data)
127
+ else
128
+ data
129
+ end
125
130
  else
126
131
  {accounts: [], download_strategy: DEFAULT_STRATEGY}
127
132
  end
128
133
  end
129
134
 
135
+ def dehashify_folders(data)
136
+ data[:version] = VERSION
137
+
138
+ data[:accounts].each do |account|
139
+ next if !account.key?(:folders)
140
+
141
+ folders = account[:folders]
142
+ names = folders.map { |f| f[:name] }
143
+ account[:folders] = names
144
+ end
145
+
146
+ data
147
+ end
148
+
130
149
  def remove_modified_flags
131
150
  @download_strategy_modified = false
132
151
  accounts.each(&:clear_changes)
@@ -1,3 +1,5 @@
1
+ require "net/imap"
2
+
1
3
  module Imap; end
2
4
 
3
5
  module Imap::Backup
@@ -16,19 +16,20 @@ module Imap::Backup
16
16
  def self.setup_logging(options = {})
17
17
  copy = options.clone
18
18
  quiet = copy.delete(:quiet)
19
- verbose = copy.delete(:verbose)
19
+ verbose = copy.delete(:verbose) || []
20
+ verbose_count = count(verbose)
20
21
  level =
21
22
  case
22
23
  when quiet
23
24
  ::Logger::Severity::UNKNOWN
24
- when verbose
25
+ when verbose_count >= 2
25
26
  ::Logger::Severity::DEBUG
26
27
  else
27
28
  ::Logger::Severity::INFO
28
29
  end
29
30
  logger.level = level
30
- debug = level == ::Logger::Severity::DEBUG
31
- Net::IMAP.debug = debug
31
+
32
+ Net::IMAP.debug = (verbose_count >= 3)
32
33
 
33
34
  copy
34
35
  end
@@ -43,6 +44,10 @@ module Imap::Backup
43
44
  $stderr = previous_stderr
44
45
  end
45
46
 
47
+ def self.count(verbose)
48
+ verbose.reduce(1) { |acc, v| acc + (v ? 1 : -1) }
49
+ end
50
+
46
51
  attr_reader :logger
47
52
 
48
53
  def initialize
@@ -78,7 +78,7 @@ module Imap::Backup
78
78
  list =
79
79
  case
80
80
  when items.any?
81
- items.map { |f| f[:name] }.join(", ")
81
+ items.join(", ")
82
82
  when !account.folder_blacklist
83
83
  "(all folders)"
84
84
  else
@@ -1,3 +1,5 @@
1
+ require "net/imap"
2
+
1
3
  module Imap; end
2
4
 
3
5
  module Imap::Backup
@@ -63,18 +63,18 @@ module Imap::Backup
63
63
  config_folders = account.folders
64
64
  return false if config_folders.nil?
65
65
 
66
- config_folders.find { |f| f[:name] == folder_name }
66
+ config_folders.find { |f| f == folder_name }
67
67
  end
68
68
 
69
69
  def remove_missing
70
70
  removed = []
71
71
  config_folders = []
72
72
  account.folders.each do |f|
73
- found = folder_names.find { |folder| folder == f[:name] }
73
+ found = folder_names.find { |folder| folder == f }
74
74
  if found
75
75
  config_folders << f
76
76
  else
77
- removed << f[:name]
77
+ removed << f
78
78
  end
79
79
  end
80
80
 
@@ -91,11 +91,11 @@ module Imap::Backup
91
91
 
92
92
  def toggle_selection(folder_name)
93
93
  if selected?(folder_name)
94
- new_list = account.folders.reject { |f| f[:name] == folder_name }
94
+ new_list = account.folders.reject { |f| f == folder_name }
95
95
  account.folders = new_list
96
96
  else
97
97
  existing = account.folders || []
98
- account.folders = existing + [{name: folder_name}]
98
+ account.folders = existing << folder_name
99
99
  end
100
100
  end
101
101
 
@@ -42,7 +42,7 @@ module Imap::Backup
42
42
  def change_download_strategy(menu)
43
43
  strategies = Imap::Backup::Configuration::DOWNLOAD_STRATEGIES
44
44
  current = strategies.find { |s| s[:key] == config.download_strategy }
45
- changed = config.download_strategy_modified ? " *" : ""
45
+ changed = config.download_strategy_modified? ? " *" : ""
46
46
  menu.choice("change download strategy (currently: '#{current[:description]}')#{changed}") do
47
47
  DownloadStrategyChooser.new(config: config).run
48
48
  end
@@ -76,7 +76,7 @@ module Imap::Backup
76
76
  end
77
77
 
78
78
  def modify_global_options(menu)
79
- changed = config.modified? ? " *" : ""
79
+ changed = config.download_strategy_modified? ? " *" : ""
80
80
  menu.choice("modify global options#{changed}") do
81
81
  GlobalOptions.new(config: config).run
82
82
  end
@@ -2,7 +2,7 @@ module Imap; end
2
2
 
3
3
  module Imap::Backup
4
4
  MAJOR = 13
5
- MINOR = 3
5
+ MINOR = 4
6
6
  REVISION = 0
7
7
  PRE = nil
8
8
  VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
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: 13.3.0
4
+ version: 13.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-06 00:00:00.000000000 Z
11
+ date: 2023-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline