imap-backup 15.0.2 → 15.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de4f5bfc1260430435d380fd3fa6c315efad4ef503b0429bce041615d3ae2e10
4
- data.tar.gz: 3c1541e30cb01d1ecd6da9372e79b8e8c71f119eee5a11770bef76b90e89e037
3
+ metadata.gz: 9a391a879278c1f286d5756ebfc3e77c39acda7e5ec9441776e30fb720251cee
4
+ data.tar.gz: bcd9c851be504e9c775a241a21e1ecc708baf4f05ff7fe42160e7468c10ca3f3
5
5
  SHA512:
6
- metadata.gz: 25aa565a7860560958b59c5f88f67b470128405acc15fc67fe3683152d0ea9c63d8787287f006249a22b26a88d92425bed653254126ef92259ea85022b33efcb
7
- data.tar.gz: 54d8df69cef34dcafd3ba97f63f202b0f00e2306f8e12c4ea7329dfae5028e42e9a4050630fae2d03131048aa3c70e90ee7bb8a49a1388084bd136ad3e0ce973
6
+ metadata.gz: 289206eb94864c60e82b35db46e9f5d7531f73692bd10c02d407e800c77aa00597a149cfc7d05f749abe8d8189745a4b9b5a184fd8df472ea13d646fe8065105
7
+ data.tar.gz: b38e2740e7862fc92175a684dfd93a3b176ed3b8e56ae2ee6438490577ab54002238ecdf4d6f1449d0c557ca5996eea1b81f6aabbb6aaaa47ad455796b431903
data/docs/performance.md CHANGED
@@ -1,14 +1,12 @@
1
- # Performace
1
+ # Performance
2
2
 
3
- The two performance-related settings are "Download strategy",
4
- which is a global setting,
5
- and "Multi-fetch size", which is an Account-level setting.
3
+ The two performance-related settings are "Download strategy", which is a global setting, and "Multi-fetch size", which is an Account-level setting.
6
4
 
7
5
  As with all performance tweaks, there are trade-offs.
8
6
 
9
7
  # Overview
10
8
 
11
- The defaults, which suit most machines and plays nice with servers is:
9
+ The defaults, which suit most machines and play nice with servers are:
12
10
 
13
11
  * Download strategy: "delay writing metadata",
14
12
  * Multi-fetch size: 1.
@@ -18,7 +16,7 @@ a small virtual server or Raspberry Pi
18
16
  to run your backups, you can change "Download strategy".
19
17
 
20
18
  If your email provider supports it,
21
- and you don't have tight memeory limits,
19
+ and you don't have tight memory limits,
22
20
  increase "Multi-fetch size" for faster backups.
23
21
 
24
22
  # Delay download writes
@@ -45,7 +43,7 @@ By default, during backup, each message is downloaded one-by-one.
45
43
  Using this setting, you can download chunks of emails at a time,
46
44
  potentially speeding up the process.
47
45
 
48
- Using multi-fetch *will* mean that the backup process will use
46
+ Using multi-fetch mean that the backup process *will* use
49
47
  more memory - equivalent to the size of the groups of messages
50
48
  that are downloaded.
51
49
 
@@ -18,27 +18,33 @@ module Imap::Backup
18
18
  # Runs the backup
19
19
  # @return [void]
20
20
  def run
21
- Logger.logger.info "Running backup of account: #{account.username}"
21
+ Logger.logger.info "Running backup of account '#{account.username}'"
22
22
  # start the connection so we get logging messages in the right order
23
23
  account.client.login
24
24
 
25
- Account::FolderEnsurer.new(account: account).run
26
- Account::LocalOnlyFolderDeleter.new(account: account).run if account.mirror_mode
25
+ run_pre_backup_tasks
27
26
  backup_folders = Account::BackupFolders.new(
28
27
  client: account.client, account: account
29
- )
28
+ ).to_a
30
29
  if backup_folders.none?
31
- Logger.logger.warn "Account #{account.username}: No folders found to backup"
30
+ Logger.logger.warn "No folders found to backup for account '#{account.username}'"
32
31
  return
33
32
  end
33
+ Logger.logger.debug "Starting backup of #{backup_folders.count} folders"
34
34
  backup_folders.each do |folder|
35
35
  Account::FolderBackup.new(account: account, folder: folder, refresh: refresh).run
36
36
  end
37
+ Logger.logger.debug "Backup of account '#{account.username}' complete"
37
38
  end
38
39
 
39
40
  private
40
41
 
41
42
  attr_reader :account
42
43
  attr_reader :refresh
44
+
45
+ def run_pre_backup_tasks
46
+ Account::FolderEnsurer.new(account: account).run
47
+ Account::LocalOnlyFolderDeleter.new(account: account).run if account.mirror_mode
48
+ end
43
49
  end
44
50
  end
@@ -31,19 +31,15 @@ module Imap::Backup
31
31
 
32
32
  # @raise any error that occurs more than 10 times
33
33
  def exist?
34
- previous_level = Imap::Backup::Logger.logger.level
35
- previous_debug = Net::IMAP.debug
36
- Imap::Backup::Logger.logger.level = ::Logger::Severity::UNKNOWN
37
- Net::IMAP.debug = false
34
+ Logger.logger.debug "Checking whether folder '#{name}' exists"
38
35
  retry_on_error(errors: EXAMINE_RETRY_CLASSES) do
39
36
  examine
40
37
  end
38
+ Logger.logger.debug "Folder '#{name}' exists"
41
39
  true
42
40
  rescue FolderNotFound
41
+ Logger.logger.debug "Folder '#{name}' does not exist"
43
42
  false
44
- ensure
45
- Imap::Backup::Logger.logger.level = previous_level
46
- Net::IMAP.debug = previous_debug
47
43
  end
48
44
 
49
45
  # Creates the folder on the server
@@ -69,8 +65,11 @@ module Imap::Backup
69
65
  # @raise any error that occurs more than 10 times
70
66
  # @return [Array<Integer>] the folders message UIDs
71
67
  def uids
68
+ Logger.logger.debug "Fetching UIDs for folder '#{name}'"
72
69
  examine
73
- client.uid_search(["ALL"]).sort
70
+ result = client.uid_search(["ALL"]).sort
71
+ Logger.logger.debug "#{result.count} UIDs found for folder '#{name}'"
72
+ result
74
73
  rescue FolderNotFound
75
74
  []
76
75
  rescue NoMethodError
@@ -22,11 +22,11 @@ module Imap::Backup
22
22
  # @raise [RuntimeError] if the configured download strategy is incorrect
23
23
  # @return [void]
24
24
  def run
25
+ Logger.logger.debug "Running backup for folder '#{folder.name}'"
26
+
25
27
  folder_ok = folder_ok?
26
28
  return if !folder_ok
27
29
 
28
- Logger.logger.debug "[#{folder.name}] running backup"
29
-
30
30
  serializer.apply_uid_validity(folder.uid_validity)
31
31
 
32
32
  serializer.transaction do
@@ -36,6 +36,7 @@ module Imap::Backup
36
36
  # After the transaction the serializer will have any appended messages
37
37
  # so we can check differences between the server and the local backup
38
38
  LocalOnlyMessageDeleter.new(folder, raw_serializer).run if account.mirror_mode
39
+ Logger.logger.debug "Backup for folder '#{folder.name}' complete"
39
40
  end
40
41
 
41
42
  private
@@ -46,10 +47,13 @@ module Imap::Backup
46
47
 
47
48
  def folder_ok?
48
49
  begin
49
- return false if !folder.exist?
50
+ if !folder.exist?
51
+ Logger.logger.info "Skipping backup for folder '#{folder.name}' as it does not exist"
52
+ return false
53
+ end
50
54
  rescue Encoding::UndefinedConversionError
51
55
  message = "Skipping backup for '#{folder.name}' " \
52
- "as it is not UTF-7 encoded correctly"
56
+ "as it's name is not UTF-7 encoded correctly"
53
57
  Logger.logger.info message
54
58
  return false
55
59
  end
@@ -24,6 +24,7 @@ module Imap::Backup
24
24
  # @return [void]
25
25
  no_commands do
26
26
  def run
27
+ Logger.logger.debug "Loading configuration"
27
28
  config = load_config(**options)
28
29
  exit_code = nil
29
30
  accounts = requested_accounts(config)
@@ -31,6 +32,7 @@ module Imap::Backup
31
32
  Logger.logger.warn "No matching accounts found to backup"
32
33
  return
33
34
  end
35
+ Logger.logger.debug "Starting backup of #{accounts.count} accounts"
34
36
  accounts.each do |account|
35
37
  backup = Account::Backup.new(account: account, refresh: refresh)
36
38
  backup.run
@@ -43,6 +45,7 @@ module Imap::Backup
43
45
  Logger.logger.error message
44
46
  next
45
47
  end
48
+ Logger.logger.debug "Backup complete"
46
49
  exit(exit_code) if exit_code
47
50
  end
48
51
  end
@@ -88,7 +88,7 @@ module Imap::Backup
88
88
  "password-environment-variable",
89
89
  type: :string,
90
90
  desc: "an environment variable that is set to your password",
91
- aliases: ["-e"]
91
+ aliases: ["-w"]
92
92
  )
93
93
  method_option(
94
94
  "password-file",
@@ -137,7 +137,7 @@ module Imap::Backup
137
137
  "mirror",
138
138
  type: :boolean,
139
139
  desc: "if this option is given, " \
140
- "emails that are removed from the server " \
140
+ "existing backed-up emails that are no longer on the server " \
141
141
  "will be removed from the local backup.",
142
142
  aliases: ["-m"]
143
143
  )
@@ -27,6 +27,7 @@ module Imap::Backup
27
27
  # @return [Array<String>] the account folders
28
28
  def list
29
29
  root = provider_root
30
+ Logger.logger.debug "Listing all account folders"
30
31
  mailbox_lists = imap.list(root, "*")
31
32
 
32
33
  return [] if mailbox_lists.nil?
@@ -105,7 +106,9 @@ module Imap::Backup
105
106
  # in the reference.
106
107
  def provider_root
107
108
  @provider_root ||= begin
109
+ Logger.logger.debug "Fetching provider root"
108
110
  root_info = imap.list("", "")[0]
111
+ Logger.logger.debug "Provider root is '#{root_info.name}'"
109
112
  root_info.name
110
113
  end
111
114
  end
@@ -19,7 +19,19 @@ module Imap::Backup
19
19
  # Runs the downloader
20
20
  # @return [void]
21
21
  def run
22
- info("#{uids.count} new messages") if uids.any?
22
+ debug("#{serializer_uids.count} already messages already downloaded")
23
+ debug("#{folder_uids.count} messages on server")
24
+ local_only_count = (serializer_uids - folder_uids).count
25
+ if local_only_count.positive?
26
+ debug("#{local_only_count} downloaded messages no longer on server")
27
+ end
28
+
29
+ if uids.none?
30
+ debug("no new messages on server — skipping")
31
+ return
32
+ end
33
+
34
+ info("#{uids.count} new messages")
23
35
 
24
36
  uids.each_slice(multi_fetch_size).with_index do |block, i|
25
37
  multifetch_failed = download_block(block, i)
@@ -62,8 +74,8 @@ module Imap::Backup
62
74
  end
63
75
  if uids_and_bodies.nil?
64
76
  if multi_fetch_size > 1
65
- uids = block.join(", ")
66
- debug("Multi fetch failed for UIDs #{uids}, switching to single fetches")
77
+ uid_list = block.join(", ")
78
+ debug("Multi fetch failed for UIDs #{uid_list}, switching to single fetches")
67
79
  return true
68
80
  else
69
81
  debug("Fetch failed for UID #{block[0]} - skipping")
@@ -96,8 +108,16 @@ module Imap::Backup
96
108
  error(e)
97
109
  end
98
110
 
111
+ def folder_uids
112
+ @folder_uids ||= folder.uids
113
+ end
114
+
115
+ def serializer_uids
116
+ @serializer_uids ||= serializer.uids
117
+ end
118
+
99
119
  def uids
100
- @uids ||= folder.uids - serializer.uids
120
+ @uids ||= folder_uids - serializer_uids
101
121
  end
102
122
 
103
123
  def debug(message)
@@ -4,9 +4,9 @@ module Imap::Backup
4
4
  # @private
5
5
  MAJOR = 15
6
6
  # @private
7
- MINOR = 0
7
+ MINOR = 1
8
8
  # @private
9
- REVISION = 2
9
+ REVISION = 3
10
10
  # @private
11
11
  PRE = nil
12
12
  # The application version
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 15.0.2
4
+ version: 15.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Yates
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-10 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: highline
@@ -219,7 +218,6 @@ licenses:
219
218
  - MIT
220
219
  metadata:
221
220
  rubygems_mfa_required: 'true'
222
- post_install_message:
223
221
  rdoc_options: []
224
222
  require_paths:
225
223
  - lib
@@ -234,8 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
232
  - !ruby/object:Gem::Version
235
233
  version: '0'
236
234
  requirements: []
237
- rubygems_version: 3.5.3
238
- signing_key:
235
+ rubygems_version: 3.6.7
239
236
  specification_version: 4
240
237
  summary: Backup GMail (or other IMAP) accounts to disk
241
238
  test_files: []