Revision 3d5142d6
Added by Marc Dequènes over 14 years ago
- ID 3d5142d656e19aa1a2a611e475738afa947b927c
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
[evol] preliminary IMAP IDLE support (not fully working yet)