Project

General

Profile

« Previous | Next » 

Revision 3d5142d6

Added by Marc Dequènes over 14 years ago

  • ID 3d5142d656e19aa1a2a611e475738afa947b927c

[evol] preliminary IMAP IDLE support (not fully working yet)

View differences:

lib/cyborghood/imap.rb
require 'net/imap'
# IMAP IDLE support
class Net::IMAP
def idle(&response_handler)
return if @idle_mode
@idle_response_handler = response_handler
synchronize do
@idle_tag = generate_tag
add_response_handler @idle_response_handler
put_string "#{@idle_tag} IDLE#{CRLF}"
end
@idle_mode = true
end
def idle_done
return unless @idle_mode
synchronize do
remove_response_handler @idle_response_handler
put_string "DONE#{CRLF}"
end
@idle_mode = false
get_tagged_response @idle_tag
end
def idle?
@idle_mode || false
end
end
module CyborgHood
class IMAP
def initialize(params, min_check_interval)
@params = params
@min_check_interval = min_check_interval
@config = Config.instance
@imap = nil
@is_loggued = false
@min_check_interval = min_check_interval
if not (@config.debug.nil? or @config.debug.flags.nil?) and @config.debug.flags.include?(:debug_imapverbose)
Net::IMAP.debug = true
end
end
class IMAPMessage
......
connect &&
authenticate &&
check_inbox(&message_handler)
if @imap.capability.include?("IDLE")
logger.debug "Waiting for new mails in idle mode"
@imap.idle do |resp|
if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
message_id = resp.data
logger.debug "*** Received mail ##{message_id}"
# TODO: can't do that, a new IMAP connection should be used, this one is dedicated to IDLE mode
message_handler.call IMAPMessage.new(@imap, message_id)
end
end
sleep(1) until @stop_mail_check
p idle_done
# TODO: ensure all thread for IDLE processing have finished before closing the connection
end
rescue SocketError, Net::IMAP::NoResponseError => e
logger.warn "IMAP or Network error: " + e.message
rescue Net::IMAP::Error => e
......
r = check_mails_once(&message_handler)
t2 = Time.now.to_i
# wait before new check either if the IMAP server does not support IDLE mode
# or if an error occured
sleep_time = @min_check_interval - (t2 - t)
if sleep_time > 0
logger.debug "Having a break before new check..."
......
end
end
def check_inbox
def check_inbox(&message_handler)
logger.debug "Examining INBOX"
@imap.select('INBOX')
logger.debug "Starting mail check"
@imap.search(["ALL"], "UTF-8").each do |message_id|
logger.debug "*** Fetched mail ##{message_id}"
unless yield IMAPMessage.new(@imap, message_id)
unless message_handler.call IMAPMessage.new(@imap, message_id)
@stop_mail_check = true
break
end

Also available in: Unified diff