imap-backup 9.1.1 → 9.2.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: f5cf8072ca8c7a95ca74edc961352099b468a287e846c71c0243d5c2fc285e17
4
- data.tar.gz: 8b66b63ed93044a9fe019ce5af838f165589a9f7b1eebe0751cc804891dacab2
3
+ metadata.gz: 2817e61358b848f7dbef08e1a16562def8cd364e66d317e4dac56c1f5e62f958
4
+ data.tar.gz: ec0e2d2963e863b204b0529ca3746492703486e8f77a9e7c08bc301b203249de
5
5
  SHA512:
6
- metadata.gz: 79a410fe6b307969a27cafed38cd145951016c86c45f62033b91dd6b9df289993f4e134c42bd6ddabbb8b4a523534fdad18ea4b71cd40aa6656375c750c4aaf6
7
- data.tar.gz: baf5eb4583afe8263f54cede96ad308f1b0ce507987b10adfba337eb899ecc456f22c9895cb18805a87ef486ba3712f150af17ca21beed5160081b3eb4c07ffe
6
+ metadata.gz: 66871fce3faebbcbd87737fef230803b46f32025b28753fe4f83813e652ef14817fce302da0570000f0d0ecb582862589a84f535a94aa1fa7cc1578eaf30591c
7
+ data.tar.gz: 274cfc47767322e31eb1e7206c3d1d449b2098ba1a65073c80aa5010c06924abfc7a952aeace01436715a7f95599503d86bcecbbdf210f7c8b5529bf7bee4fdf
@@ -2,7 +2,7 @@ require "logger"
2
2
  require "singleton"
3
3
 
4
4
  require "imap/backup/configuration"
5
- require "imap/backup/sanitizer"
5
+ require "text/sanitizer"
6
6
 
7
7
  module Imap::Backup
8
8
  class Logger
@@ -33,7 +33,7 @@ module Imap::Backup
33
33
  end
34
34
 
35
35
  def self.sanitize_stderr
36
- sanitizer = Sanitizer.new($stdout)
36
+ sanitizer = Text::Sanitizer.new($stdout)
37
37
  previous_stderr = $stderr
38
38
  $stderr = sanitizer
39
39
  yield
@@ -0,0 +1,25 @@
1
+ module Imap::Backup
2
+ class Naming
3
+ INVALID_FILENAME_CHARACTERS = ":%;".freeze
4
+ INVALID_FILENAME_CHARACTER_MATCH = /([#{INVALID_FILENAME_CHARACTERS}])/.freeze
5
+
6
+ # `*_path` functions treat `/` as an acceptable character
7
+ def self.to_local_path(name)
8
+ name.gsub(INVALID_FILENAME_CHARACTER_MATCH) do |character|
9
+ hex =
10
+ character.
11
+ codepoints[0].
12
+ to_s(16)
13
+ "%#{hex};"
14
+ end
15
+ end
16
+
17
+ def self.from_local_path(name)
18
+ name.gsub(/%(.*?);/) do
19
+ ::Regexp.last_match(1).
20
+ to_i(16).
21
+ chr("UTF-8")
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,4 +1,6 @@
1
1
  module Imap::Backup
2
+ class Serializer; end
3
+
2
4
  class Serializer::Appender
3
5
  attr_reader :imap
4
6
  attr_reader :folder
@@ -1,6 +1,7 @@
1
1
  require "forwardable"
2
2
 
3
3
  require "email/mboxrd/message"
4
+ require "imap/backup/naming"
4
5
  require "imap/backup/serializer/appender"
5
6
  require "imap/backup/serializer/imap"
6
7
  require "imap/backup/serializer/message"
@@ -72,7 +73,7 @@ module Imap::Backup
72
73
  def append(uid, message, flags)
73
74
  validate!
74
75
 
75
- appender = Serializer::Appender.new(folder: folder, imap: imap, mbox: mbox)
76
+ appender = Serializer::Appender.new(folder: sanitized, imap: imap, mbox: mbox)
76
77
  appender.run(uid: uid, message: message, flags: flags)
77
78
  end
78
79
 
@@ -116,14 +117,16 @@ module Imap::Backup
116
117
  end
117
118
 
118
119
  def folder_path
119
- self.class.folder_path_for(path: path, folder: folder)
120
+ self.class.folder_path_for(path: path, folder: sanitized)
120
121
  end
121
122
 
122
123
  private
123
124
 
124
125
  def rename(new_name)
125
126
  destination = self.class.folder_path_for(path: path, folder: new_name)
126
- ensure_containing_directory(new_name)
127
+ relative = File.dirname(new_name)
128
+ directory = Serializer::Directory.new(path, relative)
129
+ directory.ensure_exists
127
130
  mbox.rename destination
128
131
  imap.rename destination
129
132
  end
@@ -136,7 +139,7 @@ module Imap::Backup
136
139
  def mbox
137
140
  @mbox ||=
138
141
  begin
139
- ensure_containing_directory(folder)
142
+ ensure_containing_directory
140
143
  Serializer::Mbox.new(folder_path)
141
144
  end
142
145
  end
@@ -144,11 +147,15 @@ module Imap::Backup
144
147
  def imap
145
148
  @imap ||=
146
149
  begin
147
- ensure_containing_directory(folder)
150
+ ensure_containing_directory
148
151
  Serializer::Imap.new(folder_path)
149
152
  end
150
153
  end
151
154
 
155
+ def sanitized
156
+ @sanitized ||= Naming.to_local_path(folder)
157
+ end
158
+
152
159
  def optionally_migrate2to3
153
160
  migrator = Version2Migrator.new(folder_path)
154
161
  return if !migrator.required?
@@ -162,8 +169,8 @@ module Imap::Backup
162
169
  migrator.run
163
170
  end
164
171
 
165
- def ensure_containing_directory(folder)
166
- relative = File.dirname(folder)
172
+ def ensure_containing_directory
173
+ relative = File.dirname(sanitized)
167
174
  directory = Serializer::Directory.new(path, relative)
168
175
  directory.ensure_exists
169
176
  end
@@ -2,8 +2,8 @@ module Imap; end
2
2
 
3
3
  module Imap::Backup
4
4
  MAJOR = 9
5
- MINOR = 1
6
- REVISION = 1
5
+ MINOR = 2
6
+ REVISION = 0
7
7
  PRE = nil
8
8
  VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
9
9
  end
@@ -0,0 +1,46 @@
1
+ require "forwardable"
2
+
3
+ module Text; end
4
+
5
+ class Text::Sanitizer
6
+ extend Forwardable
7
+
8
+ attr_reader :output
9
+
10
+ delegate puts: :output
11
+ delegate write: :output
12
+
13
+ def initialize(output)
14
+ @output = output
15
+ @current = ""
16
+ end
17
+
18
+ def print(*args)
19
+ @current << args.join
20
+ loop do
21
+ line, newline, rest = @current.partition("\n")
22
+ break if newline != "\n"
23
+
24
+ clean = sanitize(line)
25
+ output.puts clean
26
+ @current = rest
27
+ end
28
+ end
29
+
30
+ def flush
31
+ return if @current == ""
32
+
33
+ clean = sanitize(@current)
34
+ output.puts clean
35
+ end
36
+
37
+ private
38
+
39
+ def sanitize(text)
40
+ # Hide password in Net::IMAP debug output
41
+ text.gsub(
42
+ /\A(C: RUBY\d+ LOGIN \S+) \S+/,
43
+ "\\1 [PASSWORD REDACTED]"
44
+ )
45
+ end
46
+ end
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: 9.1.1
4
+ version: 9.2.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-02-19 00:00:00.000000000 Z
11
+ date: 2023-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -258,7 +258,7 @@ files:
258
258
  - lib/imap/backup/migrator.rb
259
259
  - lib/imap/backup/mirror.rb
260
260
  - lib/imap/backup/mirror/map.rb
261
- - lib/imap/backup/sanitizer.rb
261
+ - lib/imap/backup/naming.rb
262
262
  - lib/imap/backup/serializer.rb
263
263
  - lib/imap/backup/serializer/appender.rb
264
264
  - lib/imap/backup/serializer/directory.rb
@@ -282,6 +282,7 @@ files:
282
282
  - lib/imap/backup/utils.rb
283
283
  - lib/imap/backup/version.rb
284
284
  - lib/retry_on_error.rb
285
+ - lib/text/sanitizer.rb
285
286
  homepage: https://github.com/joeyates/imap-backup
286
287
  licenses:
287
288
  - MIT
@@ -1,46 +0,0 @@
1
- require "forwardable"
2
-
3
- module Imap::Backup
4
- class Sanitizer
5
- extend Forwardable
6
-
7
- attr_reader :output
8
-
9
- delegate puts: :output
10
- delegate write: :output
11
-
12
- def initialize(output)
13
- @output = output
14
- @current = ""
15
- end
16
-
17
- def print(*args)
18
- @current << args.join
19
- loop do
20
- line, newline, rest = @current.partition("\n")
21
- break if newline != "\n"
22
-
23
- clean = sanitize(line)
24
- output.puts clean
25
- @current = rest
26
- end
27
- end
28
-
29
- def flush
30
- return if @current == ""
31
-
32
- clean = sanitize(@current)
33
- output.puts clean
34
- end
35
-
36
- private
37
-
38
- def sanitize(text)
39
- # Hide password in Net::IMAP debug output
40
- text.gsub(
41
- /\A(C: RUBY\d+ LOGIN \S+) \S+/,
42
- "\\1 [PASSWORD REDACTED]"
43
- )
44
- end
45
- end
46
- end