Skip to content

Commit

Permalink
✨ Add changedsince kwarg to #fetch, #uid_fetch
Browse files Browse the repository at this point in the history
Fixes #132.
  • Loading branch information
nevans committed Dec 12, 2023
1 parent 647a745 commit 3d2493d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
38 changes: 33 additions & 5 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@ module Net
# search criterion, and adds SearchResult#modseq to the search response.
# - Updates #thread and #uid_thread with the +MODSEQ+ search criterion
# <em>(but thread responses are unchanged)</em>.
# - Updates #fetch and #uid_fetch with the +changedsince+ modifier and
# +MODSEQ+ FetchData attribute.
#
# ==== RFC8438: <tt>STATUS=SIZE</tt>
# - Updates #status with the +SIZE+ status attribute.
Expand Down Expand Up @@ -1986,6 +1988,9 @@ def uid_search(keys, charset = nil)
return search_internal("UID SEARCH", keys, charset)
end

# :call-seq:
# fetch(set, attr, changedsince: nil) -> array of FetchData
#
# Sends a {FETCH command [IMAP4rev1 §6.4.5]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5]
# to retrieve data associated with a message in the mailbox.
#
Expand All @@ -2001,6 +2006,9 @@ def uid_search(keys, charset = nil)
# +attr+ is a list of attributes to fetch; see the documentation
# for FetchData for a list of valid attributes.
#
# +changedsince+ is an optional integer mod-sequence. It limits results to
# messages with a mod-sequence greater than +changedsince+.
#
# The return value is an array of FetchData.
#
# Related: #uid_search, FetchData
Expand All @@ -2022,10 +2030,23 @@ def uid_search(keys, charset = nil)
# #=> "12-Oct-2000 22:40:59 +0900"
# p data.attr["UID"]
# #=> 98
def fetch(set, attr, mod = nil)
return fetch_internal("FETCH", set, attr, mod)
#
# ===== Capabilities
#
# Many extensions define new message +attr+ names. See FetchData for a list
# of supported extension fields.
#
# The server's capabilities must include +CONDSTORE+
# {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
# +changedsince+ argument. Using +changedsince+ implicitly enables the
# +CONDSTORE+ extension.
def fetch(set, attr, mod = nil, changedsince: nil)
fetch_internal("FETCH", set, attr, mod, changedsince: changedsince)
end

# :call-seq:
# uid_fetch(set, attr, changedsince: nil) -> array of FetchData
#
# Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
# to retrieve data associated with a message in the mailbox.
#
Expand All @@ -2038,8 +2059,11 @@ def fetch(set, attr, mod = nil)
# whether a +UID+ was specified as a message data item to the +FETCH+.
#
# Related: #fetch, FetchData
def uid_fetch(set, attr, mod = nil)
return fetch_internal("UID FETCH", set, attr, mod)
#
# ===== Capabilities
# Same as #fetch.
def uid_fetch(set, attr, mod = nil, changedsince: nil)
fetch_internal("UID FETCH", set, attr, mod, changedsince: changedsince)
end

# Sends a {STORE command [IMAP4rev1 §6.4.6]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.6]
Expand Down Expand Up @@ -2760,7 +2784,11 @@ def search_internal(cmd, keys, charset)
end
end

def fetch_internal(cmd, set, attr, mod = nil)
def fetch_internal(cmd, set, attr, mod = nil, changedsince: nil)
if changedsince
mod ||= []
mod << "CHANGEDSINCE" << Integer(changedsince)
end
case attr
when String then
attr = RawData.new(attr)
Expand Down
18 changes: 18 additions & 0 deletions test/net/imap/test_imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,24 @@ def test_clear_responses
end
end

test "#fetch with changedsince" do
with_fake_server select: "inbox" do |server, imap|
server.on("FETCH", &:done_ok)
imap.fetch 1..-1, %w[FLAGS], changedsince: 12345
assert_equal("RUBY0002 FETCH 1:* (FLAGS) (CHANGEDSINCE 12345)",
server.commands.pop.raw.strip)
end
end

test "#uid_fetch with changedsince" do
with_fake_server select: "inbox" do |server, imap|
server.on("UID FETCH", &:done_ok)
imap.uid_fetch 1..-1, %w[FLAGS], changedsince: 12345
assert_equal("RUBY0002 UID FETCH 1:* (FLAGS) (CHANGEDSINCE 12345)",
server.commands.pop.raw.strip)
end
end

def test_close
with_fake_server(select: "inbox") do |server, imap|
resp = imap.close
Expand Down

0 comments on commit 3d2493d

Please sign in to comment.