net-imap 0.5.3 → 0.5.4
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.
Potentially problematic release.
This version of net-imap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/net/imap/command_data.rb +32 -0
- data/lib/net/imap/esearch_result.rb +44 -4
- data/lib/net/imap/response_parser.rb +51 -0
- data/lib/net/imap.rb +109 -47
- data/rakelib/rfcs.rake +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a871e99f51067e3a509aa5a74fe2c49f4d79496bcec2f21ac50c3c5793d2cdbf
|
4
|
+
data.tar.gz: 302c03e65954f9a118d877f97ea2296f34a7f50c8b1299e3e4f8b589cb620880
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85d97c9729220265da03588f175fea22bcdd27d40cd06910ad35bc01ed64bd0c27b2769790464712572166761f3e82fc4eb6330fef64f45cceb0b3e1007f7126
|
7
|
+
data.tar.gz: aa18d53b81e57ddfbdde2b8295ca7324f965fa744846fdd756ec4ca1c30e6e72092b106ff454d100f70d1078ee239f2b3e643bd4650606a2fc3b4ab5a2d0cc1f
|
@@ -153,6 +153,38 @@ module Net
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
class PartialRange < CommandData # :nodoc:
|
157
|
+
uint32_max = 2**32 - 1
|
158
|
+
POS_RANGE = 1..uint32_max
|
159
|
+
NEG_RANGE = -uint32_max..-1
|
160
|
+
Positive = ->{ (_1 in Range) and POS_RANGE.cover?(_1) }
|
161
|
+
Negative = ->{ (_1 in Range) and NEG_RANGE.cover?(_1) }
|
162
|
+
|
163
|
+
def initialize(data:)
|
164
|
+
min, max = case data
|
165
|
+
in Range
|
166
|
+
data.minmax.map { Integer _1 }
|
167
|
+
in ResponseParser::Patterns::PARTIAL_RANGE
|
168
|
+
data.split(":").map { Integer _1 }.minmax
|
169
|
+
else
|
170
|
+
raise ArgumentError, "invalid partial range input: %p" % [data]
|
171
|
+
end
|
172
|
+
data = min..max
|
173
|
+
unless data in Positive | Negative
|
174
|
+
raise ArgumentError, "invalid partial-range: %p" % [data]
|
175
|
+
end
|
176
|
+
super
|
177
|
+
rescue TypeError, RangeError
|
178
|
+
raise ArgumentError, "expected range min/max to be Integers"
|
179
|
+
end
|
180
|
+
|
181
|
+
def formatted = "%d:%d" % data.minmax
|
182
|
+
|
183
|
+
def send_data(imap, tag)
|
184
|
+
imap.__send__(:put_string, formatted)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
156
188
|
# *DEPRECATED*. Replaced by SequenceSet.
|
157
189
|
class MessageSet < CommandData # :nodoc:
|
158
190
|
def send_data(imap, tag)
|
@@ -35,16 +35,16 @@ module Net
|
|
35
35
|
|
36
36
|
# :call-seq: to_a -> Array of integers
|
37
37
|
#
|
38
|
-
# When #all contains a SequenceSet of message sequence
|
38
|
+
# When either #all or #partial contains a SequenceSet of message sequence
|
39
39
|
# numbers or UIDs, +to_a+ returns that set as an array of integers.
|
40
40
|
#
|
41
|
-
# When #all
|
42
|
-
# returned no results or because +ALL+
|
41
|
+
# When both #all and #partial are +nil+, either because the server
|
42
|
+
# returned no results or because +ALL+ and +PARTIAL+ were not included in
|
43
43
|
# the IMAP#search +RETURN+ options, #to_a returns an empty array.
|
44
44
|
#
|
45
45
|
# Note that SearchResult also implements +to_a+, so it can be used without
|
46
46
|
# checking if the server returned +SEARCH+ or +ESEARCH+ data.
|
47
|
-
def to_a; all&.numbers || [] end
|
47
|
+
def to_a; all&.numbers || partial&.to_a || [] end
|
48
48
|
|
49
49
|
##
|
50
50
|
# attr_reader: tag
|
@@ -135,6 +135,46 @@ module Net
|
|
135
135
|
# and +ESEARCH+ {[RFC4731]}[https://www.rfc-editor.org/rfc/rfc4731.html#section-3.2].
|
136
136
|
def modseq; data.assoc("MODSEQ")&.last end
|
137
137
|
|
138
|
+
# Returned by ESearchResult#partial.
|
139
|
+
#
|
140
|
+
# Requires +PARTIAL+ {[RFC9394]}[https://www.rfc-editor.org/rfc/rfc9394.html]
|
141
|
+
# or <tt>CONTEXT=SEARCH</tt>/<tt>CONTEXT=SORT</tt>
|
142
|
+
# {[RFC5267]}[https://www.rfc-editor.org/rfc/rfc5267.html]
|
143
|
+
#
|
144
|
+
# See also: #to_a
|
145
|
+
class PartialResult < Data.define(:range, :results)
|
146
|
+
def initialize(range:, results:)
|
147
|
+
range => Range
|
148
|
+
results = SequenceSet[results] unless results.nil?
|
149
|
+
super
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# method: range
|
154
|
+
# :call-seq: range -> range
|
155
|
+
|
156
|
+
##
|
157
|
+
# method: results
|
158
|
+
# :call-seq: results -> sequence set or nil
|
159
|
+
|
160
|
+
# Converts #results to an array of integers.
|
161
|
+
#
|
162
|
+
# See also: ESearchResult#to_a.
|
163
|
+
def to_a; results&.numbers || [] end
|
164
|
+
end
|
165
|
+
|
166
|
+
# :call-seq: partial -> PartialResult or nil
|
167
|
+
#
|
168
|
+
# A PartialResult containing a subset of the message sequence numbers or
|
169
|
+
# UIDs that satisfy the SEARCH criteria.
|
170
|
+
#
|
171
|
+
# Requires +PARTIAL+ {[RFC9394]}[https://www.rfc-editor.org/rfc/rfc9394.html]
|
172
|
+
# or <tt>CONTEXT=SEARCH</tt>/<tt>CONTEXT=SORT</tt>
|
173
|
+
# {[RFC5267]}[https://www.rfc-editor.org/rfc/rfc5267.html]
|
174
|
+
#
|
175
|
+
# See also: #to_a
|
176
|
+
def partial; data.assoc("PARTIAL")&.last end
|
177
|
+
|
138
178
|
end
|
139
179
|
end
|
140
180
|
end
|
@@ -321,6 +321,24 @@ module Net
|
|
321
321
|
SEQUENCE_SET = /#{SEQUENCE_SET_ITEM}(?:,#{SEQUENCE_SET_ITEM})*/n
|
322
322
|
SEQUENCE_SET_STR = /\A#{SEQUENCE_SET}\z/n
|
323
323
|
|
324
|
+
# partial-range-first = nz-number ":" nz-number
|
325
|
+
# ;; Request to search from oldest (lowest UIDs) to
|
326
|
+
# ;; more recent messages.
|
327
|
+
# ;; A range 500:400 is the same as 400:500.
|
328
|
+
# ;; This is similar to <seq-range> from [RFC3501]
|
329
|
+
# ;; but cannot contain "*".
|
330
|
+
PARTIAL_RANGE_FIRST = /\A(#{NZ_NUMBER}):(#{NZ_NUMBER})\z/n
|
331
|
+
|
332
|
+
# partial-range-last = MINUS nz-number ":" MINUS nz-number
|
333
|
+
# ;; Request to search from newest (highest UIDs) to
|
334
|
+
# ;; oldest messages.
|
335
|
+
# ;; A range -500:-400 is the same as -400:-500.
|
336
|
+
PARTIAL_RANGE_LAST = /\A(-#{NZ_NUMBER}):(-#{NZ_NUMBER})\z/n
|
337
|
+
|
338
|
+
# partial-range = partial-range-first / partial-range-last
|
339
|
+
PARTIAL_RANGE = Regexp.union(PARTIAL_RANGE_FIRST,
|
340
|
+
PARTIAL_RANGE_LAST)
|
341
|
+
|
324
342
|
# RFC3501:
|
325
343
|
# literal = "{" number "}" CRLF *CHAR8
|
326
344
|
# ; Number represents the number of CHAR8s
|
@@ -1517,6 +1535,9 @@ module Net
|
|
1517
1535
|
# From RFC4731 (ESEARCH):
|
1518
1536
|
# search-return-data =/ "MODSEQ" SP mod-sequence-value
|
1519
1537
|
#
|
1538
|
+
# From RFC9394 (PARTIAL):
|
1539
|
+
# search-return-data =/ ret-data-partial
|
1540
|
+
#
|
1520
1541
|
def search_return_data
|
1521
1542
|
label = search_modifier_name; SP!
|
1522
1543
|
value =
|
@@ -1526,11 +1547,41 @@ module Net
|
|
1526
1547
|
when "ALL" then sequence_set
|
1527
1548
|
when "COUNT" then number
|
1528
1549
|
when "MODSEQ" then mod_sequence_value # RFC7162: CONDSTORE
|
1550
|
+
when "PARTIAL" then ret_data_partial__value # RFC9394: PARTIAL
|
1529
1551
|
else search_return_value
|
1530
1552
|
end
|
1531
1553
|
[label, value]
|
1532
1554
|
end
|
1533
1555
|
|
1556
|
+
# From RFC5267 (CONTEXT=SEARCH, CONTEXT=SORT) and RFC9394 (PARTIAL):
|
1557
|
+
# ret-data-partial = "PARTIAL"
|
1558
|
+
# SP "(" partial-range SP partial-results ")"
|
1559
|
+
def ret_data_partial__value
|
1560
|
+
lpar
|
1561
|
+
range = partial_range; SP!
|
1562
|
+
results = partial_results
|
1563
|
+
rpar
|
1564
|
+
ESearchResult::PartialResult.new(range, results)
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
# partial-range = partial-range-first / partial-range-last
|
1568
|
+
# tagged-ext-simple =/ partial-range-last
|
1569
|
+
def partial_range
|
1570
|
+
case (str = atom)
|
1571
|
+
when Patterns::PARTIAL_RANGE_FIRST, Patterns::PARTIAL_RANGE_LAST
|
1572
|
+
min, max = [Integer($1), Integer($2)].minmax
|
1573
|
+
min..max
|
1574
|
+
else
|
1575
|
+
parse_error("unexpected atom %p, expected partial-range", str)
|
1576
|
+
end
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
# partial-results = sequence-set / "NIL"
|
1580
|
+
# ;; <sequence-set> from [RFC3501].
|
1581
|
+
# ;; NIL indicates that no results correspond to
|
1582
|
+
# ;; the requested range.
|
1583
|
+
def partial_results; NIL? ? nil : sequence_set end
|
1584
|
+
|
1534
1585
|
# search-modifier-name = tagged-ext-label
|
1535
1586
|
alias search_modifier_name tagged_ext_label
|
1536
1587
|
|
data/lib/net/imap.rb
CHANGED
@@ -534,6 +534,11 @@ module Net
|
|
534
534
|
# See FetchData#emailid and FetchData#emailid.
|
535
535
|
# - Updates #status with support for the +MAILBOXID+ status attribute.
|
536
536
|
#
|
537
|
+
# ==== RFC9394: +PARTIAL+
|
538
|
+
# - Updates #search, #uid_search with the +PARTIAL+ return option which adds
|
539
|
+
# ESearchResult#partial return data.
|
540
|
+
# - Updates #uid_fetch with the +partial+ modifier.
|
541
|
+
#
|
537
542
|
# == References
|
538
543
|
#
|
539
544
|
# [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501.html]]::
|
@@ -701,6 +706,11 @@ module Net
|
|
701
706
|
# Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
|
702
707
|
# RFC 8474, DOI 10.17487/RFC8474, September 2018,
|
703
708
|
# <https://www.rfc-editor.org/info/rfc8474>.
|
709
|
+
# [PARTIAL[https://www.rfc-editor.org/info/rfc9394]]::
|
710
|
+
# Melnikov, A., Achuthan, A., Nagulakonda, V., and L. Alves,
|
711
|
+
# "IMAP PARTIAL Extension for Paged SEARCH and FETCH", RFC 9394,
|
712
|
+
# DOI 10.17487/RFC9394, June 2023,
|
713
|
+
# <https://www.rfc-editor.org/info/rfc9394>.
|
704
714
|
#
|
705
715
|
# === IANA registries
|
706
716
|
# * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
|
@@ -723,7 +733,7 @@ module Net
|
|
723
733
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
724
734
|
#
|
725
735
|
class IMAP < Protocol
|
726
|
-
VERSION = "0.5.
|
736
|
+
VERSION = "0.5.4"
|
727
737
|
|
728
738
|
# Aliases for supported capabilities, to be used with the #enable command.
|
729
739
|
ENABLE_ALIASES = {
|
@@ -1971,8 +1981,9 @@ module Net
|
|
1971
1981
|
# the server to return an ESearchResult instead of a SearchResult, but some
|
1972
1982
|
# servers disobey this requirement. <em>Requires an extended search
|
1973
1983
|
# capability, such as +ESEARCH+ or +IMAP4rev2+.</em>
|
1974
|
-
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation]
|
1975
|
-
#
|
1984
|
+
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation] and
|
1985
|
+
# {"Supported return options"}[rdoc-ref:#search@Supported+return+options],
|
1986
|
+
# below.
|
1976
1987
|
#
|
1977
1988
|
# +charset+ is the name of the {registered character
|
1978
1989
|
# set}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
|
@@ -2082,33 +2093,58 @@ module Net
|
|
2082
2093
|
# <em>*WARNING:* This is vulnerable to injection attacks when external
|
2083
2094
|
# inputs are used.</em>
|
2084
2095
|
#
|
2085
|
-
# ====
|
2096
|
+
# ==== Supported return options
|
2086
2097
|
#
|
2087
2098
|
# For full definitions of the standard return options and return data, see
|
2088
2099
|
# the relevant RFCs.
|
2089
2100
|
#
|
2090
|
-
# ===== +ESEARCH+ or +IMAP4rev2+
|
2091
|
-
#
|
2092
|
-
# The following return options require either +ESEARCH+ or +IMAP4rev2+.
|
2093
|
-
# See [{RFC4731 §3.1}[https://rfc-editor.org/rfc/rfc4731#section-3.1]] or
|
2094
|
-
# [{IMAP4rev2 §6.4.4}[https://www.rfc-editor.org/rfc/rfc9051.html#section-6.4.4]].
|
2095
|
-
#
|
2096
2101
|
# [+ALL+]
|
2097
2102
|
# Returns ESearchResult#all with a SequenceSet of all matching sequence
|
2098
2103
|
# numbers or UIDs. This is the default, when return options are empty.
|
2099
2104
|
#
|
2100
2105
|
# For compatibility with SearchResult, ESearchResult#to_a returns an
|
2101
2106
|
# Array of message sequence numbers or UIDs.
|
2107
|
+
#
|
2108
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2109
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2110
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2111
|
+
#
|
2102
2112
|
# [+COUNT+]
|
2103
2113
|
# Returns ESearchResult#count with the number of matching messages.
|
2114
|
+
#
|
2115
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2116
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2117
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2118
|
+
#
|
2104
2119
|
# [+MAX+]
|
2105
2120
|
# Returns ESearchResult#max with the highest matching sequence number or
|
2106
2121
|
# UID.
|
2122
|
+
#
|
2123
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2124
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2125
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2126
|
+
#
|
2107
2127
|
# [+MIN+]
|
2108
2128
|
# Returns ESearchResult#min with the lowest matching sequence number or
|
2109
2129
|
# UID.
|
2110
2130
|
#
|
2111
|
-
#
|
2131
|
+
# <em>Requires either the +ESEARCH+ or +IMAP4rev2+ capabability.</em>
|
2132
|
+
# {[RFC4731]}[https://rfc-editor.org/rfc/rfc4731]
|
2133
|
+
# {[RFC9051]}[https://rfc-editor.org/rfc/rfc9051]
|
2134
|
+
#
|
2135
|
+
# [+PARTIAL+ _range_]
|
2136
|
+
# Returns ESearchResult#partial with a SequenceSet of a subset of
|
2137
|
+
# matching sequence numbers or UIDs, as selected by _range_. As with
|
2138
|
+
# sequence numbers, the first result is +1+: <tt>1..500</tt> selects the
|
2139
|
+
# first 500 search results (in mailbox order), <tt>501..1000</tt> the
|
2140
|
+
# second 500, and so on. _range_ may also be negative: <tt>-500..-1</tt>
|
2141
|
+
# selects the last 500 search results.
|
2142
|
+
#
|
2143
|
+
# <em>Requires either the <tt>CONTEXT=SEARCH</tt> or +PARTIAL+ capabability.</em>
|
2144
|
+
# {[RFC5267]}[https://rfc-editor.org/rfc/rfc5267]
|
2145
|
+
# {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
|
2146
|
+
#
|
2147
|
+
# ===== +MODSEQ+ return data
|
2112
2148
|
#
|
2113
2149
|
# ESearchResult#modseq return data does not have a corresponding return
|
2114
2150
|
# option. Instead, it is returned if the +MODSEQ+ search key is used or
|
@@ -2120,8 +2156,8 @@ module Net
|
|
2120
2156
|
#
|
2121
2157
|
# {RFC4466 §2.6}[https://www.rfc-editor.org/rfc/rfc4466.html#section-2.6]
|
2122
2158
|
# defines standard syntax for search extensions. Net::IMAP allows sending
|
2123
|
-
#
|
2124
|
-
# return values into ExtensionData. Please note that this is an
|
2159
|
+
# unsupported search return options and will parse unsupported search
|
2160
|
+
# extensions' return values into ExtensionData. Please note that this is an
|
2125
2161
|
# intentionally _unstable_ API. Future releases may return different
|
2126
2162
|
# (incompatible) objects, <em>without deprecation or warning</em>.
|
2127
2163
|
#
|
@@ -2357,14 +2393,9 @@ module Net
|
|
2357
2393
|
# Sends a {FETCH command [IMAP4rev1 §6.4.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5]
|
2358
2394
|
# to retrieve data associated with a message in the mailbox.
|
2359
2395
|
#
|
2360
|
-
#
|
2361
|
-
#
|
2362
|
-
#
|
2363
|
-
# being interpreted as '100:*'. Beware that the +exclude_end?+
|
2364
|
-
# property of a Range object is ignored, and the contents of a
|
2365
|
-
# range are independent of the order of the range endpoints as per
|
2366
|
-
# the protocol specification, so 1...5, 5..1 and 5...1 are all
|
2367
|
-
# equivalent to 1..5.
|
2396
|
+
# +set+ is the message sequence numbers to fetch, and may be any valid input
|
2397
|
+
# to {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
|
2398
|
+
# (For UIDs, use #uid_fetch instead.)
|
2368
2399
|
#
|
2369
2400
|
# +attr+ is a list of attributes to fetch; see the documentation
|
2370
2401
|
# for FetchData for a list of valid attributes.
|
@@ -2374,7 +2405,7 @@ module Net
|
|
2374
2405
|
#
|
2375
2406
|
# The return value is an array of FetchData.
|
2376
2407
|
#
|
2377
|
-
# Related: #
|
2408
|
+
# Related: #uid_fetch, FetchData
|
2378
2409
|
#
|
2379
2410
|
# ==== For example:
|
2380
2411
|
#
|
@@ -2403,30 +2434,66 @@ module Net
|
|
2403
2434
|
# {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
|
2404
2435
|
# +changedsince+ argument. Using +changedsince+ implicitly enables the
|
2405
2436
|
# +CONDSTORE+ extension.
|
2406
|
-
def fetch(
|
2407
|
-
fetch_internal("FETCH",
|
2437
|
+
def fetch(...)
|
2438
|
+
fetch_internal("FETCH", ...)
|
2408
2439
|
end
|
2409
2440
|
|
2410
2441
|
# :call-seq:
|
2411
|
-
# uid_fetch(set, attr, changedsince: nil) -> array of FetchData
|
2442
|
+
# uid_fetch(set, attr, changedsince: nil, partial: nil) -> array of FetchData
|
2412
2443
|
#
|
2413
2444
|
# Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
|
2414
2445
|
# to retrieve data associated with a message in the mailbox.
|
2415
2446
|
#
|
2416
|
-
#
|
2417
|
-
#
|
2447
|
+
# +set+ is the message UIDs to fetch, and may be any valid input to
|
2448
|
+
# {SequenceSet[...]}[rdoc-ref:SequenceSet@Creating+sequence+sets].
|
2449
|
+
# (For message sequence numbers, use #fetch instead.)
|
2418
2450
|
#
|
2451
|
+
# +attr+ behaves the same as with #fetch.
|
2419
2452
|
# >>>
|
2420
2453
|
# *Note:* Servers _MUST_ implicitly include the +UID+ message data item as
|
2421
2454
|
# part of any +FETCH+ response caused by a +UID+ command, regardless of
|
2422
2455
|
# whether a +UID+ was specified as a message data item to the +FETCH+.
|
2423
2456
|
#
|
2457
|
+
# +changedsince+ (optional) behaves the same as with #fetch.
|
2458
|
+
#
|
2459
|
+
# +partial+ is an optional range to limit the number of results returned.
|
2460
|
+
# It's useful when +set+ contains an unknown number of messages.
|
2461
|
+
# <tt>1..500</tt> returns the first 500 messages in +set+ (in mailbox
|
2462
|
+
# order), <tt>501..1000</tt> the second 500, and so on. +partial+ may also
|
2463
|
+
# be negative: <tt>-500..-1</tt> selects the last 500 messages in +set+.
|
2464
|
+
# <em>Requires the +PARTIAL+ capabability.</em>
|
2465
|
+
# {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
|
2466
|
+
#
|
2467
|
+
# For example:
|
2468
|
+
#
|
2469
|
+
# # Without partial, the size of the results may be unknown beforehand:
|
2470
|
+
# results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS))
|
2471
|
+
# # ... maybe wait for a long time ... and allocate a lot of memory ...
|
2472
|
+
# results.size # => 0..2**32-1
|
2473
|
+
# process results # may also take a long time and use a lot of memory...
|
2474
|
+
#
|
2475
|
+
# # Using partial, the results may be paginated:
|
2476
|
+
# loop do
|
2477
|
+
# results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS),
|
2478
|
+
# partial: 1..500)
|
2479
|
+
# # fetch should return quickly and allocate little memory
|
2480
|
+
# results.size # => 0..500
|
2481
|
+
# break if results.empty?
|
2482
|
+
# next_uid_to_fetch = results.last.uid + 1
|
2483
|
+
# process results
|
2484
|
+
# end
|
2485
|
+
#
|
2424
2486
|
# Related: #fetch, FetchData
|
2425
2487
|
#
|
2426
2488
|
# ==== Capabilities
|
2427
|
-
#
|
2428
|
-
|
2429
|
-
|
2489
|
+
#
|
2490
|
+
# The server's capabilities must include +PARTIAL+
|
2491
|
+
# {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394] in order to use the
|
2492
|
+
# +partial+ argument.
|
2493
|
+
#
|
2494
|
+
# Otherwise, the same as #fetch.
|
2495
|
+
def uid_fetch(...)
|
2496
|
+
fetch_internal("UID FETCH", ...)
|
2430
2497
|
end
|
2431
2498
|
|
2432
2499
|
# :call-seq:
|
@@ -3338,24 +3405,14 @@ module Net
|
|
3338
3405
|
]
|
3339
3406
|
return_opts.map {|opt|
|
3340
3407
|
case opt
|
3341
|
-
when Symbol
|
3342
|
-
when
|
3343
|
-
|
3408
|
+
when Symbol then opt.to_s
|
3409
|
+
when PartialRange::Negative then PartialRange[opt]
|
3410
|
+
when Range then SequenceSet[opt]
|
3411
|
+
else opt
|
3344
3412
|
end
|
3345
3413
|
}
|
3346
3414
|
end
|
3347
3415
|
|
3348
|
-
def partial_range_last_or_seqset(range)
|
3349
|
-
case [range.begin, range.end]
|
3350
|
-
in [Integer => first, Integer => last] if first.negative? && last.negative?
|
3351
|
-
# partial-range-last [RFC9394]
|
3352
|
-
first <= last or raise DataFormatError, "empty range: %p" % [range]
|
3353
|
-
"#{first}:#{last}"
|
3354
|
-
else
|
3355
|
-
SequenceSet[range]
|
3356
|
-
end
|
3357
|
-
end
|
3358
|
-
|
3359
3416
|
def search_internal(cmd, ...)
|
3360
3417
|
args, esearch = search_args(...)
|
3361
3418
|
synchronize do
|
@@ -3382,7 +3439,12 @@ module Net
|
|
3382
3439
|
end
|
3383
3440
|
end
|
3384
3441
|
|
3385
|
-
def fetch_internal(cmd, set, attr, mod = nil, changedsince: nil)
|
3442
|
+
def fetch_internal(cmd, set, attr, mod = nil, partial: nil, changedsince: nil)
|
3443
|
+
set = SequenceSet[set]
|
3444
|
+
if partial
|
3445
|
+
mod ||= []
|
3446
|
+
mod << "PARTIAL" << PartialRange[partial]
|
3447
|
+
end
|
3386
3448
|
if changedsince
|
3387
3449
|
mod ||= []
|
3388
3450
|
mod << "CHANGEDSINCE" << Integer(changedsince)
|
@@ -3399,9 +3461,9 @@ module Net
|
|
3399
3461
|
synchronize do
|
3400
3462
|
clear_responses("FETCH")
|
3401
3463
|
if mod
|
3402
|
-
send_command(cmd,
|
3464
|
+
send_command(cmd, set, attr, mod)
|
3403
3465
|
else
|
3404
|
-
send_command(cmd,
|
3466
|
+
send_command(cmd, set, attr)
|
3405
3467
|
end
|
3406
3468
|
clear_responses("FETCH")
|
3407
3469
|
end
|
data/rakelib/rfcs.rake
CHANGED
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.5.
|
4
|
+
version: 0.5.4
|
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-12-
|
12
|
+
date: 2024-12-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-protocol
|