net-imap 0.4.4 → 0.4.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/pages.yml +2 -2
- data/.github/workflows/test.yml +1 -1
- data/.gitignore +2 -1
- data/docs/styles.css +0 -12
- data/lib/net/imap/data_encoding.rb +14 -2
- data/lib/net/imap/fetch_data.rb +518 -0
- data/lib/net/imap/response_data.rb +88 -210
- data/lib/net/imap/response_parser/parser_utils.rb +1 -1
- data/lib/net/imap/response_parser.rb +531 -281
- data/lib/net/imap/search_result.rb +150 -0
- data/lib/net/imap/sequence_set.rb +1414 -0
- data/lib/net/imap.rb +238 -45
- data/net-imap.gemspec +1 -0
- data/rakelib/benchmarks.rake +4 -11
- metadata +7 -3
data/lib/net/imap.rb
CHANGED
@@ -404,18 +404,16 @@ module Net
|
|
404
404
|
#
|
405
405
|
# Although IMAP4rev2[https://tools.ietf.org/html/rfc9051] is not supported
|
406
406
|
# yet, Net::IMAP supports several extensions that have been folded into it:
|
407
|
-
# +ENABLE+, +IDLE+, +MOVE+, +NAMESPACE+, +SASL-IR+, +UIDPLUS+,
|
407
|
+
# +ENABLE+, +IDLE+, +MOVE+, +NAMESPACE+, +SASL-IR+, +UIDPLUS+, +UNSELECT+,
|
408
|
+
# <tt>STATUS=SIZE</tt>, and the fetch side of +BINARY+.
|
408
409
|
# Commands for these extensions are listed with the {Core IMAP
|
409
410
|
# commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands], above.
|
410
411
|
#
|
411
412
|
# >>>
|
412
413
|
# <em>The following are folded into +IMAP4rev2+ but are currently
|
413
414
|
# unsupported or incompletely supported by</em> Net::IMAP<em>: RFC4466
|
414
|
-
# extensions, +ESEARCH+, +SEARCHRES+, +LIST-EXTENDED+,
|
415
|
-
# +
|
416
|
-
# following extensions are implicitly supported, but will be updated with
|
417
|
-
# more direct support: RFC5530 response codes, <tt>STATUS=SIZE</tt>, and
|
418
|
-
# <tt>STATUS=DELETED</tt>.</em>
|
415
|
+
# extensions, +ESEARCH+, +SEARCHRES+, +LIST-EXTENDED+, +LIST-STATUS+,
|
416
|
+
# +LITERAL-+, and +SPECIAL-USE+.</em>
|
419
417
|
#
|
420
418
|
# ==== RFC2087: +QUOTA+
|
421
419
|
# - #getquota: returns the resource usage and limits for a quota root
|
@@ -437,6 +435,15 @@ module Net
|
|
437
435
|
# ==== RFC2971: +ID+
|
438
436
|
# - #id: exchanges client and server implementation information.
|
439
437
|
#
|
438
|
+
# ==== RFC3516: +BINARY+
|
439
|
+
# The fetch side of +BINARY+ has been folded into
|
440
|
+
# IMAP4rev2[https://tools.ietf.org/html/rfc9051].
|
441
|
+
# - Updates #fetch and #uid_fetch with the +BINARY+, +BINARY.PEEK+, and
|
442
|
+
# +BINARY.SIZE+ items. See FetchData#binary and FetchData#binary_size.
|
443
|
+
#
|
444
|
+
# >>>
|
445
|
+
# *NOTE:* The binary extension the #append command is _not_ supported yet.
|
446
|
+
#
|
440
447
|
# ==== RFC3691: +UNSELECT+
|
441
448
|
# Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051] and also included
|
442
449
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
@@ -474,9 +481,17 @@ module Net
|
|
474
481
|
# which arranges the results into ordered groups or threads according to a
|
475
482
|
# chosen algorithm.
|
476
483
|
#
|
477
|
-
# ==== +
|
484
|
+
# ==== +X-GM-EXT-1+
|
485
|
+
# +X-GM-EXT-1+ is a non-standard Gmail extension. See {Google's
|
486
|
+
# documentation}[https://developers.google.com/gmail/imap/imap-extensions].
|
487
|
+
# - Updates #fetch and #uid_fetch with support for +X-GM-MSGID+ (unique
|
488
|
+
# message ID), +X-GM-THRID+ (thread ID), and +X-GM-LABELS+ (Gmail labels).
|
489
|
+
# - Updates #search with the +X-GM-RAW+ search attribute.
|
478
490
|
# - #xlist: replaced by +SPECIAL-USE+ attributes in #list responses.
|
479
491
|
#
|
492
|
+
# *NOTE:* The +OBJECTID+ extension should replace +X-GM-MSGID+ and
|
493
|
+
# +X-GM-THRID+, but Gmail does not support it (as of 2023-11-10).
|
494
|
+
#
|
480
495
|
# ==== RFC6851: +MOVE+
|
481
496
|
# Folded into IMAP4rev2[https://tools.ietf.org/html/rfc9051] and also included
|
482
497
|
# above with {Core IMAP commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands].
|
@@ -487,6 +502,32 @@ module Net
|
|
487
502
|
#
|
488
503
|
# - See #enable for information about support for UTF-8 string encoding.
|
489
504
|
#
|
505
|
+
# ==== RFC7162: +CONDSTORE+
|
506
|
+
#
|
507
|
+
# - Updates #enable with +CONDSTORE+ parameter. +CONDSTORE+ will also be
|
508
|
+
# enabled by using any of the extension's command parameters, listed below.
|
509
|
+
# - Updates #status with the +HIGHESTMODSEQ+ status attribute.
|
510
|
+
# - Updates #select and #examine with the +condstore+ modifier, and adds
|
511
|
+
# either a +HIGHESTMODSEQ+ or +NOMODSEQ+ ResponseCode to the responses.
|
512
|
+
# - Updates #search, #uid_search, #sort, and #uid_sort with the +MODSEQ+
|
513
|
+
# search criterion, and adds SearchResult#modseq to the search response.
|
514
|
+
# - Updates #thread and #uid_thread with the +MODSEQ+ search criterion
|
515
|
+
# <em>(but thread responses are unchanged)</em>.
|
516
|
+
# - Updates #fetch and #uid_fetch with the +changedsince+ modifier and
|
517
|
+
# +MODSEQ+ FetchData attribute.
|
518
|
+
# - Updates #store and #uid_store with the +unchangedsince+ modifier and adds
|
519
|
+
# the +MODIFIED+ ResponseCode to the tagged response.
|
520
|
+
#
|
521
|
+
# ==== RFC8438: <tt>STATUS=SIZE</tt>
|
522
|
+
# - Updates #status with the +SIZE+ status attribute.
|
523
|
+
#
|
524
|
+
# ==== RFC8474: +OBJECTID+
|
525
|
+
# - Adds +MAILBOXID+ ResponseCode to #create tagged response.
|
526
|
+
# - Adds +MAILBOXID+ ResponseCode to #select and #examine untagged response.
|
527
|
+
# - Updates #fetch and #uid_fetch with the +EMAILID+ and +THREADID+ items.
|
528
|
+
# See FetchData#emailid and FetchData#emailid.
|
529
|
+
# - Updates #status with support for the +MAILBOXID+ status attribute.
|
530
|
+
#
|
490
531
|
# == References
|
491
532
|
#
|
492
533
|
# [{IMAP4rev1}[https://www.rfc-editor.org/rfc/rfc3501.html]]::
|
@@ -612,6 +653,10 @@ module Net
|
|
612
653
|
# [ID[https://tools.ietf.org/html/rfc2971]]::
|
613
654
|
# Showalter, T., "IMAP4 ID extension", RFC 2971, DOI 10.17487/RFC2971,
|
614
655
|
# October 2000, <https://www.rfc-editor.org/info/rfc2971>.
|
656
|
+
# [BINARY[https://tools.ietf.org/html/rfc3516]]::
|
657
|
+
# Nerenberg, L., "IMAP4 Binary Content Extension", RFC 3516,
|
658
|
+
# DOI 10.17487/RFC3516, April 2003,
|
659
|
+
# <https://www.rfc-editor.org/info/rfc3516>.
|
615
660
|
# [ACL[https://tools.ietf.org/html/rfc4314]]::
|
616
661
|
# Melnikov, A., "IMAP4 Access Control List (ACL) Extension", RFC 4314,
|
617
662
|
# DOI 10.17487/RFC4314, December 2005,
|
@@ -640,6 +685,16 @@ module Net
|
|
640
685
|
# Resnick, P., Ed., Newman, C., Ed., and S. Shen, Ed.,
|
641
686
|
# "IMAP Support for UTF-8", RFC 6855, DOI 10.17487/RFC6855, March 2013,
|
642
687
|
# <https://www.rfc-editor.org/info/rfc6855>.
|
688
|
+
# [CONDSTORE[https://tools.ietf.org/html/rfc7162]]::
|
689
|
+
# [QRESYNC[https://tools.ietf.org/html/rfc7162]]::
|
690
|
+
# Melnikov, A. and D. Cridland, "IMAP Extensions: Quick Flag Changes
|
691
|
+
# Resynchronization (CONDSTORE) and Quick Mailbox Resynchronization
|
692
|
+
# (QRESYNC)", RFC 7162, DOI 10.17487/RFC7162, May 2014,
|
693
|
+
# <https://www.rfc-editor.org/info/rfc7162>.
|
694
|
+
# [OBJECTID[https://tools.ietf.org/html/rfc8474]]::
|
695
|
+
# Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
|
696
|
+
# RFC 8474, DOI 10.17487/RFC8474, September 2018,
|
697
|
+
# <https://www.rfc-editor.org/info/rfc8474>.
|
643
698
|
#
|
644
699
|
# === IANA registries
|
645
700
|
# * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
|
@@ -662,7 +717,7 @@ module Net
|
|
662
717
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
663
718
|
#
|
664
719
|
class IMAP < Protocol
|
665
|
-
VERSION = "0.4.
|
720
|
+
VERSION = "0.4.9"
|
666
721
|
|
667
722
|
# Aliases for supported capabilities, to be used with the #enable command.
|
668
723
|
ENABLE_ALIASES = {
|
@@ -1316,6 +1371,12 @@ module Net
|
|
1316
1371
|
# or when existing messages are expunged; see #add_response_handler for a
|
1317
1372
|
# way to detect these events.
|
1318
1373
|
#
|
1374
|
+
# When the +condstore+ keyword argument is true, the server is told to
|
1375
|
+
# enable the extension. If +mailbox+ supports persistence of mod-sequences,
|
1376
|
+
# the +HIGHESTMODSEQ+ ResponseCode will be sent as an untagged response to
|
1377
|
+
# #select and all `FETCH` responses will include FetchData#modseq.
|
1378
|
+
# Otherwise, the +NOMODSEQ+ ResponseCode will be sent.
|
1379
|
+
#
|
1319
1380
|
# A Net::IMAP::NoResponseError is raised if the mailbox does not
|
1320
1381
|
# exist or is for some reason non-selectable.
|
1321
1382
|
#
|
@@ -1328,10 +1389,17 @@ module Net
|
|
1328
1389
|
# response code indicating that the mailstore does not support persistent
|
1329
1390
|
# UIDs:
|
1330
1391
|
# imap.responses("NO", &:last)&.code&.name == "UIDNOTSTICKY"
|
1331
|
-
|
1392
|
+
#
|
1393
|
+
# If [CONDSTORE[https://www.rfc-editor.org/rfc/rfc7162.html]] is supported,
|
1394
|
+
# the +condstore+ keyword parameter may be used.
|
1395
|
+
# imap.select("mbox", condstore: true)
|
1396
|
+
# modseq = imap.responses("HIGHESTMODSEQ", &:last)
|
1397
|
+
def select(mailbox, condstore: false)
|
1398
|
+
args = ["SELECT", mailbox]
|
1399
|
+
args << ["CONDSTORE"] if condstore
|
1332
1400
|
synchronize do
|
1333
1401
|
@responses.clear
|
1334
|
-
send_command(
|
1402
|
+
send_command(*args)
|
1335
1403
|
end
|
1336
1404
|
end
|
1337
1405
|
|
@@ -1344,10 +1412,12 @@ module Net
|
|
1344
1412
|
# exist or is for some reason non-examinable.
|
1345
1413
|
#
|
1346
1414
|
# Related: #select
|
1347
|
-
def examine(mailbox)
|
1415
|
+
def examine(mailbox, condstore: false)
|
1416
|
+
args = ["EXAMINE", mailbox]
|
1417
|
+
args << ["CONDSTORE"] if condstore
|
1348
1418
|
synchronize do
|
1349
1419
|
@responses.clear
|
1350
|
-
send_command(
|
1420
|
+
send_command(*args)
|
1351
1421
|
end
|
1352
1422
|
end
|
1353
1423
|
|
@@ -1660,23 +1730,66 @@ module Net
|
|
1660
1730
|
end
|
1661
1731
|
end
|
1662
1732
|
|
1663
|
-
# Sends a {STATUS
|
1733
|
+
# Sends a {STATUS command [IMAP4rev1 §6.3.10]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.3.10]
|
1664
1734
|
# and returns the status of the indicated +mailbox+. +attr+ is a list of one
|
1665
|
-
# or more attributes whose statuses are to be requested.
|
1666
|
-
#
|
1735
|
+
# or more attributes whose statuses are to be requested.
|
1736
|
+
#
|
1737
|
+
# The return value is a hash of attributes. Most status attributes return
|
1738
|
+
# integer values, but some return other value types (documented below).
|
1739
|
+
#
|
1740
|
+
# A Net::IMAP::NoResponseError is raised if status values
|
1741
|
+
# for +mailbox+ cannot be returned; for instance, because it
|
1742
|
+
# does not exist.
|
1743
|
+
#
|
1744
|
+
# ===== Supported attributes
|
1745
|
+
#
|
1746
|
+
# +MESSAGES+:: The number of messages in the mailbox.
|
1747
|
+
#
|
1748
|
+
# +UIDNEXT+:: The next unique identifier value of the mailbox.
|
1749
|
+
#
|
1750
|
+
# +UIDVALIDITY+:: The unique identifier validity value of the mailbox.
|
1751
|
+
#
|
1752
|
+
# +UNSEEN+:: The number of messages without the <tt>\Seen</tt> flag.
|
1667
1753
|
#
|
1668
|
-
#
|
1669
|
-
# RECENT:: the number of recent messages in the mailbox.
|
1670
|
-
# UNSEEN:: the number of unseen messages in the mailbox.
|
1754
|
+
# +DELETED+:: The number of messages with the <tt>\Deleted</tt> flag.
|
1671
1755
|
#
|
1672
|
-
#
|
1756
|
+
# +SIZE+::
|
1757
|
+
# The approximate size of the mailbox---must be greater than or equal to
|
1758
|
+
# the sum of all messages' +RFC822.SIZE+ fetch item values.
|
1759
|
+
#
|
1760
|
+
# +HIGHESTMODSEQ+::
|
1761
|
+
# The highest mod-sequence value of all messages in the mailbox. See
|
1762
|
+
# +CONDSTORE+ {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
1763
|
+
#
|
1764
|
+
# +MAILBOXID+::
|
1765
|
+
# A server-allocated unique _string_ identifier for the mailbox. See
|
1766
|
+
# +OBJECTID+ {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html].
|
1767
|
+
#
|
1768
|
+
# +RECENT+::
|
1769
|
+
# The number of messages with the <tt>\Recent</tt> flag.
|
1770
|
+
# _NOTE:_ +RECENT+ was removed from IMAP4rev2.
|
1771
|
+
#
|
1772
|
+
# Unsupported attributes may be requested. The attribute value will be
|
1773
|
+
# either an Integer or an ExtensionData object.
|
1774
|
+
#
|
1775
|
+
# ===== For example:
|
1673
1776
|
#
|
1674
1777
|
# p imap.status("inbox", ["MESSAGES", "RECENT"])
|
1675
1778
|
# #=> {"RECENT"=>0, "MESSAGES"=>44}
|
1676
1779
|
#
|
1677
|
-
#
|
1678
|
-
#
|
1679
|
-
#
|
1780
|
+
# ===== Capabilities
|
1781
|
+
#
|
1782
|
+
# +SIZE+ requires the server's capabilities to include either +IMAP4rev2+ or
|
1783
|
+
# <tt>STATUS=SIZE</tt>
|
1784
|
+
# {[RFC8483]}[https://www.rfc-editor.org/rfc/rfc8483.html].
|
1785
|
+
#
|
1786
|
+
# +DELETED+ requires the server's capabilities to include +IMAP4rev2+.
|
1787
|
+
#
|
1788
|
+
# +HIGHESTMODSEQ+ requires the server's capabilities to include +CONDSTORE+
|
1789
|
+
# {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
|
1790
|
+
#
|
1791
|
+
# +MAILBOXID+ requires the server's capabilities to include +OBJECTID+
|
1792
|
+
# {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html].
|
1680
1793
|
def status(mailbox, attr)
|
1681
1794
|
synchronize do
|
1682
1795
|
send_command("STATUS", mailbox, attr)
|
@@ -1811,6 +1924,10 @@ module Net
|
|
1811
1924
|
# string holding the entire search string, or a single-dimension array of
|
1812
1925
|
# search keywords and arguments.
|
1813
1926
|
#
|
1927
|
+
# Returns a SearchResult object. SearchResult inherits from Array (for
|
1928
|
+
# backward compatibility) but adds SearchResult#modseq when the +CONDSTORE+
|
1929
|
+
# capability has been enabled.
|
1930
|
+
#
|
1814
1931
|
# Related: #uid_search
|
1815
1932
|
#
|
1816
1933
|
# ===== Search criteria
|
@@ -1859,6 +1976,15 @@ module Net
|
|
1859
1976
|
# p imap.search(["SUBJECT", "hello", "NOT", "NEW"])
|
1860
1977
|
# #=> [1, 6, 7, 8]
|
1861
1978
|
#
|
1979
|
+
# ===== Capabilities
|
1980
|
+
#
|
1981
|
+
# If [CONDSTORE[https://www.rfc-editor.org/rfc/rfc7162.html]] is supported
|
1982
|
+
# and enabled for the selected mailbox, a non-empty SearchResult will
|
1983
|
+
# include a +MODSEQ+ value.
|
1984
|
+
# imap.select("mbox", condstore: true)
|
1985
|
+
# result = imap.search(["SUBJECT", "hi there", "not", "new")
|
1986
|
+
# #=> Net::IMAP::SearchResult[1, 6, 7, 8, modseq: 5594]
|
1987
|
+
# result.modseq # => 5594
|
1862
1988
|
def search(keys, charset = nil)
|
1863
1989
|
return search_internal("SEARCH", keys, charset)
|
1864
1990
|
end
|
@@ -1867,11 +1993,18 @@ module Net
|
|
1867
1993
|
# to search the mailbox for messages that match the given searching
|
1868
1994
|
# criteria, and returns unique identifiers (<tt>UID</tt>s).
|
1869
1995
|
#
|
1996
|
+
# Returns a SearchResult object. SearchResult inherits from Array (for
|
1997
|
+
# backward compatibility) but adds SearchResult#modseq when the +CONDSTORE+
|
1998
|
+
# capability has been enabled.
|
1999
|
+
#
|
1870
2000
|
# See #search for documentation of search criteria.
|
1871
2001
|
def uid_search(keys, charset = nil)
|
1872
2002
|
return search_internal("UID SEARCH", keys, charset)
|
1873
2003
|
end
|
1874
2004
|
|
2005
|
+
# :call-seq:
|
2006
|
+
# fetch(set, attr, changedsince: nil) -> array of FetchData
|
2007
|
+
#
|
1875
2008
|
# Sends a {FETCH command [IMAP4rev1 §6.4.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5]
|
1876
2009
|
# to retrieve data associated with a message in the mailbox.
|
1877
2010
|
#
|
@@ -1887,6 +2020,9 @@ module Net
|
|
1887
2020
|
# +attr+ is a list of attributes to fetch; see the documentation
|
1888
2021
|
# for FetchData for a list of valid attributes.
|
1889
2022
|
#
|
2023
|
+
# +changedsince+ is an optional integer mod-sequence. It limits results to
|
2024
|
+
# messages with a mod-sequence greater than +changedsince+.
|
2025
|
+
#
|
1890
2026
|
# The return value is an array of FetchData.
|
1891
2027
|
#
|
1892
2028
|
# Related: #uid_search, FetchData
|
@@ -1908,10 +2044,23 @@ module Net
|
|
1908
2044
|
# #=> "12-Oct-2000 22:40:59 +0900"
|
1909
2045
|
# p data.attr["UID"]
|
1910
2046
|
# #=> 98
|
1911
|
-
|
1912
|
-
|
2047
|
+
#
|
2048
|
+
# ===== Capabilities
|
2049
|
+
#
|
2050
|
+
# Many extensions define new message +attr+ names. See FetchData for a list
|
2051
|
+
# of supported extension fields.
|
2052
|
+
#
|
2053
|
+
# The server's capabilities must include +CONDSTORE+
|
2054
|
+
# {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
|
2055
|
+
# +changedsince+ argument. Using +changedsince+ implicitly enables the
|
2056
|
+
# +CONDSTORE+ extension.
|
2057
|
+
def fetch(set, attr, mod = nil, changedsince: nil)
|
2058
|
+
fetch_internal("FETCH", set, attr, mod, changedsince: changedsince)
|
1913
2059
|
end
|
1914
2060
|
|
2061
|
+
# :call-seq:
|
2062
|
+
# uid_fetch(set, attr, changedsince: nil) -> array of FetchData
|
2063
|
+
#
|
1915
2064
|
# Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
|
1916
2065
|
# to retrieve data associated with a message in the mailbox.
|
1917
2066
|
#
|
@@ -1924,17 +2073,36 @@ module Net
|
|
1924
2073
|
# whether a +UID+ was specified as a message data item to the +FETCH+.
|
1925
2074
|
#
|
1926
2075
|
# Related: #fetch, FetchData
|
1927
|
-
|
1928
|
-
|
2076
|
+
#
|
2077
|
+
# ===== Capabilities
|
2078
|
+
# Same as #fetch.
|
2079
|
+
def uid_fetch(set, attr, mod = nil, changedsince: nil)
|
2080
|
+
fetch_internal("UID FETCH", set, attr, mod, changedsince: changedsince)
|
1929
2081
|
end
|
1930
2082
|
|
2083
|
+
# :call-seq:
|
2084
|
+
# store(set, attr, value, unchangedsince: nil) -> array of FetchData
|
2085
|
+
#
|
1931
2086
|
# Sends a {STORE command [IMAP4rev1 §6.4.6]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.6]
|
1932
2087
|
# to alter data associated with messages in the mailbox, in particular their
|
1933
|
-
# flags.
|
1934
|
-
#
|
1935
|
-
#
|
1936
|
-
#
|
1937
|
-
#
|
2088
|
+
# flags.
|
2089
|
+
#
|
2090
|
+
# +set+ is a number, an array of numbers, or a Range object. Each number is
|
2091
|
+
# a message sequence number.
|
2092
|
+
#
|
2093
|
+
# +attr+ is the name of a data item to store. The semantics of +value+
|
2094
|
+
# varies based on +attr+:
|
2095
|
+
# * When +attr+ is <tt>"FLAGS"</tt>, the flags in +value+ replace the
|
2096
|
+
# message's flag list.
|
2097
|
+
# * When +attr+ is <tt>"+FLAGS"</tt>, the flags in +value+ are added to
|
2098
|
+
# the flags for the message.
|
2099
|
+
# * When +attr+ is <tt>"-FLAGS"</tt>, the flags in +value+ are removed
|
2100
|
+
# from the message.
|
2101
|
+
#
|
2102
|
+
# +unchangedsince+ is an optional integer mod-sequence. It prohibits any
|
2103
|
+
# changes to messages with +mod-sequence+ greater than the specified
|
2104
|
+
# +unchangedsince+ value. A SequenceSet of any messages that fail this
|
2105
|
+
# check will be returned in a +MODIFIED+ ResponseCode.
|
1938
2106
|
#
|
1939
2107
|
# The return value is an array of FetchData.
|
1940
2108
|
#
|
@@ -1943,13 +2111,25 @@ module Net
|
|
1943
2111
|
# ===== For example:
|
1944
2112
|
#
|
1945
2113
|
# p imap.store(6..8, "+FLAGS", [:Deleted])
|
1946
|
-
# #=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>,
|
1947
|
-
# #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>,
|
2114
|
+
# #=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>,
|
2115
|
+
# #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>,
|
1948
2116
|
# #<Net::IMAP::FetchData seqno=8, attr={"FLAGS"=>[:Seen, :Deleted]}>]
|
1949
|
-
|
1950
|
-
|
2117
|
+
#
|
2118
|
+
# ===== Capabilities
|
2119
|
+
#
|
2120
|
+
# Extensions may define new data items to be used with #store.
|
2121
|
+
#
|
2122
|
+
# The server's capabilities must include +CONDSTORE+
|
2123
|
+
# {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
|
2124
|
+
# +unchangedsince+ argument. Using +unchangedsince+ implicitly enables the
|
2125
|
+
# +CONDSTORE+ extension.
|
2126
|
+
def store(set, attr, flags, unchangedsince: nil)
|
2127
|
+
store_internal("STORE", set, attr, flags, unchangedsince: unchangedsince)
|
1951
2128
|
end
|
1952
2129
|
|
2130
|
+
# :call-seq:
|
2131
|
+
# uid_store(set, attr, value, unchangedsince: nil) -> array of FetchData
|
2132
|
+
#
|
1953
2133
|
# Sends a {UID STORE command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
|
1954
2134
|
# to alter data associated with messages in the mailbox, in particular their
|
1955
2135
|
# flags.
|
@@ -1958,8 +2138,11 @@ module Net
|
|
1958
2138
|
# message sequence numbers.
|
1959
2139
|
#
|
1960
2140
|
# Related: #store
|
1961
|
-
|
1962
|
-
|
2141
|
+
#
|
2142
|
+
# ===== Capabilities
|
2143
|
+
# Same as #store.
|
2144
|
+
def uid_store(set, attr, flags, unchangedsince: nil)
|
2145
|
+
store_internal("UID STORE", set, attr, flags, unchangedsince: unchangedsince)
|
1963
2146
|
end
|
1964
2147
|
|
1965
2148
|
# Sends a {COPY command [IMAP4rev1 §6.4.7]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.7]
|
@@ -2135,6 +2318,13 @@ module Net
|
|
2135
2318
|
# each enabled extension (usually the same name as the enabled extension).
|
2136
2319
|
# The following capabilities may be enabled:
|
2137
2320
|
#
|
2321
|
+
# [+CONDSTORE+ {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html]]
|
2322
|
+
#
|
2323
|
+
# Updates various commands to return +CONDSTORE+ extension responses. It
|
2324
|
+
# is not necessary to explicitly enable +CONDSTORE+—using any of the
|
2325
|
+
# command parameters defined by the extension will implicitly enable it.
|
2326
|
+
# See {[RFC7162 §3.1]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1].
|
2327
|
+
#
|
2138
2328
|
# [+:utf8+ --- an alias for <tt>"UTF8=ACCEPT"</tt>]
|
2139
2329
|
#
|
2140
2330
|
# In a future release, <tt>enable(:utf8)</tt> will enable either
|
@@ -2646,7 +2836,11 @@ module Net
|
|
2646
2836
|
end
|
2647
2837
|
end
|
2648
2838
|
|
2649
|
-
def fetch_internal(cmd, set, attr, mod = nil)
|
2839
|
+
def fetch_internal(cmd, set, attr, mod = nil, changedsince: nil)
|
2840
|
+
if changedsince
|
2841
|
+
mod ||= []
|
2842
|
+
mod << "CHANGEDSINCE" << Integer(changedsince)
|
2843
|
+
end
|
2650
2844
|
case attr
|
2651
2845
|
when String then
|
2652
2846
|
attr = RawData.new(attr)
|
@@ -2667,13 +2861,14 @@ module Net
|
|
2667
2861
|
end
|
2668
2862
|
end
|
2669
2863
|
|
2670
|
-
def store_internal(cmd, set, attr, flags)
|
2671
|
-
if attr.instance_of?(String)
|
2672
|
-
|
2673
|
-
|
2864
|
+
def store_internal(cmd, set, attr, flags, unchangedsince: nil)
|
2865
|
+
attr = RawData.new(attr) if attr.instance_of?(String)
|
2866
|
+
args = [MessageSet.new(set)]
|
2867
|
+
args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
|
2868
|
+
args << attr << flags
|
2674
2869
|
synchronize do
|
2675
2870
|
clear_responses("FETCH")
|
2676
|
-
send_command(cmd,
|
2871
|
+
send_command(cmd, *args)
|
2677
2872
|
clear_responses("FETCH")
|
2678
2873
|
end
|
2679
2874
|
end
|
@@ -2688,7 +2883,6 @@ module Net
|
|
2688
2883
|
else
|
2689
2884
|
normalize_searching_criteria(search_keys)
|
2690
2885
|
end
|
2691
|
-
normalize_searching_criteria(search_keys)
|
2692
2886
|
synchronize do
|
2693
2887
|
send_command(cmd, sort_keys, charset, *search_keys)
|
2694
2888
|
clear_responses("SORT").last || []
|
@@ -2701,7 +2895,6 @@ module Net
|
|
2701
2895
|
else
|
2702
2896
|
normalize_searching_criteria(search_keys)
|
2703
2897
|
end
|
2704
|
-
normalize_searching_criteria(search_keys)
|
2705
2898
|
synchronize do
|
2706
2899
|
send_command(cmd, algorithm, charset, *search_keys)
|
2707
2900
|
clear_responses("THREAD").last || []
|
data/net-imap.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
23
23
|
spec.metadata["source_code_uri"] = spec.homepage
|
24
|
+
spec.metadata["changelog_uri"] = spec.homepage + "/releases"
|
24
25
|
|
25
26
|
# Specify which files should be added to the gem when it is released.
|
26
27
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
data/rakelib/benchmarks.rake
CHANGED
@@ -17,11 +17,6 @@ BENCHMARK_INIT = <<RUBY
|
|
17
17
|
parser = Net::IMAP::ResponseParser.new
|
18
18
|
RUBY
|
19
19
|
|
20
|
-
PER_BENCHMARK_PRELUDE = <<RUBY
|
21
|
-
response = load_response(%p,
|
22
|
-
%p)
|
23
|
-
RUBY
|
24
|
-
|
25
20
|
file "benchmarks/parser.yml" => PARSER_TEST_FIXTURES do |t|
|
26
21
|
require "yaml"
|
27
22
|
require "pathname"
|
@@ -31,7 +26,7 @@ file "benchmarks/parser.yml" => PARSER_TEST_FIXTURES do |t|
|
|
31
26
|
files = path.glob("*.yml")
|
32
27
|
tests = files.flat_map {|file|
|
33
28
|
file.read
|
34
|
-
.gsub(%r{([-:]) !ruby/struct:\S+}) { $1 }
|
29
|
+
.gsub(%r{([-:]) !ruby/(object|struct):\S+}) { $1 }
|
35
30
|
.then {
|
36
31
|
YAML.safe_load(_1, filename: file,
|
37
32
|
permitted_classes: [Symbol, Regexp], aliases: true)
|
@@ -42,14 +37,12 @@ file "benchmarks/parser.yml" => PARSER_TEST_FIXTURES do |t|
|
|
42
37
|
test.key?(:expected) ? :parser_assert_equal : :parser_pending
|
43
38
|
}
|
44
39
|
}
|
45
|
-
.map {|test_name,
|
46
|
-
[file.relative_path_from(__dir__).to_s, test_name.to_s]
|
47
|
-
}
|
40
|
+
.map {|test_name, test| [test_name.to_s, test.fetch(:response)] }
|
48
41
|
}
|
49
42
|
|
50
|
-
benchmarks = tests.map {|
|
43
|
+
benchmarks = tests.map {|fixture_name, response|
|
51
44
|
{"name" => fixture_name.delete_prefix("test_"),
|
52
|
-
"prelude" =>
|
45
|
+
"prelude" => "response = -%s.b" % [response.dump],
|
53
46
|
"script" => "parser.parse(response)"}
|
54
47
|
}
|
55
48
|
.sort_by { _1["name"] }
|
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.
|
4
|
+
version: 0.4.9
|
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: 2023-
|
12
|
+
date: 2023-12-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-protocol
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/net/imap/data_encoding.rb
|
91
91
|
- lib/net/imap/deprecated_client_options.rb
|
92
92
|
- lib/net/imap/errors.rb
|
93
|
+
- lib/net/imap/fetch_data.rb
|
93
94
|
- lib/net/imap/flags.rb
|
94
95
|
- lib/net/imap/response_data.rb
|
95
96
|
- lib/net/imap/response_parser.rb
|
@@ -112,6 +113,8 @@ files:
|
|
112
113
|
- lib/net/imap/sasl/stringprep.rb
|
113
114
|
- lib/net/imap/sasl/xoauth2_authenticator.rb
|
114
115
|
- lib/net/imap/sasl_adapter.rb
|
116
|
+
- lib/net/imap/search_result.rb
|
117
|
+
- lib/net/imap/sequence_set.rb
|
115
118
|
- lib/net/imap/stringprep.rb
|
116
119
|
- lib/net/imap/stringprep/nameprep.rb
|
117
120
|
- lib/net/imap/stringprep/saslprep.rb
|
@@ -131,6 +134,7 @@ licenses:
|
|
131
134
|
metadata:
|
132
135
|
homepage_uri: https://github.com/ruby/net-imap
|
133
136
|
source_code_uri: https://github.com/ruby/net-imap
|
137
|
+
changelog_uri: https://github.com/ruby/net-imap/releases
|
134
138
|
post_install_message:
|
135
139
|
rdoc_options: []
|
136
140
|
require_paths:
|
@@ -146,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
150
|
- !ruby/object:Gem::Version
|
147
151
|
version: '0'
|
148
152
|
requirements: []
|
149
|
-
rubygems_version: 3.4.
|
153
|
+
rubygems_version: 3.4.22
|
150
154
|
signing_key:
|
151
155
|
specification_version: 4
|
152
156
|
summary: Ruby client api for Internet Message Access Protocol
|