Created
May 24, 2012 19:40
-
-
Save jem/2783772 to your computer and use it in GitHub Desktop.
Ancient (2009) code for IMAP idle in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SERVER = 'imap.gmail.com' | |
USERNAME = 'XXX' | |
PW = 'XXX' | |
require 'net/imap' | |
require 'net/smtp' | |
require 'tmail' | |
require 'maruku' | |
def to_markdown(text) | |
Maruku.new(text).to_html | |
end | |
# Extend support for idle command. See online. | |
# http://www.ruby-forum.com/topic/50828 | |
# but that was wrong. see /opt/ruby-1.9.1-p243/lib/net/imap.rb. | |
class Net::IMAP | |
def idle | |
cmd = "IDLE" | |
synchronize do | |
@idle_tag = generate_tag | |
put_string(@idle_tag + " " + cmd) | |
put_string(CRLF) | |
end | |
end | |
def say_done | |
cmd = "DONE" | |
synchronize do | |
put_string(cmd) | |
put_string(CRLF) | |
end | |
end | |
def await_done_confirmation | |
synchronize do | |
get_tagged_response(@idle_tag, nil) | |
puts 'just got confirmation' | |
end | |
end | |
end | |
class Remailer | |
attr_reader :imap | |
public | |
def initialize | |
@imap = nil | |
@smtp = nil | |
@mailer = nil | |
start_imap | |
end | |
def process | |
puts 'Processing!' | |
msg_ids = @imap.search(["SINCE", "25-Nov-2009", "TO", "XXX", "UNSEEN"]) | |
puts 'Done with search!' | |
unless msg_ids.empty? | |
start_smtp | |
msg_ids.each do |msg_id| | |
mail = TMail::Mail.parse(@imap.fetch(msg_id, 'RFC822').first.attr['RFC822']) | |
print "Processing #{mail.subject}..." | |
mail.to = '[email protected]' | |
mail.body = to_markdown(mail.body) | |
print ' marked down...' | |
@smtp.send_message mail.encoded, mail.from, [mail.to, 'XXX'] | |
puts ' sent.' | |
@imap.store msg_id, '+FLAGS', [:Seen] | |
end | |
end | |
ensure | |
stop_smtp | |
end | |
def tidy | |
stop_smtp | |
stop_imap | |
end | |
def bounce_idle | |
# Bounces the idle command. | |
@imap.say_done | |
@imap.await_done_confirmation | |
# Do a manual check, just in case things aren't working properly. | |
process | |
@imap.idle | |
end | |
private | |
def start_imap | |
@imap = Net::IMAP.new SERVER, :ssl => true | |
@imap.login USERNAME, PW | |
@imap.select 'INBOX' | |
# Add handler. | |
@imap.add_response_handler do |resp| | |
if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS" | |
@imap.say_done | |
Thread.new do | |
@imap.await_done_confirmation | |
process | |
@imap.idle | |
end | |
end | |
end | |
process | |
@imap.idle | |
end | |
def stop_imap | |
@imap.done | |
end | |
def start_smtp | |
# Don't start more than once. | |
return unless @smtp.nil? | |
@smtp = Net::SMTP.new 'smtp.gmail.com', 465 | |
@smtp.enable_tls | |
@smtp.start 'XXX', USERNAME, PW | |
end | |
def stop_smtp | |
# Don't stop if we haven't started. | |
return if @smtp.nil? | |
@smtp.finish | |
@smtp = nil | |
end | |
end | |
begin | |
Net::IMAP.debug = true | |
r = Remailer.new | |
loop do | |
puts 'bouncing...' | |
r.bounce_idle | |
sleep 10*60 | |
end | |
ensure | |
r.tidy | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment