class MailRoom::Connection
Public Class Methods
# File lib/mail_room/connection.rb, line 3 def initialize(mailbox) @mailbox = mailbox # log in and set the mailbox reset setup end
Public Instance Methods
is the imap connection closed? @return [Boolean]
# File lib/mail_room/connection.rb, line 29 def disconnected? @imap.disconnected? end
is the connection blocked idling? @return [Boolean]
# File lib/mail_room/connection.rb, line 23 def idling? @idling end
is the connection logged in? @return [Boolean]
# File lib/mail_room/connection.rb, line 17 def logged_in? @logged_in end
# File lib/mail_room/connection.rb, line 11 def on_new_message(&block) @new_message_handler = block end
# File lib/mail_room/connection.rb, line 39 def quit stop_idling reset end
is the connection ready to idle? @return [Boolean]
# File lib/mail_room/connection.rb, line 35 def ready_to_idle? logged_in? && !idling? end
# File lib/mail_room/connection.rb, line 44 def wait begin # in case we missed any between idles process_mailbox idle process_mailbox rescue Net::IMAP::Error, IOError reset setup end end
Private Instance Methods
maintain an imap idle connection
# File lib/mail_room/connection.rb, line 106 def idle return unless ready_to_idle? @idling = true imap.idle(@mailbox.idle_timeout, &idle_handler) ensure @idling = false end
@private
# File lib/mail_room/connection.rb, line 101 def idle_handler lambda {|response| imap.idle_done if message_exists?(response)} end
build a net/imap connection to google imap
# File lib/mail_room/connection.rb, line 73 def imap @imap ||= MailRoom::IMAP.new(@mailbox.host, :port => @mailbox.port, :ssl => @mailbox.ssl_options) end
send the imap login command to google
# File lib/mail_room/connection.rb, line 83 def log_in imap.login(@mailbox.email, @mailbox.password) @logged_in = true end
is the response for a new message? @param response [Net::IMAP::TaggedResponse] the imap response from idle @return [Boolean]
# File lib/mail_room/connection.rb, line 96 def message_exists?(response) response.respond_to?(:name) && response.name == 'EXISTS' end
@private fetch the email for all given ids in RFC822 format @param ids [Array<Integer>] list of message ids @return [Array<Net::IMAP::FetchData>] the net/imap messages for the given ids
# File lib/mail_room/connection.rb, line 168 def messages_for_ids(uids) return [] if uids.empty? # uid_fetch marks as SEEN, will not be re-fetched for UNSEEN imap.uid_fetch(uids, "RFC822") end
@private search for all new (unseen) message ids @return [Array<Integer>] message ids
# File lib/mail_room/connection.rb, line 159 def new_message_ids # uid_search still leaves messages UNSEEN imap.uid_search(@mailbox.search_command).select { |uid| @mailbox.deliver?(uid) } end
@private fetch all messages for the new message ids
# File lib/mail_room/connection.rb, line 146 def new_messages # Both of these calls may results in # imap raising an EOFError, we handle # this exception in the watcher messages_for_ids(new_message_ids) end
# File lib/mail_room/connection.rb, line 126 def process_mailbox return unless @new_message_handler msgs = new_messages msgs. map(&@new_message_handler). # deliver each new message, collect success zip(msgs). # include messages with success select(&:first).map(&:last). # filter failed deliveries, collect message each {|message| scrub(message)} # scrub delivered messages end
# File lib/mail_room/connection.rb, line 60 def reset @imap = nil @logged_in = false @idling = false end
# File lib/mail_room/connection.rb, line 138 def scrub(message) if @mailbox.delete_after_delivery imap.store(message.seqno, "+FLAGS", [Net::IMAP::DELETED]) end end
select the mailbox name we want to use
# File lib/mail_room/connection.rb, line 89 def set_mailbox imap.select(@mailbox.name) if logged_in? end
# File lib/mail_room/connection.rb, line 66 def setup start_tls log_in set_mailbox end
start a TLS session
# File lib/mail_room/connection.rb, line 78 def start_tls imap.starttls if @mailbox.start_tls end
trigger the idle to finish and wait for the thread to finish
# File lib/mail_room/connection.rb, line 117 def stop_idling return unless idling? imap.idle_done # idling_thread.join # self.idling_thread = nil end