net-imap 0.4.16 → 0.4.18

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: eb20811050c485f7fcde01bb24dbe455026b45cc463efe39353a3f186312a5d5
4
- data.tar.gz: 1290933be2c606cb299c75acc7ba59aa3ecdbcad245e776981eb2eb49d3289f3
3
+ metadata.gz: f71a5476fad0d1bbe6dd52a510fa083ef6b35cb98f27af536a5991ebe9f31244
4
+ data.tar.gz: 10082ff774cfccf2b0b43c58cf62bdb99b3e2e75cf7ff7fcb9c508cde8dc33ed
5
5
  SHA512:
6
- metadata.gz: 857dfd2863abedf53c6adf874a8d6883ea93de91cb01bd0c3ec60ca2279f86e1ae41ddedaccd1329490dddb6dabdce59cddf22699c0792085a5fba2a76184647
7
- data.tar.gz: 0766bbf7514aa1c293b18575c47bf02f5eff1c62b69c8cda432aba35d72572607d60588e45ab78a25e5df7f8d7df2fe5c90d965f580c8178171554151ab0c4a0
6
+ metadata.gz: c98013c4ad6493bb0e455cced96388e35214567eb0359085e5023beffc9d748472ff729dc70718a3e66ba86a78e5a1d5de803fc68e5012a6da852e57f951398c
7
+ data.tar.gz: bd5b766443689dad66eb1caf4479763f8181d38e64b3db7fdf415b277d27721fda9d4ce634e4638ab4f0860e3a82f63a37581830e81a617fe08baaff07262694
@@ -7,10 +7,10 @@ require_relative "config/attr_type_coercion"
7
7
  module Net
8
8
  class IMAP
9
9
 
10
- # Net::IMAP::Config stores configuration options for Net::IMAP clients.
11
- # The global configuration can be seen at either Net::IMAP.config or
12
- # Net::IMAP::Config.global, and the client-specific configuration can be
13
- # seen at Net::IMAP#config.
10
+ # Net::IMAP::Config <em>(available since +v0.4.13+)</em> stores
11
+ # configuration options for Net::IMAP clients. The global configuration can
12
+ # be seen at either Net::IMAP.config or Net::IMAP::Config.global, and the
13
+ # client-specific configuration can be seen at Net::IMAP#config.
14
14
  #
15
15
  # When creating a new client, all unhandled keyword arguments to
16
16
  # Net::IMAP.new are delegated to Config.new. Every client has its own
@@ -128,7 +128,7 @@ module Net
128
128
  # The global config object. Also available from Net::IMAP.config.
129
129
  def self.global; @global if defined?(@global) end
130
130
 
131
- # A hash of hard-coded configurations, indexed by version number.
131
+ # A hash of hard-coded configurations, indexed by version number or name.
132
132
  def self.version_defaults; @version_defaults end
133
133
  @version_defaults = {}
134
134
 
@@ -172,9 +172,16 @@ module Net
172
172
  include AttrInheritance
173
173
  include AttrTypeCoercion
174
174
 
175
- # The debug mode (boolean)
175
+ # The debug mode (boolean). The default value is +false+.
176
176
  #
177
- # The default value is +false+.
177
+ # When #debug is +true+:
178
+ # * Data sent to and received from the server will be logged.
179
+ # * ResponseParser will print warnings with extra detail for parse
180
+ # errors. _This may include recoverable errors._
181
+ # * ResponseParser makes extra assertions.
182
+ #
183
+ # *NOTE:* Versioned default configs inherit #debug from Config.global, and
184
+ # #load_defaults will not override #debug.
178
185
  attr_accessor :debug, type: :boolean
179
186
 
180
187
  # method: debug?
@@ -200,34 +207,61 @@ module Net
200
207
  # The default value is +5+ seconds.
201
208
  attr_accessor :idle_response_timeout, type: Integer
202
209
 
203
- # :markup: markdown
204
- #
205
210
  # Whether to use the +SASL-IR+ extension when the server and \SASL
206
- # mechanism both support it.
211
+ # mechanism both support it. Can be overridden by the +sasl_ir+ keyword
212
+ # parameter to Net::IMAP#authenticate.
213
+ #
214
+ # <em>(Support for +SASL-IR+ was added in +v0.4.0+.)</em>
215
+ #
216
+ # ==== Valid options
207
217
  #
208
- # See Net::IMAP#authenticate.
218
+ # [+false+ <em>(original behavior, before support was added)</em>]
219
+ # Do not use +SASL-IR+, even when it is supported by the server and the
220
+ # mechanism.
209
221
  #
210
- # | Starting with version | The default value is |
211
- # |-----------------------|------------------------------------------|
212
- # | _original_ | +false+ <em>(extension unsupported)</em> |
213
- # | v0.4 | +true+ <em>(support added)</em> |
222
+ # [+true+ <em>(default since +v0.4+)</em>]
223
+ # Use +SASL-IR+ when it is supported by the server and the mechanism.
214
224
  attr_accessor :sasl_ir, type: :boolean
215
225
 
216
- # :markup: markdown
226
+
227
+ # Controls the behavior of Net::IMAP#responses when called without any
228
+ # arguments (+type+ or +block+).
229
+ #
230
+ # ==== Valid options
231
+ #
232
+ # [+:silence_deprecation_warning+ <em>(original behavior)</em>]
233
+ # Returns the mutable responses hash (without any warnings).
234
+ # <em>This is not thread-safe.</em>
217
235
  #
218
- # Controls the behavior of Net::IMAP#responses when called without a
219
- # block. Valid options are `:warn`, `:raise`, or
220
- # `:silence_deprecation_warning`.
236
+ # [+:warn+ <em>(default since +v0.5+)</em>]
237
+ # Prints a warning and returns the mutable responses hash.
238
+ # <em>This is not thread-safe.</em>
221
239
  #
222
- # | Starting with version | The default value is |
223
- # |-------------------------|--------------------------------|
224
- # | v0.4.13 | +:silence_deprecation_warning+ |
225
- # | v0.5 <em>(planned)</em> | +:warn+ |
226
- # | _eventually_ | +:raise+ |
240
+ # [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
241
+ # Returns a frozen copy of the unhandled responses hash, with frozen
242
+ # array values.
243
+ #
244
+ # Note that calling IMAP#responses with a +type+ and without a block is
245
+ # not configurable and always behaves like +:frozen_dup+.
246
+ #
247
+ # <em>(+:frozen_dup+ config option was added in +v0.4.17+)</em>
248
+ #
249
+ # [+:raise+]
250
+ # Raise an ArgumentError with the deprecation warning.
251
+ #
252
+ # Note: #responses_without_args is an alias for #responses_without_block.
227
253
  attr_accessor :responses_without_block, type: [
228
- :silence_deprecation_warning, :warn, :raise,
254
+ :silence_deprecation_warning, :warn, :frozen_dup, :raise,
229
255
  ]
230
256
 
257
+ alias responses_without_args responses_without_block # :nodoc:
258
+ alias responses_without_args= responses_without_block= # :nodoc:
259
+
260
+ ##
261
+ # :attr_accessor: responses_without_args
262
+ #
263
+ # Alias for responses_without_block
264
+
231
265
  # Creates a new config object and initialize its attribute with +attrs+.
232
266
  #
233
267
  # If +parent+ is not given, the global config is used by default.
@@ -329,9 +363,10 @@ module Net
329
363
  version_defaults[:current] = Config[0.4]
330
364
  version_defaults[:next] = Config[0.5]
331
365
 
332
- version_defaults[:future] = Config[0.5].dup.update(
333
- responses_without_block: :raise,
366
+ version_defaults[0.6] = Config[0.5].dup.update(
367
+ responses_without_block: :frozen_dup,
334
368
  ).freeze
369
+ version_defaults[:future] = Config[0.6]
335
370
 
336
371
  version_defaults.freeze
337
372
  end
@@ -304,7 +304,7 @@ module Net
304
304
  # Use ::new to create a mutable or empty SequenceSet.
305
305
  def [](first, *rest)
306
306
  if rest.empty?
307
- if first.is_a?(SequenceSet) && set.frozen? && set.valid?
307
+ if first.is_a?(SequenceSet) && first.frozen? && first.valid?
308
308
  first
309
309
  else
310
310
  new(first).validate.freeze
@@ -325,7 +325,7 @@ module Net
325
325
  # raised.
326
326
  def try_convert(obj)
327
327
  return obj if obj.is_a?(SequenceSet)
328
- return nil unless respond_to?(:to_sequence_set)
328
+ return nil unless obj.respond_to?(:to_sequence_set)
329
329
  obj = obj.to_sequence_set
330
330
  return obj if obj.is_a?(SequenceSet)
331
331
  raise DataFormatError, "invalid object returned from to_sequence_set"
@@ -682,6 +682,7 @@ module Net
682
682
  # Unlike #add, #merge, or #union, the new value is appended to #string.
683
683
  # This may result in a #string which has duplicates or is out-of-order.
684
684
  def append(object)
685
+ modifying!
685
686
  tuple = input_to_tuple object
686
687
  entry = tuple_to_str tuple
687
688
  tuple_add tuple
@@ -1317,6 +1318,12 @@ module Net
1317
1318
  range.include?(min) || range.include?(max) || (min..max).cover?(range)
1318
1319
  end
1319
1320
 
1321
+ def modifying!
1322
+ if frozen?
1323
+ raise FrozenError, "can't modify frozen #{self.class}: %p" % [self]
1324
+ end
1325
+ end
1326
+
1320
1327
  def tuples_add(tuples) tuples.each do tuple_add _1 end; self end
1321
1328
  def tuples_subtract(tuples) tuples.each do tuple_subtract _1 end; self end
1322
1329
 
@@ -1331,6 +1338,7 @@ module Net
1331
1338
  # ---------??===lower==|--|==|----|===upper===|-- join until upper
1332
1339
  # ---------??===lower==|--|==|--|=====upper===|-- join to upper
1333
1340
  def tuple_add(tuple)
1341
+ modifying!
1334
1342
  min, max = tuple
1335
1343
  lower, lower_idx = tuple_gte_with_index(min - 1)
1336
1344
  if lower.nil? then tuples << tuple
@@ -1367,6 +1375,7 @@ module Net
1367
1375
  # -------??=====lower====|--|====|---|====upper====|-- 7. delete until
1368
1376
  # -------??=====lower====|--|====|--|=====upper====|-- 8. delete and trim
1369
1377
  def tuple_subtract(tuple)
1378
+ modifying!
1370
1379
  min, max = tuple
1371
1380
  lower, idx = tuple_gte_with_index(min)
1372
1381
  if lower.nil? then nil # case 1.
data/lib/net/imap.rb CHANGED
@@ -288,6 +288,8 @@ module Net
288
288
  # pre-authenticated connection.
289
289
  # - #responses: Yields unhandled UntaggedResponse#data and <em>non-+nil+</em>
290
290
  # ResponseCode#data.
291
+ # - #extract_responses: Removes and returns the responses for which the block
292
+ # returns a true value.
291
293
  # - #clear_responses: Deletes unhandled data from #responses and returns it.
292
294
  # - #add_response_handler: Add a block to be called inside the receiver thread
293
295
  # with every server response.
@@ -717,7 +719,7 @@ module Net
717
719
  # * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
718
720
  #
719
721
  class IMAP < Protocol
720
- VERSION = "0.4.16"
722
+ VERSION = "0.4.18"
721
723
 
722
724
  # Aliases for supported capabilities, to be used with the #enable command.
723
725
  ENABLE_ALIASES = {
@@ -2494,41 +2496,98 @@ module Net
2494
2496
  end
2495
2497
  end
2496
2498
 
2499
+ RESPONSES_DEPRECATION_MSG =
2500
+ "Pass a type or block to #responses, " \
2501
+ "set config.responses_without_block to :frozen_dup " \
2502
+ "or :silence_deprecation_warning, " \
2503
+ "or use #extract_responses or #clear_responses."
2504
+ private_constant :RESPONSES_DEPRECATION_MSG
2505
+
2497
2506
  # :call-seq:
2507
+ # responses -> hash of {String => Array} (see config.responses_without_block)
2508
+ # responses(type) -> frozen array
2498
2509
  # responses {|hash| ...} -> block result
2499
2510
  # responses(type) {|array| ...} -> block result
2500
2511
  #
2501
- # Yields unhandled responses and returns the result of the block.
2512
+ # Yields or returns unhandled server responses. Unhandled responses are
2513
+ # stored in a hash, with arrays of UntaggedResponse#data keyed by
2514
+ # UntaggedResponse#name and <em>non-+nil+</em> untagged ResponseCode#data
2515
+ # keyed by ResponseCode#name.
2516
+ #
2517
+ # When a block is given, yields unhandled responses and returns the block's
2518
+ # result. Without a block, returns the unhandled responses.
2519
+ #
2520
+ # [With +type+]
2521
+ # Yield or return only the array of responses for that +type+.
2522
+ # When no block is given, the returned array is a frozen copy.
2523
+ # [Without +type+]
2524
+ # Yield or return the entire responses hash.
2525
+ #
2526
+ # When no block is given, the behavior is determined by
2527
+ # Config#responses_without_block:
2528
+ # >>>
2529
+ # [+:silence_deprecation_warning+ <em>(original behavior)</em>]
2530
+ # Returns the mutable responses hash (without any warnings).
2531
+ # <em>This is not thread-safe.</em>
2532
+ #
2533
+ # [+:warn+ <em>(default since +v0.5+)</em>]
2534
+ # Prints a warning and returns the mutable responses hash.
2535
+ # <em>This is not thread-safe.</em>
2502
2536
  #
2503
- # Unhandled responses are stored in a hash, with arrays of
2504
- # <em>non-+nil+</em> UntaggedResponse#data keyed by UntaggedResponse#name
2505
- # and ResponseCode#data keyed by ResponseCode#name. Call without +type+ to
2506
- # yield the entire responses hash. Call with +type+ to yield only the array
2507
- # of responses for that type.
2537
+ # [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
2538
+ # Returns a frozen copy of the unhandled responses hash, with frozen
2539
+ # array values.
2540
+ #
2541
+ # [+:raise+]
2542
+ # Raise an +ArgumentError+ with the deprecation warning.
2508
2543
  #
2509
2544
  # For example:
2510
2545
  #
2511
2546
  # imap.select("inbox")
2512
- # p imap.responses("EXISTS", &:last)
2547
+ # p imap.responses("EXISTS").last
2513
2548
  # #=> 2
2549
+ # p imap.responses("UIDNEXT", &:last)
2550
+ # #=> 123456
2514
2551
  # p imap.responses("UIDVALIDITY", &:last)
2515
2552
  # #=> 968263756
2553
+ # p imap.responses {|responses|
2554
+ # {
2555
+ # exists: responses.delete("EXISTS").last,
2556
+ # uidnext: responses.delete("UIDNEXT").last,
2557
+ # uidvalidity: responses.delete("UIDVALIDITY").last,
2558
+ # }
2559
+ # }
2560
+ # #=> {:exists=>2, :uidnext=>123456, :uidvalidity=>968263756}
2561
+ # # "EXISTS", "UIDNEXT", and "UIDVALIDITY" have been removed:
2562
+ # p imap.responses(&:keys)
2563
+ # #=> ["FLAGS", "OK", "PERMANENTFLAGS", "RECENT", "HIGHESTMODSEQ"]
2564
+ #
2565
+ # Related: #extract_responses, #clear_responses, #response_handlers, #greeting
2516
2566
  #
2567
+ # ===== Thread safety
2517
2568
  # >>>
2518
2569
  # *Note:* Access to the responses hash is synchronized for thread-safety.
2519
2570
  # The receiver thread and response_handlers cannot process new responses
2520
2571
  # until the block completes. Accessing either the response hash or its
2521
- # response type arrays outside of the block is unsafe.
2572
+ # response type arrays outside of the block is unsafe. They can be safely
2573
+ # updated inside the block. Consider using #clear_responses or
2574
+ # #extract_responses instead.
2522
2575
  #
2523
- # Calling without a block is unsafe and deprecated. Future releases will
2524
- # raise ArgumentError unless a block is given.
2525
- # See Config#responses_without_block.
2576
+ # Net::IMAP will add and remove responses from the responses hash and its
2577
+ # array values, in the calling threads for commands and in the receiver
2578
+ # thread, but will not modify any responses after adding them to the
2579
+ # responses hash.
2580
+ #
2581
+ # ===== Clearing responses
2526
2582
  #
2527
2583
  # Previously unhandled responses are automatically cleared before entering a
2528
2584
  # mailbox with #select or #examine. Long-lived connections can receive many
2529
2585
  # unhandled server responses, which must be pruned or they will continually
2530
2586
  # consume more memory. Update or clear the responses hash or arrays inside
2531
- # the block, or use #clear_responses.
2587
+ # the block, or remove responses with #extract_responses, #clear_responses,
2588
+ # or #add_response_handler.
2589
+ #
2590
+ # ===== Missing responses
2532
2591
  #
2533
2592
  # Only non-+nil+ data is stored. Many important response codes have no data
2534
2593
  # of their own, but are used as "tags" on the ResponseText object they are
@@ -2539,19 +2598,24 @@ module Net
2539
2598
  # ResponseCode#data on tagged responses. Although some command methods do
2540
2599
  # return the TaggedResponse directly, #add_response_handler must be used to
2541
2600
  # handle all response codes.
2542
- #
2543
- # Related: #clear_responses, #response_handlers, #greeting
2544
2601
  def responses(type = nil)
2545
2602
  if block_given?
2546
2603
  synchronize { yield(type ? @responses[type.to_s.upcase] : @responses) }
2547
2604
  elsif type
2548
- raise ArgumentError, "Pass a block or use #clear_responses"
2605
+ synchronize { @responses[type.to_s.upcase].dup.freeze }
2549
2606
  else
2550
2607
  case config.responses_without_block
2551
2608
  when :raise
2552
- raise ArgumentError, "Pass a block or use #clear_responses"
2609
+ raise ArgumentError, RESPONSES_DEPRECATION_MSG
2553
2610
  when :warn
2554
- warn("DEPRECATED: pass a block or use #clear_responses", uplevel: 1)
2611
+ warn(RESPONSES_DEPRECATION_MSG, uplevel: 1)
2612
+ when :frozen_dup
2613
+ synchronize {
2614
+ responses = @responses.transform_values(&:freeze)
2615
+ responses.default_proc = nil
2616
+ responses.default = [].freeze
2617
+ return responses.freeze
2618
+ }
2555
2619
  end
2556
2620
  @responses
2557
2621
  end
@@ -2567,7 +2631,7 @@ module Net
2567
2631
  # Clearing responses is synchronized with other threads. The lock is
2568
2632
  # released before returning.
2569
2633
  #
2570
- # Related: #responses, #response_handlers
2634
+ # Related: #extract_responses, #responses, #response_handlers
2571
2635
  def clear_responses(type = nil)
2572
2636
  synchronize {
2573
2637
  if type
@@ -2581,6 +2645,30 @@ module Net
2581
2645
  .freeze
2582
2646
  end
2583
2647
 
2648
+ # :call-seq:
2649
+ # extract_responses(type) {|response| ... } -> array
2650
+ #
2651
+ # Yields all of the unhandled #responses for a single response +type+.
2652
+ # Removes and returns the responses for which the block returns a true
2653
+ # value.
2654
+ #
2655
+ # Extracting responses is synchronized with other threads. The lock is
2656
+ # released before returning.
2657
+ #
2658
+ # Related: #responses, #clear_responses
2659
+ def extract_responses(type)
2660
+ type = String.try_convert(type) or
2661
+ raise ArgumentError, "type must be a string"
2662
+ raise ArgumentError, "must provide a block" unless block_given?
2663
+ extracted = []
2664
+ responses(type) do |all|
2665
+ all.reject! do |response|
2666
+ extracted << response if yield response
2667
+ end
2668
+ end
2669
+ extracted
2670
+ end
2671
+
2584
2672
  # Returns all response handlers, including those that are added internally
2585
2673
  # by commands. Each response handler will be called with every new
2586
2674
  # UntaggedResponse, TaggedResponse, and ContinuationRequest.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-imap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.16
4
+ version: 0.4.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-09-04 00:00:00.000000000 Z
12
+ date: 2024-11-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-protocol
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.5.9
128
+ rubygems_version: 3.5.22
129
129
  signing_key:
130
130
  specification_version: 4
131
131
  summary: Ruby client api for Internet Message Access Protocol