net-imap 0.5.1 → 0.5.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.
Potentially problematic release.
This version of net-imap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/docs/styles.css +65 -14
- data/lib/net/imap/command_data.rb +21 -51
- data/lib/net/imap/data_lite.rb +225 -0
- data/lib/net/imap/esearch_result.rb +140 -0
- data/lib/net/imap/response_data.rb +2 -0
- data/lib/net/imap/response_parser/parser_utils.rb +5 -0
- data/lib/net/imap/response_parser.rb +86 -2
- data/lib/net/imap/vanished_data.rb +56 -0
- data/lib/net/imap.rb +449 -206
- metadata +8 -5
data/lib/net/imap.rb
CHANGED
@@ -414,7 +414,7 @@ module Net
|
|
414
414
|
# >>>
|
415
415
|
# <em>The following are folded into +IMAP4rev2+ but are currently
|
416
416
|
# unsupported or incompletely supported by</em> Net::IMAP<em>: RFC4466
|
417
|
-
# extensions, +
|
417
|
+
# extensions, +SEARCHRES+, +LIST-EXTENDED+, +LIST-STATUS+,
|
418
418
|
# +LITERAL-+, and +SPECIAL-USE+.</em>
|
419
419
|
#
|
420
420
|
# ==== RFC2087: +QUOTA+
|
@@ -466,6 +466,10 @@ module Net
|
|
466
466
|
# - Updates #append with the +APPENDUID+ ResponseCode
|
467
467
|
# - Updates #copy, #move with the +COPYUID+ ResponseCode
|
468
468
|
#
|
469
|
+
# ==== RFC4731: +ESEARCH+
|
470
|
+
# Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
|
471
|
+
# - Updates #search, #uid_search with +return+ options and ESearchResult.
|
472
|
+
#
|
469
473
|
# ==== RFC4959: +SASL-IR+
|
470
474
|
# Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051].
|
471
475
|
# - Updates #authenticate with the option to send an initial response.
|
@@ -719,7 +723,7 @@ module Net
|
|
719
723
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
720
724
|
#
|
721
725
|
class IMAP < Protocol
|
722
|
-
VERSION = "0.5.
|
726
|
+
VERSION = "0.5.3"
|
723
727
|
|
724
728
|
# Aliases for supported capabilities, to be used with the #enable command.
|
725
729
|
ENABLE_ALIASES = {
|
@@ -1123,7 +1127,7 @@ module Net
|
|
1123
1127
|
#
|
1124
1128
|
# See [ID[https://tools.ietf.org/html/rfc2971]] for field definitions.
|
1125
1129
|
#
|
1126
|
-
#
|
1130
|
+
# ==== Capabilities
|
1127
1131
|
#
|
1128
1132
|
# The server's capabilities must include +ID+
|
1129
1133
|
# [RFC2971[https://tools.ietf.org/html/rfc2971]].
|
@@ -1205,7 +1209,7 @@ module Net
|
|
1205
1209
|
#
|
1206
1210
|
# Related: Net::IMAP.new, #login, #authenticate
|
1207
1211
|
#
|
1208
|
-
#
|
1212
|
+
# ==== Capability
|
1209
1213
|
# Clients should not call #starttls unless the server advertises the
|
1210
1214
|
# +STARTTLS+ capability.
|
1211
1215
|
#
|
@@ -1352,7 +1356,7 @@ module Net
|
|
1352
1356
|
#
|
1353
1357
|
# Related: #authenticate, #starttls
|
1354
1358
|
#
|
1355
|
-
#
|
1359
|
+
# ==== Capabilities
|
1356
1360
|
#
|
1357
1361
|
# An IMAP client MUST NOT call #login when the server advertises the
|
1358
1362
|
# +LOGINDISABLED+ capability. By default, Net::IMAP will raise a
|
@@ -1393,7 +1397,7 @@ module Net
|
|
1393
1397
|
#
|
1394
1398
|
# Related: #examine
|
1395
1399
|
#
|
1396
|
-
#
|
1400
|
+
# ==== Capabilities
|
1397
1401
|
#
|
1398
1402
|
# If [UIDPLUS[https://www.rfc-editor.org/rfc/rfc4315.html]] is supported,
|
1399
1403
|
# the server may return an untagged "NO" response with a "UIDNOTSTICKY"
|
@@ -1511,7 +1515,7 @@ module Net
|
|
1511
1515
|
#
|
1512
1516
|
# Related: #lsub, MailboxList
|
1513
1517
|
#
|
1514
|
-
#
|
1518
|
+
# ==== For example:
|
1515
1519
|
#
|
1516
1520
|
# imap.create("foo/bar")
|
1517
1521
|
# imap.create("foo/baz")
|
@@ -1562,7 +1566,7 @@ module Net
|
|
1562
1566
|
#
|
1563
1567
|
# Related: #list, Namespaces, Namespace
|
1564
1568
|
#
|
1565
|
-
#
|
1569
|
+
# ==== For example:
|
1566
1570
|
#
|
1567
1571
|
# if capable?("NAMESPACE")
|
1568
1572
|
# namespaces = imap.namespace
|
@@ -1576,7 +1580,7 @@ module Net
|
|
1576
1580
|
# end
|
1577
1581
|
# end
|
1578
1582
|
#
|
1579
|
-
#
|
1583
|
+
# ==== Capabilities
|
1580
1584
|
#
|
1581
1585
|
# The server's capabilities must include +NAMESPACE+
|
1582
1586
|
# [RFC2342[https://tools.ietf.org/html/rfc2342]].
|
@@ -1615,7 +1619,7 @@ module Net
|
|
1615
1619
|
#
|
1616
1620
|
# Related: #list, MailboxList
|
1617
1621
|
#
|
1618
|
-
#
|
1622
|
+
# ==== Capabilities
|
1619
1623
|
#
|
1620
1624
|
# The server's capabilities must include +XLIST+,
|
1621
1625
|
# a deprecated Gmail extension (replaced by +SPECIAL-USE+).
|
@@ -1638,7 +1642,7 @@ module Net
|
|
1638
1642
|
#
|
1639
1643
|
# Related: #getquota, #setquota, MailboxQuotaRoot, MailboxQuota
|
1640
1644
|
#
|
1641
|
-
#
|
1645
|
+
# ==== Capabilities
|
1642
1646
|
#
|
1643
1647
|
# The server's capabilities must include +QUOTA+
|
1644
1648
|
# [RFC2087[https://tools.ietf.org/html/rfc2087]].
|
@@ -1659,7 +1663,7 @@ module Net
|
|
1659
1663
|
#
|
1660
1664
|
# Related: #getquotaroot, #setquota, MailboxQuota
|
1661
1665
|
#
|
1662
|
-
#
|
1666
|
+
# ==== Capabilities
|
1663
1667
|
#
|
1664
1668
|
# The server's capabilities must include +QUOTA+
|
1665
1669
|
# [RFC2087[https://tools.ietf.org/html/rfc2087]].
|
@@ -1677,7 +1681,7 @@ module Net
|
|
1677
1681
|
#
|
1678
1682
|
# Related: #getquota, #getquotaroot
|
1679
1683
|
#
|
1680
|
-
#
|
1684
|
+
# ==== Capabilities
|
1681
1685
|
#
|
1682
1686
|
# The server's capabilities must include +QUOTA+
|
1683
1687
|
# [RFC2087[https://tools.ietf.org/html/rfc2087]].
|
@@ -1697,7 +1701,7 @@ module Net
|
|
1697
1701
|
#
|
1698
1702
|
# Related: #getacl
|
1699
1703
|
#
|
1700
|
-
#
|
1704
|
+
# ==== Capabilities
|
1701
1705
|
#
|
1702
1706
|
# The server's capabilities must include +ACL+
|
1703
1707
|
# [RFC4314[https://tools.ietf.org/html/rfc4314]].
|
@@ -1715,7 +1719,7 @@ module Net
|
|
1715
1719
|
#
|
1716
1720
|
# Related: #setacl, MailboxACLItem
|
1717
1721
|
#
|
1718
|
-
#
|
1722
|
+
# ==== Capabilities
|
1719
1723
|
#
|
1720
1724
|
# The server's capabilities must include +ACL+
|
1721
1725
|
# [RFC4314[https://tools.ietf.org/html/rfc4314]].
|
@@ -1752,7 +1756,7 @@ module Net
|
|
1752
1756
|
# for +mailbox+ cannot be returned; for instance, because it
|
1753
1757
|
# does not exist.
|
1754
1758
|
#
|
1755
|
-
#
|
1759
|
+
# ==== Supported attributes
|
1756
1760
|
#
|
1757
1761
|
# +MESSAGES+:: The number of messages in the mailbox.
|
1758
1762
|
#
|
@@ -1783,12 +1787,12 @@ module Net
|
|
1783
1787
|
# Unsupported attributes may be requested. The attribute value will be
|
1784
1788
|
# either an Integer or an ExtensionData object.
|
1785
1789
|
#
|
1786
|
-
#
|
1790
|
+
# ==== For example:
|
1787
1791
|
#
|
1788
1792
|
# p imap.status("inbox", ["MESSAGES", "RECENT"])
|
1789
1793
|
# #=> {"RECENT"=>0, "MESSAGES"=>44}
|
1790
1794
|
#
|
1791
|
-
#
|
1795
|
+
# ==== Capabilities
|
1792
1796
|
#
|
1793
1797
|
# +SIZE+ requires the server's capabilities to include either +IMAP4rev2+ or
|
1794
1798
|
# <tt>STATUS=SIZE</tt>
|
@@ -1828,7 +1832,7 @@ module Net
|
|
1828
1832
|
# not exist (it is not created automatically), or if the flags,
|
1829
1833
|
# date_time, or message arguments contain errors.
|
1830
1834
|
#
|
1831
|
-
#
|
1835
|
+
# ==== Capabilities
|
1832
1836
|
#
|
1833
1837
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
1834
1838
|
# supported and the destination supports persistent UIDs, the server's
|
@@ -1877,7 +1881,7 @@ module Net
|
|
1877
1881
|
#
|
1878
1882
|
# Related: #close
|
1879
1883
|
#
|
1880
|
-
#
|
1884
|
+
# ==== Capabilities
|
1881
1885
|
#
|
1882
1886
|
# The server's capabilities must include +UNSELECT+
|
1883
1887
|
# [RFC3691[https://tools.ietf.org/html/rfc3691]].
|
@@ -1885,110 +1889,243 @@ module Net
|
|
1885
1889
|
send_command("UNSELECT")
|
1886
1890
|
end
|
1887
1891
|
|
1892
|
+
# call-seq:
|
1893
|
+
# expunge -> array of message sequence numbers
|
1894
|
+
# expunge -> VanishedData of UIDs
|
1895
|
+
#
|
1888
1896
|
# Sends an {EXPUNGE command [IMAP4rev1 §6.4.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.3]
|
1889
|
-
#
|
1890
|
-
# selected mailbox
|
1897
|
+
# to permanently remove all messages with the +\Deleted+ flag from the
|
1898
|
+
# currently selected mailbox.
|
1899
|
+
#
|
1900
|
+
# Returns either an array of expunged message <em>sequence numbers</em> or
|
1901
|
+
# (when the appropriate capability is enabled) VanishedData of expunged
|
1902
|
+
# UIDs. Previously unhandled +EXPUNGE+ or +VANISHED+ responses are merged
|
1903
|
+
# with the direct response to this command. <tt>VANISHED (EARLIER)</tt>
|
1904
|
+
# responses will _not_ be merged.
|
1905
|
+
#
|
1906
|
+
# When no messages have been expunged, an empty array is returned,
|
1907
|
+
# regardless of which extensions are enabled. In a future release, an empty
|
1908
|
+
# VanishedData may be returned, based on the currently enabled extensions.
|
1891
1909
|
#
|
1892
1910
|
# Related: #uid_expunge
|
1911
|
+
#
|
1912
|
+
# ==== Capabilities
|
1913
|
+
#
|
1914
|
+
# When either QRESYNC[https://tools.ietf.org/html/rfc7162] or
|
1915
|
+
# UIDONLY[https://tools.ietf.org/html/rfc9586] are enabled, #expunge
|
1916
|
+
# returns VanishedData, which contains UIDs---<em>not message sequence
|
1917
|
+
# numbers</em>.
|
1893
1918
|
def expunge
|
1894
|
-
|
1895
|
-
send_command("EXPUNGE")
|
1896
|
-
clear_responses("EXPUNGE")
|
1897
|
-
end
|
1919
|
+
expunge_internal("EXPUNGE")
|
1898
1920
|
end
|
1899
1921
|
|
1922
|
+
# call-seq:
|
1923
|
+
# uid_expunge{uid_set) -> array of message sequence numbers
|
1924
|
+
# uid_expunge{uid_set) -> VanishedData of UIDs
|
1925
|
+
#
|
1900
1926
|
# Sends a {UID EXPUNGE command [RFC4315 §2.1]}[https://www.rfc-editor.org/rfc/rfc4315#section-2.1]
|
1901
1927
|
# {[IMAP4rev2 §6.4.9]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.9]
|
1902
1928
|
# to permanently remove all messages that have both the <tt>\\Deleted</tt>
|
1903
1929
|
# flag set and a UID that is included in +uid_set+.
|
1904
1930
|
#
|
1931
|
+
# Returns the same result type as #expunge.
|
1932
|
+
#
|
1905
1933
|
# By using #uid_expunge instead of #expunge when resynchronizing with
|
1906
1934
|
# the server, the client can ensure that it does not inadvertantly
|
1907
1935
|
# remove any messages that have been marked as <tt>\\Deleted</tt> by other
|
1908
1936
|
# clients between the time that the client was last connected and
|
1909
1937
|
# the time the client resynchronizes.
|
1910
1938
|
#
|
1911
|
-
# *Note:*
|
1912
|
-
# >>>
|
1913
|
-
# Although the command takes a set of UIDs for its argument, the
|
1914
|
-
# server still returns regular EXPUNGE responses, which contain
|
1915
|
-
# a <em>sequence number</em>. These will be deleted from
|
1916
|
-
# #responses and this method returns them as an array of
|
1917
|
-
# <em>sequence number</em> integers.
|
1918
|
-
#
|
1919
1939
|
# Related: #expunge
|
1920
1940
|
#
|
1921
|
-
#
|
1941
|
+
# ==== Capabilities
|
1922
1942
|
#
|
1923
|
-
# The server's capabilities must include +UIDPLUS+
|
1943
|
+
# The server's capabilities must include either +IMAP4rev2+ or +UIDPLUS+
|
1924
1944
|
# [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]].
|
1945
|
+
#
|
1946
|
+
# Otherwise, #uid_expunge is updated by extensions in the same way as
|
1947
|
+
# #expunge.
|
1925
1948
|
def uid_expunge(uid_set)
|
1926
|
-
|
1927
|
-
send_command("UID EXPUNGE", SequenceSet.new(uid_set))
|
1928
|
-
clear_responses("EXPUNGE")
|
1929
|
-
end
|
1949
|
+
expunge_internal("UID EXPUNGE", SequenceSet.new(uid_set))
|
1930
1950
|
end
|
1931
1951
|
|
1932
1952
|
# :call-seq:
|
1933
1953
|
# search(criteria, charset = nil) -> result
|
1954
|
+
# search(criteria, charset: nil, return: nil) -> result
|
1934
1955
|
#
|
1935
1956
|
# Sends a {SEARCH command [IMAP4rev1 §6.4.4]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.4]
|
1936
1957
|
# to search the mailbox for messages that match the given search +criteria+,
|
1937
|
-
# and returns a SearchResult. SearchResult
|
1938
|
-
# backward compatibility) but adds
|
1939
|
-
# capability has been enabled.
|
1958
|
+
# and returns either a SearchResult or an ESearchResult. SearchResult
|
1959
|
+
# inherits from Array (for backward compatibility) but adds
|
1960
|
+
# SearchResult#modseq when the +CONDSTORE+ capability has been enabled.
|
1961
|
+
# ESearchResult also implements {#to_a}[rdoc-ref:ESearchResult#to_a], for
|
1962
|
+
# compatibility with SearchResult.
|
1940
1963
|
#
|
1941
1964
|
# +criteria+ is one or more search keys and their arguments, which may be
|
1942
1965
|
# provided as an array or a string.
|
1943
|
-
# See {"
|
1944
|
-
#
|
1945
|
-
#
|
1946
|
-
#
|
1947
|
-
#
|
1948
|
-
#
|
1949
|
-
#
|
1950
|
-
#
|
1951
|
-
#
|
1952
|
-
#
|
1953
|
-
# +Integer+, a sequence-set formatted +String+, or a deeply nested
|
1954
|
-
# +Array+ of these same types.
|
1955
|
-
# * Any +String+ is sent verbatim when it is a valid \IMAP atom,
|
1956
|
-
# and encoded as an \IMAP quoted or literal string otherwise.
|
1957
|
-
# * Any other nested +Array+ is encoded as a parenthesized list, to group
|
1958
|
-
# multiple search keys (e.g., for use with +OR+ and +NOT+).
|
1959
|
-
# * Any other +Integer+ (besides <tt>-1</tt>) will be sent as +#to_s+.
|
1960
|
-
# * +Date+ objects will be encoded as an \IMAP date (see ::encode_date).
|
1961
|
-
#
|
1962
|
-
# * When +criteria+ is a string, it will be sent directly to the server
|
1963
|
-
# <em>without any validation or encoding</em>. *WARNING:* This is
|
1964
|
-
# vulnerable to injection attacks when external inputs are used.
|
1966
|
+
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation]
|
1967
|
+
# and {"Search criteria"}[rdoc-ref:#search@Search+criteria], below.
|
1968
|
+
#
|
1969
|
+
# +return+ options control what kind of information is returned about
|
1970
|
+
# messages matching the search +criteria+. Specifying +return+ should force
|
1971
|
+
# the server to return an ESearchResult instead of a SearchResult, but some
|
1972
|
+
# servers disobey this requirement. <em>Requires an extended search
|
1973
|
+
# capability, such as +ESEARCH+ or +IMAP4rev2+.</em>
|
1974
|
+
# See {"Argument translation"}[rdoc-ref:#search@Argument+translation]
|
1975
|
+
# and {"Return options"}[rdoc-ref:#search@Return+options], below.
|
1965
1976
|
#
|
1966
1977
|
# +charset+ is the name of the {registered character
|
1967
1978
|
# set}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
|
1968
1979
|
# used by strings in the search +criteria+. When +charset+ isn't specified,
|
1969
1980
|
# either <tt>"US-ASCII"</tt> or <tt>"UTF-8"</tt> is assumed, depending on
|
1970
|
-
# the server's capabilities.
|
1971
|
-
#
|
1981
|
+
# the server's capabilities.
|
1982
|
+
#
|
1983
|
+
# _NOTE:_ Return options and charset may be sent as part of +criteria+. Do
|
1984
|
+
# not use the +return+ or +charset+ arguments when either return options or
|
1985
|
+
# charset are embedded in +criteria+.
|
1972
1986
|
#
|
1973
1987
|
# Related: #uid_search
|
1974
1988
|
#
|
1975
|
-
#
|
1989
|
+
# ==== For example:
|
1976
1990
|
#
|
1977
|
-
#
|
1991
|
+
# imap.search(["SUBJECT", "hello", "NOT", "SEEN"])
|
1978
1992
|
# #=> [1, 6, 7, 8]
|
1979
1993
|
#
|
1980
|
-
# The following
|
1981
|
-
#
|
1982
|
-
#
|
1983
|
-
#
|
1984
|
-
#
|
1985
|
-
#
|
1986
|
-
#
|
1987
|
-
#
|
1988
|
-
#
|
1989
|
-
#
|
1990
|
-
#
|
1991
|
-
#
|
1994
|
+
# The following assumes the server supports +ESEARCH+ and +CONDSTORE+:
|
1995
|
+
#
|
1996
|
+
# result = imap.uid_search(["UID", 12345.., "MODSEQ", 620_162_338],
|
1997
|
+
# return: %w(all count min max))
|
1998
|
+
# # => #<data Net::IMAP::ESearchResult tag="RUBY0123", uid=true,
|
1999
|
+
# # data=[["ALL", Net::IMAP::SequenceSet["12346:12349,22222:22230"]],
|
2000
|
+
# # ["COUNT", 13], ["MIN", 12346], ["MAX", 22230],
|
2001
|
+
# # ["MODSEQ", 917162488]]>
|
2002
|
+
# result.to_a # => [12346, 12347, 12348, 12349, 22222, 22223, 22224,
|
2003
|
+
# # 22225, 22226, 22227, 22228, 22229, 22230]
|
2004
|
+
# result.uid? # => true
|
2005
|
+
# result.count # => 13
|
2006
|
+
# result.min # => 12346
|
2007
|
+
# result.max # => 22230
|
2008
|
+
# result.modseq # => 917162488
|
2009
|
+
#
|
2010
|
+
# Using +return+ options to limit the result to only min, max, and count:
|
2011
|
+
#
|
2012
|
+
# result = imap.uid_search(["UID", 12345..,], return: %w(count min max))
|
2013
|
+
# # => #<data Net::IMAP::ESearchResult tag="RUBY0124", uid=true,
|
2014
|
+
# # data=[["COUNT", 13], ["MIN", 12346], ["MAX", 22230]]>
|
2015
|
+
# result.to_a # => []
|
2016
|
+
# result.count # => 13
|
2017
|
+
# result.min # => 12346
|
2018
|
+
# result.max # => 22230
|
2019
|
+
#
|
2020
|
+
# Return options and charset may be sent as keyword args or embedded in the
|
2021
|
+
# +criteria+ arg, but they must be in the correct order: <tt>"RETURN (...)
|
2022
|
+
# CHARSET ... criteria..."</tt>. The following searches
|
2023
|
+
# send the exact same command to the server:
|
2024
|
+
#
|
2025
|
+
# # Return options and charset as keyword arguments (preferred)
|
2026
|
+
# imap.search(%w(OR UNSEEN FLAGGED), return: %w(MIN MAX), charset: "UTF-8")
|
2027
|
+
# # Embedding return and charset in the criteria array
|
2028
|
+
# imap.search(["RETURN", %w(MIN MAX), "CHARSET", "UTF-8", *%w(OR UNSEEN FLAGGED)])
|
2029
|
+
# # Embedding return and charset in the criteria string
|
2030
|
+
# imap.search("RETURN (MIN MAX) CHARSET UTF-8 OR UNSEEN FLAGGED")
|
2031
|
+
#
|
2032
|
+
# Sending charset as the second positional argument is supported for
|
2033
|
+
# backward compatibility. Future versions may print a deprecation warning:
|
2034
|
+
# imap.search(%w(OR UNSEEN FLAGGED), "UTF-8", return: %w(MIN MAX))
|
2035
|
+
#
|
2036
|
+
# ==== Argument translation
|
2037
|
+
#
|
2038
|
+
# [+return+ options]
|
2039
|
+
# Must be an Array. Return option names may be either strings or symbols.
|
2040
|
+
# +Range+ elements which begin and end with negative integers are encoded
|
2041
|
+
# for use with +PARTIAL+--any other ranges are converted to SequenceSet.
|
2042
|
+
# Unlike +criteria+, other return option arguments are not automatically
|
2043
|
+
# converted to SequenceSet.
|
2044
|
+
#
|
2045
|
+
# [When +criteria+ is an Array]
|
2046
|
+
# When the array begins with <tt>"RETURN"</tt> (case insensitive), the
|
2047
|
+
# second array element is translated like the +return+ parameter (as
|
2048
|
+
# described above).
|
2049
|
+
#
|
2050
|
+
# Every other member is a +SEARCH+ command argument:
|
2051
|
+
# [SequenceSet]
|
2052
|
+
# Encoded as an \IMAP +sequence-set+ with SequenceSet#valid_string.
|
2053
|
+
# [Set, Range, <tt>-1</tt>, +:*+, responds to +#to_sequence_set+]
|
2054
|
+
# Converted to SequenceSet for validation and encoding.
|
2055
|
+
# [nested sequence-set +Array+]
|
2056
|
+
# When every element in a nested array is one of the above types, a
|
2057
|
+
# positive +Integer+, a sequence-set formatted +String+, or a deeply
|
2058
|
+
# nested +Array+ of these same types, the array will be converted to
|
2059
|
+
# SequenceSet for validation and encoding.
|
2060
|
+
# [Any other nested +Array+]
|
2061
|
+
# Otherwise, a nested array is encoded as a parenthesized list, to
|
2062
|
+
# combine multiple search keys (e.g., for use with +OR+ and +NOT+).
|
2063
|
+
# [+String+]
|
2064
|
+
# Sent verbatim when it is a valid \IMAP +atom+, and encoded as an \IMAP
|
2065
|
+
# +quoted+ or +literal+ string otherwise. Every standard search key
|
2066
|
+
# name is a valid \IMAP +atom+ and every standard search key string
|
2067
|
+
# argument is an +astring+ which may be encoded as +atom+, +quoted+, or
|
2068
|
+
# +literal+.
|
2069
|
+
#
|
2070
|
+
# *Note:* <tt>*</tt> is not a valid \IMAP +atom+ character. Any string
|
2071
|
+
# containing <tt>*</tt> will be encoded as a +quoted+ string, _not_ a
|
2072
|
+
# +sequence-set+.
|
2073
|
+
# [+Integer+ (except for <tt>-1</tt>)]
|
2074
|
+
# Encoded using +#to_s+.
|
2075
|
+
# [+Date+]
|
2076
|
+
# Encoded as an \IMAP date (see ::encode_date).
|
2077
|
+
#
|
2078
|
+
# [When +criteria+ is a String]
|
2079
|
+
# +criteria+ will be sent directly to the server <em>without any
|
2080
|
+
# validation or encoding</em>.
|
2081
|
+
#
|
2082
|
+
# <em>*WARNING:* This is vulnerable to injection attacks when external
|
2083
|
+
# inputs are used.</em>
|
2084
|
+
#
|
2085
|
+
# ==== Return options
|
2086
|
+
#
|
2087
|
+
# For full definitions of the standard return options and return data, see
|
2088
|
+
# the relevant RFCs.
|
2089
|
+
#
|
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
|
+
# [+ALL+]
|
2097
|
+
# Returns ESearchResult#all with a SequenceSet of all matching sequence
|
2098
|
+
# numbers or UIDs. This is the default, when return options are empty.
|
2099
|
+
#
|
2100
|
+
# For compatibility with SearchResult, ESearchResult#to_a returns an
|
2101
|
+
# Array of message sequence numbers or UIDs.
|
2102
|
+
# [+COUNT+]
|
2103
|
+
# Returns ESearchResult#count with the number of matching messages.
|
2104
|
+
# [+MAX+]
|
2105
|
+
# Returns ESearchResult#max with the highest matching sequence number or
|
2106
|
+
# UID.
|
2107
|
+
# [+MIN+]
|
2108
|
+
# Returns ESearchResult#min with the lowest matching sequence number or
|
2109
|
+
# UID.
|
2110
|
+
#
|
2111
|
+
# ===== +CONDSTORE+
|
2112
|
+
#
|
2113
|
+
# ESearchResult#modseq return data does not have a corresponding return
|
2114
|
+
# option. Instead, it is returned if the +MODSEQ+ search key is used or
|
2115
|
+
# when the +CONDSTORE+ extension is enabled for the selected mailbox.
|
2116
|
+
# See [{RFC4731 §3.2}[https://www.rfc-editor.org/rfc/rfc4731#section-3.2]]
|
2117
|
+
# or [{RFC7162 §2.1.5}[https://www.rfc-editor.org/rfc/rfc7162#section-3.1.5]].
|
2118
|
+
#
|
2119
|
+
# ===== +RFC4466+ compatible extensions
|
2120
|
+
#
|
2121
|
+
# {RFC4466 §2.6}[https://www.rfc-editor.org/rfc/rfc4466.html#section-2.6]
|
2122
|
+
# defines standard syntax for search extensions. Net::IMAP allows sending
|
2123
|
+
# unknown search return options and will parse unknown search extensions'
|
2124
|
+
# return values into ExtensionData. Please note that this is an
|
2125
|
+
# intentionally _unstable_ API. Future releases may return different
|
2126
|
+
# (incompatible) objects, <em>without deprecation or warning</em>.
|
2127
|
+
#
|
2128
|
+
# ==== Search keys
|
1992
2129
|
#
|
1993
2130
|
# For full definitions of the standard search +criteria+,
|
1994
2131
|
# see [{IMAP4rev1 §6.4.4}[https://www.rfc-editor.org/rfc/rfc3501.html#section-6.4.4]],
|
@@ -2003,23 +2140,21 @@ module Net
|
|
2003
2140
|
# arguments. The number and type of arguments is specific to each search
|
2004
2141
|
# key.
|
2005
2142
|
#
|
2006
|
-
#
|
2007
|
-
# Matches every message in the mailbox.
|
2143
|
+
# ===== Search keys that match all messages
|
2008
2144
|
#
|
2009
|
-
#
|
2010
|
-
#
|
2011
|
-
# messages which match all contained search keys. Useful for +OR+, +NOT+,
|
2012
|
-
# and other search keys with _search-key_ arguments.
|
2145
|
+
# [+ALL+]
|
2146
|
+
# The default initial key. Matches every message in the mailbox.
|
2013
2147
|
#
|
2014
|
-
#
|
2148
|
+
# [+SAVEDATESUPPORTED+]
|
2149
|
+
# Matches every message in the mailbox when the mailbox supports the save
|
2150
|
+
# date attribute. Otherwise, it matches no messages.
|
2015
2151
|
#
|
2016
|
-
# +
|
2017
|
-
#
|
2152
|
+
# <em>Requires +SAVEDATE+ capability</em>.
|
2153
|
+
# {[RFC8514]}[https://www.rfc-editor.org/rfc/rfc8514.html#section-4.3]
|
2018
2154
|
#
|
2019
|
-
#
|
2020
|
-
# Matches messages which do not match _search-key_.
|
2155
|
+
# ===== Sequence set search keys
|
2021
2156
|
#
|
2022
|
-
# _sequence-set_
|
2157
|
+
# [_sequence-set_]
|
2023
2158
|
# Matches messages with message sequence numbers in _sequence-set_.
|
2024
2159
|
#
|
2025
2160
|
# _Note:_ this search key has no label.
|
@@ -2027,121 +2162,139 @@ module Net
|
|
2027
2162
|
# <em>+UIDONLY+ must *not* be enabled.</em>
|
2028
2163
|
# {[RFC9586]}[https://www.rfc-editor.org/rfc/rfc9586.html]
|
2029
2164
|
#
|
2030
|
-
# +UID+ _sequence-set_
|
2165
|
+
# [+UID+ _sequence-set_]
|
2031
2166
|
# Matches messages with a UID in _sequence-set_.
|
2032
2167
|
#
|
2033
|
-
#
|
2034
|
-
#
|
2168
|
+
# ===== Compound search keys
|
2169
|
+
#
|
2170
|
+
# [(_search-key_ _search-key_...)]
|
2171
|
+
# Combines one or more _search-key_ arguments to match
|
2172
|
+
# messages which match all contained search keys. Useful for +OR+, +NOT+,
|
2173
|
+
# and other search keys with _search-key_ arguments.
|
2174
|
+
#
|
2175
|
+
# _Note:_ this search key has no label.
|
2176
|
+
#
|
2177
|
+
# [+OR+ _search-key_ _search-key_]
|
2178
|
+
# Matches messages which match either _search-key_ argument.
|
2179
|
+
#
|
2180
|
+
# [+NOT+ _search-key_]
|
2181
|
+
# Matches messages which do not match _search-key_.
|
2182
|
+
#
|
2183
|
+
# [+FUZZY+ _search-key_]
|
2184
|
+
# Uses fuzzy matching for the specified search key.
|
2185
|
+
#
|
2186
|
+
# <em>Requires <tt>SEARCH=FUZZY</tt> capability.</em>
|
2187
|
+
# {[RFC6203]}[https://www.rfc-editor.org/rfc/rfc6203.html#section-6].
|
2188
|
+
#
|
2189
|
+
# ===== Flags search keys
|
2190
|
+
#
|
2191
|
+
# [+ANSWERED+, +UNANSWERED+]
|
2035
2192
|
# Matches messages with or without the <tt>\\Answered</tt> flag.
|
2036
|
-
# +DELETED
|
2037
|
-
# +UNDELETED+::
|
2193
|
+
# [+DELETED+, +UNDELETED+]
|
2038
2194
|
# Matches messages with or without the <tt>\\Deleted</tt> flag.
|
2039
|
-
# +DRAFT
|
2040
|
-
# +UNDRAFT+::
|
2195
|
+
# [+DRAFT+, +UNDRAFT+]
|
2041
2196
|
# Matches messages with or without the <tt>\\Draft</tt> flag.
|
2042
|
-
# +FLAGGED
|
2043
|
-
# +UNFLAGGED+::
|
2197
|
+
# [+FLAGGED+, +UNFLAGGED+]
|
2044
2198
|
# Matches messages with or without the <tt>\\Flagged</tt> flag.
|
2045
|
-
# +SEEN
|
2046
|
-
# +UNSEEN+::
|
2199
|
+
# [+SEEN+, +UNSEEN+]
|
2047
2200
|
# Matches messages with or without the <tt>\\Seen</tt> flag.
|
2048
|
-
#
|
2049
|
-
# +KEYWORD+ _keyword_::
|
2050
|
-
# +UNKEYWORD+ _keyword_::
|
2201
|
+
# [+KEYWORD+ _keyword_, +UNKEYWORD+ _keyword_]
|
2051
2202
|
# Matches messages with or without the specified _keyword_.
|
2052
2203
|
#
|
2053
|
-
# +
|
2054
|
-
# Matches
|
2055
|
-
#
|
2056
|
-
#
|
2057
|
-
# +
|
2058
|
-
#
|
2059
|
-
#
|
2060
|
-
#
|
2061
|
-
#
|
2062
|
-
#
|
2063
|
-
#
|
2064
|
-
# +
|
2204
|
+
# [+RECENT+, +UNRECENT+]
|
2205
|
+
# Matches messages with or without the <tt>\\Recent</tt> flag.
|
2206
|
+
#
|
2207
|
+
# *NOTE:* The <tt>\\Recent</tt> flag has been removed from +IMAP4rev2+.
|
2208
|
+
# [+NEW+]
|
2209
|
+
# Equivalent to <tt>(RECENT UNSEEN)</tt>.
|
2210
|
+
#
|
2211
|
+
# *NOTE:* The <tt>\\Recent</tt> flag has been removed from +IMAP4rev2+.
|
2212
|
+
#
|
2213
|
+
# ===== Header field substring search keys
|
2214
|
+
#
|
2215
|
+
# [+BCC+ _substring_]
|
2216
|
+
# Matches when _substring_ is in the envelope's +BCC+ field.
|
2217
|
+
# [+CC+ _substring_]
|
2218
|
+
# Matches when _substring_ is in the envelope's +CC+ field.
|
2219
|
+
# [+FROM+ _substring_]
|
2220
|
+
# Matches when _substring_ is in the envelope's +FROM+ field.
|
2221
|
+
# [+SUBJECT+ _substring_]
|
2222
|
+
# Matches when _substring_ is in the envelope's +SUBJECT+ field.
|
2223
|
+
# [+TO+ _substring_]
|
2224
|
+
# Matches when _substring_ is in the envelope's +TO+ field.
|
2225
|
+
#
|
2226
|
+
# [+HEADER+ _field_ _substring_]
|
2065
2227
|
# Matches when _substring_ is in the specified header _field_.
|
2066
2228
|
#
|
2067
|
-
#
|
2229
|
+
# ===== Body text search keys
|
2230
|
+
# [+BODY+ _string_]
|
2068
2231
|
# Matches when _string_ is in the body of the message.
|
2069
2232
|
# Does not match on header fields.
|
2070
2233
|
#
|
2071
2234
|
# The server _may_ use flexible matching, rather than simple substring
|
2072
2235
|
# matches. For example, this may use stemming or match only full words.
|
2073
2236
|
#
|
2074
|
-
# +TEXT+ _string_
|
2237
|
+
# [+TEXT+ _string_]
|
2075
2238
|
# Matches when _string_ is in the header or body of the message.
|
2076
2239
|
#
|
2077
2240
|
# The server _may_ use flexible matching, rather than simple substring
|
2078
2241
|
# matches. For example, this may use stemming or match only full words.
|
2079
2242
|
#
|
2080
|
-
#
|
2081
|
-
# +ON+ _date_::
|
2082
|
-
# +SINCE+ _date_::
|
2083
|
-
# Matches when the +INTERNALDATE+ is earlier than, on, or later than
|
2084
|
-
# _date_.
|
2243
|
+
# ===== Date/Time search keys
|
2085
2244
|
#
|
2086
|
-
# +SENTBEFORE+ _date_
|
2087
|
-
# +SENTON+ _date_
|
2088
|
-
# +SENTSINCE+ _date_
|
2245
|
+
# [+SENTBEFORE+ _date_]
|
2246
|
+
# [+SENTON+ _date_]
|
2247
|
+
# [+SENTSINCE+ _date_]
|
2089
2248
|
# Matches when the +Date+ header is earlier than, on, or later than _date_.
|
2090
2249
|
#
|
2091
|
-
# +
|
2092
|
-
# +
|
2093
|
-
#
|
2094
|
-
#
|
2095
|
-
#
|
2096
|
-
#
|
2097
|
-
# The <tt>\\Recent</tt> flag has been removed from +IMAP4rev2+. So these
|
2098
|
-
# search keys require the +IMAP4rev1+ capability.
|
2250
|
+
# [+BEFORE+ _date_]
|
2251
|
+
# [+ON+ _date_]
|
2252
|
+
# [+SINCE+ _date_]
|
2253
|
+
# Matches when the +INTERNALDATE+ is earlier than, on, or later than
|
2254
|
+
# _date_.
|
2099
2255
|
#
|
2100
|
-
# +
|
2101
|
-
# +
|
2102
|
-
# Matches
|
2256
|
+
# [+OLDER+ _interval_]
|
2257
|
+
# [+YOUNGER+ _interval_]
|
2258
|
+
# Matches when the +INTERNALDATE+ is more/less than _interval_ seconds ago.
|
2103
2259
|
#
|
2104
|
-
# +
|
2105
|
-
#
|
2260
|
+
# <em>Requires +WITHIN+ capability</em>.
|
2261
|
+
# {[RFC5032]}[https://www.rfc-editor.org/rfc/rfc5032.html]
|
2106
2262
|
#
|
2107
|
-
#
|
2263
|
+
# [+SAVEDBEFORE+ _date_]
|
2264
|
+
# [+SAVEDON+ _date_]
|
2265
|
+
# [+SAVEDSINCE+ _date_]
|
2266
|
+
# Matches when the save date is earlier than, on, or later than _date_.
|
2108
2267
|
#
|
2109
|
-
#
|
2268
|
+
# <em>Requires +SAVEDATE+ capability.</em>
|
2269
|
+
# {[RFC8514]}[https://www.rfc-editor.org/rfc/rfc8514.html#section-4.3]
|
2110
2270
|
#
|
2111
|
-
#
|
2112
|
-
# +YOUNGER+ _interval_::
|
2113
|
-
# Matches when +INTERNALDATE+ is more/less than _interval_ seconds ago.
|
2271
|
+
# ===== Other message attribute search keys
|
2114
2272
|
#
|
2115
|
-
#
|
2116
|
-
#
|
2273
|
+
# [+SMALLER+ _bytes_]
|
2274
|
+
# [+LARGER+ _bytes_]
|
2275
|
+
# Matches when +RFC822.SIZE+ is smaller or larger than _bytes_.
|
2117
2276
|
#
|
2118
|
-
# +ANNOTATION+ _entry_ _attr_ _value_
|
2277
|
+
# [+ANNOTATION+ _entry_ _attr_ _value_]
|
2119
2278
|
# Matches messages that have annotations with entries matching _entry_,
|
2120
2279
|
# attributes matching _attr_, and _value_ in the attribute's values.
|
2121
2280
|
#
|
2122
|
-
# <em>Requires
|
2281
|
+
# <em>Requires +ANNOTATE-EXPERIMENT-1+ capability</em>.
|
2123
2282
|
# {[RFC5257]}[https://www.rfc-editor.org/rfc/rfc5257.html].
|
2124
2283
|
#
|
2125
|
-
# +FILTER+ _filter_
|
2284
|
+
# [+FILTER+ _filter_]
|
2126
2285
|
# References a _filter_ that is stored on the server and matches all
|
2127
2286
|
# messages which would be matched by that filter's search criteria.
|
2128
2287
|
#
|
2129
|
-
# <em>Requires
|
2288
|
+
# <em>Requires +FILTERS+ capability</em>.
|
2130
2289
|
# {[RFC5466]}[https://www.rfc-editor.org/rfc/rfc5466.html#section-3.1]
|
2131
2290
|
#
|
2132
|
-
# +
|
2133
|
-
# Uses fuzzy matching for the specified search key.
|
2134
|
-
#
|
2135
|
-
# <em>Requires the <tt>SEARCH=FUZZY</tt> capability.</em>
|
2136
|
-
# {[RFC6203]}[https://www.rfc-editor.org/rfc/rfc6203.html#section-6].
|
2137
|
-
#
|
2138
|
-
# +MODSEQ+ _modseq_::
|
2291
|
+
# [+MODSEQ+ _modseq_]
|
2139
2292
|
# Matches when +MODSEQ+ is greater than or equal to _modseq_.
|
2140
2293
|
#
|
2141
|
-
# <em>Requires
|
2294
|
+
# <em>Requires +CONDSTORE+ capability</em>.
|
2142
2295
|
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1.5].
|
2143
2296
|
#
|
2144
|
-
# +MODSEQ+ _entry_ _entry-type_ _modseq_
|
2297
|
+
# [+MODSEQ+ _entry_ _entry-type_ _modseq_]
|
2145
2298
|
# Matches when a specific metadata _entry_ has been updated since
|
2146
2299
|
# _modseq_.
|
2147
2300
|
#
|
@@ -2150,33 +2303,25 @@ module Net
|
|
2150
2303
|
# <tt>\\</tt> prefix. _entry-type_ can be one of <tt>"shared"</tt>,
|
2151
2304
|
# <tt>"priv"</tt> (private), or <tt>"all"</tt>.
|
2152
2305
|
#
|
2153
|
-
# <em>Requires
|
2306
|
+
# <em>Requires +CONDSTORE+ capability</em>.
|
2154
2307
|
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1.5].
|
2155
2308
|
#
|
2156
|
-
# +EMAILID+ _objectid_
|
2157
|
-
# +THREADID+ _objectid_
|
2309
|
+
# [+EMAILID+ _objectid_]
|
2310
|
+
# [+THREADID+ _objectid_]
|
2158
2311
|
# Matches when +EMAILID+/+THREADID+ is equal to _objectid_
|
2159
2312
|
# (substring matches are not supported).
|
2160
2313
|
#
|
2161
|
-
# <em>Requires
|
2314
|
+
# <em>Requires +OBJECTID+ capability</em>.
|
2162
2315
|
# {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html#section-6]
|
2163
2316
|
#
|
2164
|
-
#
|
2165
|
-
# Matches every message in the mailbox when the mailbox supports the save
|
2166
|
-
# date attribute. Otherwise, it matches no messages.
|
2167
|
-
#
|
2168
|
-
# <em>Requires the +SAVEDATE+ capability</em>.
|
2169
|
-
# {[RFC8514]}[https://www.rfc-editor.org/rfc/rfc8514.html#section-4.3]
|
2170
|
-
#
|
2171
|
-
# +SAVEDBEFORE+ _date_::
|
2172
|
-
# +SAVEDON+ _date_::
|
2173
|
-
# +SAVEDSINCE+ _date_::
|
2174
|
-
# Matches when the save date is earlier than, on, or later than _date_.
|
2317
|
+
# ==== Capabilities
|
2175
2318
|
#
|
2176
|
-
#
|
2177
|
-
#
|
2319
|
+
# Return options should only be specified when the server supports
|
2320
|
+
# +IMAP4rev2+ or an extension that allows them, such as +ESEARCH+
|
2321
|
+
# [RFC4731[https://rfc-editor.org/rfc/rfc4731#section-3.1]].
|
2178
2322
|
#
|
2179
|
-
#
|
2323
|
+
# When +IMAP4rev2+ is enabled, or when the server supports +IMAP4rev2+ but
|
2324
|
+
# not +IMAP4rev1+, ESearchResult is always returned instead of SearchResult.
|
2180
2325
|
#
|
2181
2326
|
# If CONDSTORE[https://www.rfc-editor.org/rfc/rfc7162.html] is supported
|
2182
2327
|
# and enabled for the selected mailbox, a non-empty SearchResult will
|
@@ -2191,6 +2336,7 @@ module Net
|
|
2191
2336
|
|
2192
2337
|
# :call-seq:
|
2193
2338
|
# uid_search(criteria, charset = nil) -> result
|
2339
|
+
# uid_search(criteria, charset: nil, return: nil) -> result
|
2194
2340
|
#
|
2195
2341
|
# Sends a {UID SEARCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
|
2196
2342
|
# to search the mailbox for messages that match the given searching
|
@@ -2230,7 +2376,7 @@ module Net
|
|
2230
2376
|
#
|
2231
2377
|
# Related: #uid_search, FetchData
|
2232
2378
|
#
|
2233
|
-
#
|
2379
|
+
# ==== For example:
|
2234
2380
|
#
|
2235
2381
|
# p imap.fetch(6..8, "UID")
|
2236
2382
|
# #=> [#<Net::IMAP::FetchData seqno=6, attr={"UID"=>98}>, \\
|
@@ -2248,7 +2394,7 @@ module Net
|
|
2248
2394
|
# p data.attr["UID"]
|
2249
2395
|
# #=> 98
|
2250
2396
|
#
|
2251
|
-
#
|
2397
|
+
# ==== Capabilities
|
2252
2398
|
#
|
2253
2399
|
# Many extensions define new message +attr+ names. See FetchData for a list
|
2254
2400
|
# of supported extension fields.
|
@@ -2277,7 +2423,7 @@ module Net
|
|
2277
2423
|
#
|
2278
2424
|
# Related: #fetch, FetchData
|
2279
2425
|
#
|
2280
|
-
#
|
2426
|
+
# ==== Capabilities
|
2281
2427
|
# Same as #fetch.
|
2282
2428
|
def uid_fetch(set, attr, mod = nil, changedsince: nil)
|
2283
2429
|
fetch_internal("UID FETCH", set, attr, mod, changedsince: changedsince)
|
@@ -2311,14 +2457,14 @@ module Net
|
|
2311
2457
|
#
|
2312
2458
|
# Related: #uid_store
|
2313
2459
|
#
|
2314
|
-
#
|
2460
|
+
# ==== For example:
|
2315
2461
|
#
|
2316
2462
|
# p imap.store(6..8, "+FLAGS", [:Deleted])
|
2317
2463
|
# #=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>,
|
2318
2464
|
# #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>,
|
2319
2465
|
# #<Net::IMAP::FetchData seqno=8, attr={"FLAGS"=>[:Seen, :Deleted]}>]
|
2320
2466
|
#
|
2321
|
-
#
|
2467
|
+
# ==== Capabilities
|
2322
2468
|
#
|
2323
2469
|
# Extensions may define new data items to be used with #store.
|
2324
2470
|
#
|
@@ -2342,7 +2488,7 @@ module Net
|
|
2342
2488
|
#
|
2343
2489
|
# Related: #store
|
2344
2490
|
#
|
2345
|
-
#
|
2491
|
+
# ==== Capabilities
|
2346
2492
|
# Same as #store.
|
2347
2493
|
def uid_store(set, attr, flags, unchangedsince: nil)
|
2348
2494
|
store_internal("UID STORE", set, attr, flags, unchangedsince: unchangedsince)
|
@@ -2355,7 +2501,7 @@ module Net
|
|
2355
2501
|
#
|
2356
2502
|
# Related: #uid_copy
|
2357
2503
|
#
|
2358
|
-
#
|
2504
|
+
# ==== Capabilities
|
2359
2505
|
#
|
2360
2506
|
# If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
|
2361
2507
|
# supported, the server's response should include a +COPYUID+ response code
|
@@ -2372,7 +2518,7 @@ module Net
|
|
2372
2518
|
#
|
2373
2519
|
# Similar to #copy, but +set+ contains unique identifiers.
|
2374
2520
|
#
|
2375
|
-
#
|
2521
|
+
# ==== Capabilities
|
2376
2522
|
#
|
2377
2523
|
# +UIDPLUS+ affects #uid_copy the same way it affects #copy.
|
2378
2524
|
def uid_copy(set, mailbox)
|
@@ -2387,7 +2533,7 @@ module Net
|
|
2387
2533
|
#
|
2388
2534
|
# Related: #uid_move
|
2389
2535
|
#
|
2390
|
-
#
|
2536
|
+
# ==== Capabilities
|
2391
2537
|
#
|
2392
2538
|
# The server's capabilities must include +MOVE+
|
2393
2539
|
# [RFC6851[https://tools.ietf.org/html/rfc6851]].
|
@@ -2411,7 +2557,7 @@ module Net
|
|
2411
2557
|
#
|
2412
2558
|
# Related: #move
|
2413
2559
|
#
|
2414
|
-
#
|
2560
|
+
# ==== Capabilities
|
2415
2561
|
#
|
2416
2562
|
# Same as #move: The server's capabilities must include +MOVE+
|
2417
2563
|
# [RFC6851[https://tools.ietf.org/html/rfc6851]]. +UIDPLUS+ also affects
|
@@ -2431,14 +2577,14 @@ module Net
|
|
2431
2577
|
#
|
2432
2578
|
# Related: #uid_sort, #search, #uid_search, #thread, #uid_thread
|
2433
2579
|
#
|
2434
|
-
#
|
2580
|
+
# ==== For example:
|
2435
2581
|
#
|
2436
2582
|
# p imap.sort(["FROM"], ["ALL"], "US-ASCII")
|
2437
2583
|
# #=> [1, 2, 3, 5, 6, 7, 8, 4, 9]
|
2438
2584
|
# p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII")
|
2439
2585
|
# #=> [6, 7, 8, 1]
|
2440
2586
|
#
|
2441
|
-
#
|
2587
|
+
# ==== Capabilities
|
2442
2588
|
#
|
2443
2589
|
# The server's capabilities must include +SORT+
|
2444
2590
|
# [RFC5256[https://tools.ietf.org/html/rfc5256]].
|
@@ -2453,7 +2599,7 @@ module Net
|
|
2453
2599
|
#
|
2454
2600
|
# Related: #sort, #search, #uid_search, #thread, #uid_thread
|
2455
2601
|
#
|
2456
|
-
#
|
2602
|
+
# ==== Capabilities
|
2457
2603
|
#
|
2458
2604
|
# The server's capabilities must include +SORT+
|
2459
2605
|
# [RFC5256[https://tools.ietf.org/html/rfc5256]].
|
@@ -2478,7 +2624,7 @@ module Net
|
|
2478
2624
|
#
|
2479
2625
|
# Related: #uid_thread, #search, #uid_search, #sort, #uid_sort
|
2480
2626
|
#
|
2481
|
-
#
|
2627
|
+
# ==== Capabilities
|
2482
2628
|
#
|
2483
2629
|
# The server's capabilities must include +THREAD+
|
2484
2630
|
# [RFC5256[https://tools.ietf.org/html/rfc5256]].
|
@@ -2492,7 +2638,7 @@ module Net
|
|
2492
2638
|
#
|
2493
2639
|
# Related: #thread, #search, #uid_search, #sort, #uid_sort
|
2494
2640
|
#
|
2495
|
-
#
|
2641
|
+
# ==== Capabilities
|
2496
2642
|
#
|
2497
2643
|
# The server's capabilities must include +THREAD+
|
2498
2644
|
# [RFC5256[https://tools.ietf.org/html/rfc5256]].
|
@@ -2511,7 +2657,7 @@ module Net
|
|
2511
2657
|
#
|
2512
2658
|
# Related: #capable?, #capabilities, #capability
|
2513
2659
|
#
|
2514
|
-
#
|
2660
|
+
# ==== Capabilities
|
2515
2661
|
#
|
2516
2662
|
# The server's capabilities must include
|
2517
2663
|
# +ENABLE+ [RFC5161[https://tools.ietf.org/html/rfc5161]]
|
@@ -2613,7 +2759,7 @@ module Net
|
|
2613
2759
|
#
|
2614
2760
|
# Related: #idle_done, #noop, #check
|
2615
2761
|
#
|
2616
|
-
#
|
2762
|
+
# ==== Capabilities
|
2617
2763
|
#
|
2618
2764
|
# The server's capabilities must include +IDLE+
|
2619
2765
|
# [RFC2177[https://tools.ietf.org/html/rfc2177]].
|
@@ -2730,7 +2876,7 @@ module Net
|
|
2730
2876
|
#
|
2731
2877
|
# Related: #extract_responses, #clear_responses, #response_handlers, #greeting
|
2732
2878
|
#
|
2733
|
-
#
|
2879
|
+
# ==== Thread safety
|
2734
2880
|
# >>>
|
2735
2881
|
# *Note:* Access to the responses hash is synchronized for thread-safety.
|
2736
2882
|
# The receiver thread and response_handlers cannot process new responses
|
@@ -2744,7 +2890,7 @@ module Net
|
|
2744
2890
|
# thread, but will not modify any responses after adding them to the
|
2745
2891
|
# responses hash.
|
2746
2892
|
#
|
2747
|
-
#
|
2893
|
+
# ==== Clearing responses
|
2748
2894
|
#
|
2749
2895
|
# Previously unhandled responses are automatically cleared before entering a
|
2750
2896
|
# mailbox with #select or #examine. Long-lived connections can receive many
|
@@ -2753,7 +2899,7 @@ module Net
|
|
2753
2899
|
# the block, or remove responses with #extract_responses, #clear_responses,
|
2754
2900
|
# or #add_response_handler.
|
2755
2901
|
#
|
2756
|
-
#
|
2902
|
+
# ==== Missing responses
|
2757
2903
|
#
|
2758
2904
|
# Only non-+nil+ data is stored. Many important response codes have no data
|
2759
2905
|
# of their own, but are used as "tags" on the ResponseText object they are
|
@@ -3131,12 +3277,108 @@ module Net
|
|
3131
3277
|
end
|
3132
3278
|
end
|
3133
3279
|
|
3134
|
-
def
|
3135
|
-
keys = normalize_searching_criteria(keys)
|
3136
|
-
args = charset ? ["CHARSET", charset, *keys] : keys
|
3280
|
+
def expunge_internal(...)
|
3137
3281
|
synchronize do
|
3138
|
-
send_command(
|
3139
|
-
clear_responses("
|
3282
|
+
send_command(...)
|
3283
|
+
expunged_array = clear_responses("EXPUNGE")
|
3284
|
+
vanished_array = extract_responses("VANISHED") { !_1.earlier? }
|
3285
|
+
if vanished_array.empty?
|
3286
|
+
expunged_array
|
3287
|
+
elsif vanished_array.length == 1
|
3288
|
+
vanished_array.first
|
3289
|
+
else
|
3290
|
+
merged_uids = SequenceSet[*vanished_array.map(&:uids)]
|
3291
|
+
VanishedData[uids: merged_uids, earlier: false]
|
3292
|
+
end
|
3293
|
+
end
|
3294
|
+
end
|
3295
|
+
|
3296
|
+
RETURN_WHOLE = /\ARETURN\z/i
|
3297
|
+
RETURN_START = /\ARETURN\b/i
|
3298
|
+
private_constant :RETURN_WHOLE, :RETURN_START
|
3299
|
+
|
3300
|
+
def search_args(keys, charset_arg = nil, return: nil, charset: nil)
|
3301
|
+
{return:} => {return: return_kw}
|
3302
|
+
case [return_kw, keys]
|
3303
|
+
in [nil, Array[RETURN_WHOLE, return_opts, *keys]]
|
3304
|
+
return_opts = convert_return_opts(return_opts)
|
3305
|
+
esearch = true
|
3306
|
+
in [nil => return_opts, RETURN_START]
|
3307
|
+
esearch = true
|
3308
|
+
in [nil => return_opts, keys]
|
3309
|
+
esearch = false
|
3310
|
+
in [_, Array[RETURN_WHOLE, _, *] | RETURN_START]
|
3311
|
+
raise ArgumentError, "conflicting return options"
|
3312
|
+
in [_, Array[RETURN_WHOLE, _, *]] # workaround for https://bugs.ruby-lang.org/issues/20956
|
3313
|
+
raise ArgumentError, "conflicting return options"
|
3314
|
+
in [_, RETURN_START] # workaround for https://bugs.ruby-lang.org/issues/20956
|
3315
|
+
raise ArgumentError, "conflicting return options"
|
3316
|
+
in [return_opts, keys]
|
3317
|
+
return_opts = convert_return_opts(return_opts)
|
3318
|
+
esearch = true
|
3319
|
+
end
|
3320
|
+
if charset && charset_arg
|
3321
|
+
raise ArgumentError, "multiple charset arguments"
|
3322
|
+
end
|
3323
|
+
charset ||= charset_arg
|
3324
|
+
# NOTE: not handling combined RETURN and CHARSET for raw strings
|
3325
|
+
if charset && keys in /\ACHARSET\b/i | Array[/\ACHARSET\z/i, *]
|
3326
|
+
raise ArgumentError, "multiple charset arguments"
|
3327
|
+
end
|
3328
|
+
args = normalize_searching_criteria(keys)
|
3329
|
+
args.prepend("CHARSET", charset) if charset
|
3330
|
+
args.prepend("RETURN", return_opts) if return_opts
|
3331
|
+
return args, esearch
|
3332
|
+
end
|
3333
|
+
|
3334
|
+
def convert_return_opts(unconverted)
|
3335
|
+
return_opts = Array.try_convert(unconverted) or
|
3336
|
+
raise TypeError, "expected return options to be Array, got %s" % [
|
3337
|
+
unconverted.class
|
3338
|
+
]
|
3339
|
+
return_opts.map {|opt|
|
3340
|
+
case opt
|
3341
|
+
when Symbol then opt.to_s
|
3342
|
+
when Range then partial_range_last_or_seqset(opt)
|
3343
|
+
else opt
|
3344
|
+
end
|
3345
|
+
}
|
3346
|
+
end
|
3347
|
+
|
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
|
+
def search_internal(cmd, ...)
|
3360
|
+
args, esearch = search_args(...)
|
3361
|
+
synchronize do
|
3362
|
+
tagged = send_command(cmd, *args)
|
3363
|
+
tag = tagged.tag
|
3364
|
+
# Only the last ESEARCH or SEARCH is used. Excess results are ignored.
|
3365
|
+
esearch_result = extract_responses("ESEARCH") {|response|
|
3366
|
+
response in ESearchResult(tag: ^tag)
|
3367
|
+
}.last
|
3368
|
+
search_result = clear_responses("SEARCH").last
|
3369
|
+
if esearch_result
|
3370
|
+
# silently ignore SEARCH results, if any
|
3371
|
+
esearch_result
|
3372
|
+
elsif search_result
|
3373
|
+
# warn EXPECTED_ESEARCH_RESULT if esearch
|
3374
|
+
search_result
|
3375
|
+
elsif esearch
|
3376
|
+
# warn NO_SEARCH_RESPONSE
|
3377
|
+
ESearchResult[tag:, uid: cmd.start_with?("UID ")]
|
3378
|
+
else
|
3379
|
+
# warn NO_SEARCH_RESPONSE
|
3380
|
+
SearchResult[]
|
3381
|
+
end
|
3140
3382
|
end
|
3141
3383
|
end
|
3142
3384
|
|
@@ -3198,7 +3440,7 @@ module Net
|
|
3198
3440
|
end
|
3199
3441
|
|
3200
3442
|
def normalize_searching_criteria(criteria)
|
3201
|
-
return RawData.new(criteria) if criteria.is_a?(String)
|
3443
|
+
return [RawData.new(criteria)] if criteria.is_a?(String)
|
3202
3444
|
criteria.map {|i|
|
3203
3445
|
if coerce_search_arg_to_seqset?(i)
|
3204
3446
|
SequenceSet[i]
|
@@ -3276,6 +3518,7 @@ require_relative "imap/errors"
|
|
3276
3518
|
require_relative "imap/config"
|
3277
3519
|
require_relative "imap/command_data"
|
3278
3520
|
require_relative "imap/data_encoding"
|
3521
|
+
require_relative "imap/data_lite"
|
3279
3522
|
require_relative "imap/flags"
|
3280
3523
|
require_relative "imap/response_data"
|
3281
3524
|
require_relative "imap/response_parser"
|