Revision e279cb2a
Added by Marc Dequènes about 13 years ago
- ID e279cb2a35cd77522e283b0feef6c555a93b8da2
lib/cyborghood/imap.rb | ||
---|---|---|
@config = Config.instance
|
||
@imap = nil
|
||
@is_loggued = false
|
||
@need_reconnect = false
|
||
@available_mails = 0
|
||
@available_mails_mutex = Mutex.new
|
||
|
||
... | ... | |
true
|
||
end
|
||
|
||
def connected?
|
||
return false if @imap.nil?
|
||
return false if @need_reconnect
|
||
|
||
not @imap.disconnected?
|
||
end
|
||
|
||
def authenticate
|
||
raise CyberError.new(:unrecoverable, "fixme", "Trying to authenticate to the IMAP server, but we are not connected yet") unless @imap
|
||
|
||
... | ... | |
def listen_to_events
|
||
@imap.add_response_handler do |resp|
|
||
logger.debug "IMAP event: " + resp.inspect if @config.debug.flags.include?('debug_imapverbose')
|
||
if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
|
||
@available_mails_mutex.synchronize do
|
||
@available_mails = resp.data.to_i
|
||
logger.debug "*** Received new mails (#{@available_mails})" if @available_mails > 0
|
||
if resp.kind_of?(Net::IMAP::UntaggedResponse)
|
||
case resp.name
|
||
when "EXISTS"
|
||
@available_mails_mutex.synchronize do
|
||
@available_mails = resp.data.to_i
|
||
logger.debug "*** Received new mails (#{@available_mails})" if @available_mails > 0
|
||
end
|
||
when "BYE"
|
||
@need_reconnect = true
|
||
logger.debug "IMAP reconnection needed"
|
||
end
|
||
end
|
||
end
|
||
... | ... | |
|
||
if self.capabilities.include?("IDLE")
|
||
logger.debug "Waiting for new mails in idle mode"
|
||
@imap.idle
|
||
sleep(1) until @stop_mail_check or waiting_mails?
|
||
@imap.idle_done
|
||
until @stop_mail_check
|
||
return if @imap.nil? or not connected?
|
||
@imap.idle
|
||
# restart IDLE after 5 min
|
||
t = Time.now.to_i
|
||
sleep(1) until Time.now.to_i - t >= 300 or @stop_mail_check or waiting_mails?
|
||
@imap.idle_done
|
||
end
|
||
end
|
||
end
|
||
end
|
||
... | ... | |
t2 = Time.now.to_i
|
||
|
||
sleep_time = @min_check_interval - (t2 - t)
|
||
rescue SocketError, Errno::EPIPE, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::ENETUNREACH => e
|
||
rescue SocketError, Errno::EPIPE, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::ENETUNREACH, IOError => e
|
||
logger.warn "Network error: " + e.message.strip
|
||
sleep_time = @min_check_interval
|
||
end
|
||
... | ... | |
end
|
||
|
||
def check_inbox(&message_handler)
|
||
return unless @imap
|
||
|
||
logger.debug "Examining INBOX"
|
||
@imap.select('INBOX')
|
||
|
||
... | ... | |
return unless @imap
|
||
|
||
begin
|
||
@imap.logout if @is_loggued
|
||
unless @imap.disconnected?
|
||
@imap.logout if @is_loggued
|
||
|
||
logger.debug "Disconnecting from IMAP server..."
|
||
@imap.disconnect
|
||
logger.debug "Disconnected from IMAP server"
|
||
logger.debug "Disconnecting from IMAP server..."
|
||
@imap.disconnect
|
||
logger.debug "Disconnected from IMAP server"
|
||
end
|
||
rescue IOError
|
||
logger.debug "Already diconnected from IMAP server"
|
||
logger.debug "Already disconnected from IMAP server"
|
||
ensure
|
||
@imap = nil
|
||
@is_loggued = false
|
||
@imap_capab = nil
|
||
@need_reconnect = false
|
||
end
|
||
end
|
||
end
|
Also available in: Unified diff
[fix] IMAP: better handle IDLE sessions, process BYE messages from server, and add disconnection detection as Net::IMAP seems not to send BYE messages everytime it should