@@ -2636,6 +2636,7 @@ def fetch(...)
26362636
26372637 # :call-seq:
26382638 # uid_fetch(set, attr, changedsince: nil, partial: nil) -> array of FetchData (or UIDFetchData)
2639+ # uid_fetch(set, attr, changedsince:, vanished: true, partial: nil) -> array of VanishedData and FetchData (or UIDFetchData)
26392640 #
26402641 # Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
26412642 # to retrieve data associated with a message in the mailbox.
@@ -2652,6 +2653,23 @@ def fetch(...)
26522653 #
26532654 # +changedsince+ (optional) behaves the same as with #fetch.
26542655 #
2656+ # +vanished+ can be used to request a list all of the message UIDs in +set+
2657+ # that have been expunged since +changedsince+. Setting +vanished+ to true
2658+ # prepends a VanishedData object to the returned array. If the server does
2659+ # not return a +VANISHED+ response, an empty VanishedData object will still
2660+ # be added.
2661+ # <em>The +QRESYNC+ capabability must be enabled.</em>
2662+ # {[RFC7162]}[https://rfc-editor.org/rfc/rfc7162]
2663+ #
2664+ # For example:
2665+ #
2666+ # # must enable "QRESYNC" before selecting the mailbox
2667+ # imap.enable("QRESYNC")
2668+ # imap.select("INBOX")
2669+ # # first value in the array is VanishedData
2670+ # vanished, *fetched = imap.uid_fetch(301..500, %w[flags],
2671+ # changedsince: 12345, vanished: true)
2672+ #
26552673 # +partial+ is an optional range to limit the number of results returned.
26562674 # It's useful when +set+ contains an unknown number of messages.
26572675 # <tt>1..500</tt> returns the first 500 messages in +set+ (in mailbox
@@ -2683,6 +2701,9 @@ def fetch(...)
26832701 #
26842702 # ==== Capabilities
26852703 #
2704+ # QRESYNC[https://www.rfc-editor.org/rfc/rfc7162] must be enabled in order
2705+ # to use the +vanished+ fetch modifier.
2706+ #
26862707 # The server's capabilities must include +PARTIAL+
26872708 # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394] in order to use the
26882709 # +partial+ argument.
@@ -2962,9 +2983,8 @@ def uid_thread(algorithm, search_keys, charset)
29622983 # See {[RFC7162 §3.1]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1].
29632984 #
29642985 # [+QRESYNC+ {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html]]
2965- # *NOTE:* Enabling QRESYNC will replace +EXPUNGE+ with +VANISHED+, but
2966- # the extension arguments to #select, #examine, and #uid_fetch are not
2967- # supported yet.
2986+ # *NOTE:* The +QRESYNC+ argument to #select and #examine is not supported
2987+ # yet.
29682988 #
29692989 # Adds quick resynchronization options to #select, #examine, and
29702990 # #uid_fetch. +QRESYNC+ _must_ be explicitly enabled before using any of
@@ -3683,16 +3703,21 @@ def search_internal(cmd, ...)
36833703 end
36843704 end
36853705
3686- def fetch_internal ( cmd , set , attr , mod = nil , partial : nil , changedsince : nil )
3687- set = SequenceSet [ set ]
3688- if partial
3689- mod ||= [ ]
3690- mod << "PARTIAL" << PartialRange [ partial ]
3691- end
3692- if changedsince
3693- mod ||= [ ]
3694- mod << "CHANGEDSINCE" << Integer ( changedsince )
3706+ def fetch_internal ( cmd , set , attr , mod = nil ,
3707+ partial : nil ,
3708+ changedsince : nil ,
3709+ vanished : false )
3710+ if vanished
3711+ if !cmd . start_with? ( "UID " )
3712+ raise ArgumentError , "vanished can only be used with uid_fetch"
3713+ elsif !changedsince
3714+ raise ArgumentError , "vanished must be used with changedsince"
3715+ end
36953716 end
3717+ set = SequenceSet [ set ]
3718+ ( mod ||= [ ] ) << "PARTIAL" << PartialRange [ partial ] if partial
3719+ ( mod ||= [ ] ) << "CHANGEDSINCE" << Integer ( changedsince ) if changedsince
3720+ ( mod ||= [ ] ) << "VANISHED" if vanished
36963721 case attr
36973722 when String then
36983723 attr = RawData . new ( attr )
@@ -3704,7 +3729,7 @@ def fetch_internal(cmd, set, attr, mod = nil, partial: nil, changedsince: nil)
37043729
37053730 args = [ cmd , set , attr ]
37063731 args << mod if mod
3707- send_command_returning_fetch_results ( *args )
3732+ send_command_returning_fetch_results ( *args , vanished : )
37083733 end
37093734
37103735 def store_internal ( cmd , set , attr , flags , unchangedsince : nil )
@@ -3715,14 +3740,20 @@ def store_internal(cmd, set, attr, flags, unchangedsince: nil)
37153740 send_command_returning_fetch_results ( cmd , *args )
37163741 end
37173742
3718- def send_command_returning_fetch_results ( ... )
3743+ def send_command_returning_fetch_results ( * args , vanished : false )
37193744 synchronize do
37203745 clear_responses ( "FETCH" )
37213746 clear_responses ( "UIDFETCH" )
3722- send_command ( ... )
3747+ send_command ( * args )
37233748 fetches = clear_responses ( "FETCH" )
37243749 uidfetches = clear_responses ( "UIDFETCH" )
3725- uidfetches . any? ? uidfetches : fetches
3750+ fetches = uidfetches if uidfetches . any?
3751+ if vanished
3752+ vanished = extract_responses ( "VANISHED" , &:earlier? ) . last ||
3753+ VanishedData [ uids : SequenceSet . empty , earlier : true ]
3754+ fetches = [ vanished , *fetches ] . freeze
3755+ end
3756+ fetches
37263757 end
37273758 end
37283759
0 commit comments