Forum: Ruby Support for IMAP IDLE in net/imap

Posted by Abhishiv Saxena (abhishiv)
on 2009-07-03 10:17
(Received via mailing list)
Ok, I have been suck on it for hours. I thought net/imap.rb with ruby 
1.9
supported the idle command, but not yet.

Can anyone help me in implementing that? From
here<http://www.ruby-forum.com/topic/50828>,
I though this would work:

class Net::IMAP
  def idle
    cmd = "IDLE"
    synchronize do
      tag = generate_tag
      put_string(tag + " " + cmd)
      put_string(CRLF)
    end
  end

  def done
    cmd = "DONE"
    synchronize do
      put_string(cmd)
      put_string(CRLF)
    end
  end
end

But, when i issue imap.idle, it return true, but i have to press return
twice to get the server response. And there's no notification for new
messages.

?> imap.idle
C: RUBY0005 IDLE
=> true
>>
?>
?> S: + idling
Posted by Eric Hodel (Guest)
on 2009-07-03 17:34
(Received via mailing list)
On Jul 3, 2009, at 1:16, Abhishiv Saxena <abhishiv@gmail.com> wrote:

> Ok, I have been suck on it for hours. I thought net/imap.rb with  
> ruby 1.9
> supported the idle command, but not yet.
>
> Can anyone help me in implementing that?

I have a working IDLE method, but it's not handy. Ill post it in a bit.
Posted by Eric Hodel (Guest)
on 2009-07-03 18:44
(Received via mailing list)
On Jul 3, 2009, at 01:16, Abhishiv Saxena wrote:

> Ok, I have been suck on it for hours. I thought net/imap.rb with  
> ruby 1.9
> supported the idle command, but not yet.
>
> Can anyone help me in implementing that?

NOTE: There's no need to post to the mailing list and the forum, they
both come to the same place.

Try this:

require 'net/imap'

class Net::IMAP

   ##
   # Sends an IDLE command that waits for notifications of new or
expunged
   # messages.  Yields responses from the server during the IDLE.
   #
   # Use +break+ in the response handler to leave IDLE.

   def idle(&response_handler)
     raise LocalJumpError, "no block given" unless response_handler

     response = nil

     synchronize do
       tag = Thread.current[:net_imap_tag] = generate_tag
       put_string "#{tag} IDLE#{CRLF}"

       add_response_handler response_handler

       begin
         response = get_tagged_response tag
       rescue LocalJumpError # can't break cross-threads or something
       ensure
         unless response then
           put_string "DONE#{CRLF}"
           response = get_tagged_response tag
         end

         remove_response_handler response_handler
       end
     end

     response
   end

end
Posted by Abhishiv Saxena (abhishiv)
on 2009-07-03 23:19
Eric, Thanks a lot that works like a charm.

imap.idle { |resp|
  puts "Mailbox now has #{resp.data} messages"
}
Posted by Eric Hodel (Guest)
on 2009-07-04 18:08
(Received via mailing list)
On Jul 3, 2009, at 14:19, Abhishiv Saxena <abhishiv@gmail.com> wrote:

> Eric, Thanks a lot that works like a charm.
>
> imap.idle { |resp|
>  puts "Mailbox now has #{resp.data} messages"
> }

Careful, you'll get both EXIST and EXPUNGE responses, so be sure to
subtract when appropriate. Also note that EXPUNGE shifts all your
recorded UIDs down by one. See RFC 3501 for all the crazy details :(
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.