lib/sup/imap.rb in sup-0.8.1 vs lib/sup/imap.rb in sup-0.9
- old
+ new
@@ -2,10 +2,11 @@
require 'net/imap'
require 'stringio'
require 'time'
require 'rmail'
require 'cgi'
+require 'set'
## TODO: remove synchronized method protector calls; use a Monitor instead
## (ruby's reentrant mutex)
## fucking imap fucking sucks. what the FUCK kind of committee of dunces
@@ -45,10 +46,11 @@
## fuck you, imap committee. you managed to design something nearly as
## shitty as mbox but goddamn THIRTY YEARS LATER.
module Redwood
class IMAP < Source
+ include SerializeLabelsNicely
SCAN_INTERVAL = 60 # seconds
## upon these errors we'll try to rereconnect a few times
RECOVERABLE_ERRORS = [ Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError ]
@@ -67,11 +69,11 @@
@password = password
@imap = nil
@imap_state = {}
@ids = []
@last_scan = nil
- @labels = ((labels || []) - LabelManager::RESERVED_LABELS).uniq.freeze
+ @labels = Set.new((labels || []) - LabelManager::RESERVED_LABELS)
@say_id = nil
@mutex = Mutex.new
end
def self.suggest_labels_for path
@@ -109,10 +111,18 @@
header, flags = get_imap_fields id, 'RFC822.HEADER'
header.gsub(/\r\n/, "\n")
end
synchronized :raw_header
+ def store_message date, from_email, &block
+ message = StringIO.new
+ yield message
+ message.string.gsub! /\n/, "\r\n"
+
+ safely { @imap.append mailbox, message.string, [:Seen], Time.now }
+ end
+
def raw_message id
unsynchronized_scan_mailbox
get_imap_fields(id, 'RFC822').first.gsub(/\r\n/, "\n")
end
synchronized :raw_message
@@ -149,17 +159,17 @@
@ids = [] if force
return if last_id == @ids.length
range = (@ids.length + 1) .. last_id
- Redwood::log "fetching IMAP headers #{range}"
+ debug "fetching IMAP headers #{range}"
fetch(range, ['RFC822.SIZE', 'INTERNALDATE', 'FLAGS']).each do |v|
id = make_id v
@ids << id
@imap_state[id] = { :id => v.seqno, :flags => v.attr["FLAGS"] }
end
- Redwood::log "done fetching IMAP headers"
+ debug "done fetching IMAP headers"
end
synchronized :scan_mailbox
def each
return unless start_offset
@@ -214,11 +224,11 @@
end
if good_results.empty?
raise FatalSourceError, "no IMAP response for #{ids} containing all fields #{fields.join(', ')} (got #{results.size} results)"
elsif good_results.size < results.size
- Redwood::log "Your IMAP server sucks. It sent #{results.size} results for a request for #{good_results.size} messages. What are you using, Binc?"
+ warn "Your IMAP server sucks. It sent #{results.size} results for a request for #{good_results.size} messages. What are you using, Binc?"
end
good_results
end
@@ -242,16 +252,16 @@
## it seems like they can also send a BAD response.
begin
raise Net::IMAP::NoResponseError unless @imap.capability().member? "AUTH=CRAM-MD5"
@imap.authenticate 'CRAM-MD5', @username, @password
rescue Net::IMAP::BadResponseError, Net::IMAP::NoResponseError => e
- Redwood::log "CRAM-MD5 authentication failed: #{e.class}. Trying LOGIN auth..."
+ debug "CRAM-MD5 authentication failed: #{e.class}. Trying LOGIN auth..."
begin
raise Net::IMAP::NoResponseError unless @imap.capability().member? "AUTH=LOGIN"
@imap.authenticate 'LOGIN', @username, @password
rescue Net::IMAP::BadResponseError, Net::IMAP::NoResponseError => e
- Redwood::log "LOGIN authentication failed: #{e.class}. Trying plain-text LOGIN..."
+ debug "LOGIN authentication failed: #{e.class}. Trying plain-text LOGIN..."
@imap.login @username, @password
end
end
say "Successfully connected to #{@parsed_uri}."
rescue Exception => e
@@ -264,11 +274,11 @@
raise exception if exception
end
def say s
@say_id = BufferManager.say s, @say_id if BufferManager.instantiated?
- Redwood::log s
+ info s
end
def shutup
BufferManager.clear @say_id if BufferManager.instantiated?
@say_id = nil
@@ -321,10 +331,10 @@
unsafe_connect unless @imap
yield
rescue *RECOVERABLE_ERRORS => e
if (retries += 1) <= 3
@imap = nil
- Redwood::log "got #{e.class.name}: #{e.message.inspect}"
+ warn "got #{e.class.name}: #{e.message.inspect}"
sleep 2
retry
end
raise
end