ruby-changes:47309
From: shugo <ko1@a...>
Date: Wed, 26 Jul 2017 16:47:42 +0900 (JST)
Subject: [ruby-changes:47309] shugo:r59424 (trunk): lib/net/imap.rb: support CHANGEDSINCE and MODSEQ
shugo 2017-07-26 16:47:34 +0900 (Wed, 26 Jul 2017) New Revision: 59424 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59424 Log: lib/net/imap.rb: support CHANGEDSINCE and MODSEQ Patch by plehoux (Philippe-Antoine Lehoux). [ruby-core:64272] [Feature #10119] Modified files: trunk/lib/net/imap.rb trunk/test/net/imap/test_imap_response_parser.rb Index: lib/net/imap.rb =================================================================== --- lib/net/imap.rb (revision 59423) +++ lib/net/imap.rb (revision 59424) @@ -814,13 +814,13 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L814 # #=> "12-Oct-2000 22:40:59 +0900" # p data.attr["UID"] # #=> 98 - def fetch(set, attr) - return fetch_internal("FETCH", set, attr) + def fetch(set, attr, mod = nil) + return fetch_internal("FETCH", set, attr, mod) end # Similar to #fetch(), but +set+ contains unique identifiers. - def uid_fetch(set, attr) - return fetch_internal("UID FETCH", set, attr) + def uid_fetch(set, attr, mod = nil) + return fetch_internal("UID FETCH", set, attr, mod) end # Sends a STORE command to alter data associated with messages @@ -1304,8 +1304,12 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L1304 when Integer NumValidator.ensure_number(data) when Array - data.each do |i| - validate_data(i) + if data[0] == 'CHANGEDSINCE' + NumValidator.ensure_mod_sequence_value(data[1]) + else + data.each do |i| + validate_data(i) + end end when Time when Symbol @@ -1417,7 +1421,7 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L1421 end end - def fetch_internal(cmd, set, attr) + def fetch_internal(cmd, set, attr, mod = nil) case attr when String then attr = RawData.new(attr) @@ -1429,7 +1433,11 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L1433 synchronize do @responses.delete("FETCH") - send_command(cmd, MessageSet.new(set), attr) + if mod + send_command(cmd, MessageSet.new(set), attr, mod) + else + send_command(cmd, MessageSet.new(set), attr) + end return @responses.delete("FETCH") end end @@ -1663,6 +1671,15 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L1671 num != 0 && valid_number?(num) end + # Check is passed argument valid 'mod_sequence_value' in RFC 4551 terminology + def valid_mod_sequence_value?(num) + # mod-sequence-value = 1*DIGIT + # ; Positive unsigned 64-bit integer + # ; (mod-sequence) + # ; (1 <= n < 18,446,744,073,709,551,615) + num >= 1 && num < 18446744073709551615 + end + # Ensure argument is 'number' or raise DataFormatError def ensure_number(num) return if valid_number?(num) @@ -1678,6 +1695,14 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L1695 msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}" raise DataFormatError, msg end + + # Ensure argument is 'mod_sequence_value' or raise DataFormatError + def ensure_mod_sequence_value(num) + return if valid_mod_sequence_value?(num) + + msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}" + raise DataFormatError, msg + end end end @@ -2343,6 +2368,8 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L2368 name, val = body_data when /\A(?:UID)\z/ni name, val = uid_data + when /\A(?:MODSEQ)\z/ni + name, val = modseq_data else parse_error("unknown attribute `%s' for {%d}", token.value, n) end @@ -2832,6 +2859,16 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L2859 return name, number end + def modseq_data + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + match(T_LPAR) + modseq = number + match(T_RPAR) + return name, modseq + end + def text_response token = match(T_ATOM) name = token.value.upcase Index: test/net/imap/test_imap_response_parser.rb =================================================================== --- test/net/imap/test_imap_response_parser.rb (revision 59423) +++ test/net/imap/test_imap_response_parser.rb (revision 59424) @@ -304,4 +304,11 @@ EOF https://github.com/ruby/ruby/blob/trunk/test/net/imap/test_imap_response_parser.rb#L304 assert_equal("INBOX", response.data.mailbox) assert_equal(1234, response.data.attr["UIDVALIDITY"]) end + + # [Bug #10119] + def test_msg_att_modseq_data + parser = Net::IMAP::ResponseParser.new + response = parser.parse("* 1 FETCH (FLAGS (\Seen) MODSEQ (12345) UID 5)\r\n") + assert_equal(12345, response.data.attr["MODSEQ"]) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/