10 def initialize uri, username, password, last_uid=nil, usual=true, archived=false, id=nil
11 raise ArgumentError, "username and password must be specified" unless username && password
12 raise ArgumentError, "not an imap uri" unless uri =~ %r!imaps?://!
14 super uri, last_uid, usual, archived, id
16 @parsed_uri = URI(uri)
21 @labels << :inbox unless archived?
22 @labels << mailbox.intern unless mailbox =~ /inbox/i || mailbox.nil?
28 return false if broken?
30 Redwood::log "connecting to #{@parsed_uri.host} port #{ssl? ? 993 : 143}, ssl=#{ssl?} ..."
32 ## ok, this is FUCKING ANNOYING.
34 ## what imap.rb likes to do is, if an exception occurs, catch it
35 ## and re-raise it on the calling thread. seems reasonable. but
36 ## what that REALLY means is that the only way to reasonably
37 ## initialize imap is in its own thread, because otherwise, you
38 ## will never be able to catch the exception it raises on the
39 ## calling thread, and the backtrace will not make any sense at
40 ## all, and you will waste HOURS of your life on this fucking
46 #raise Net::IMAP::ByeResponseError, "simulated imap failure"
47 @imap = Net::IMAP.new host, ssl? ? 993 : 143, ssl?
48 @imap.authenticate 'LOGIN', @username, @password
50 Redwood::log "successfully connected to #{@parsed_uri}, mailbox #{mailbox}"
52 self.broken_msg = e.message.chomp # fucking chomp! fuck!!!
54 Redwood::log "error connecting to IMAP server: #{self.broken_msg}"
62 def host; @parsed_uri.host; end
63 def mailbox; @parsed_uri.path[1..-1] end ##XXXX TODO handle nil
64 def ssl?; @parsed_uri.scheme == 'imaps' end
66 def load_header uid=nil
67 MBox::read_header StringIO.new(raw_header(uid))
71 RMail::Parser.read raw_full_message(uid)
74 ## load the full header text
76 connect or return broken_msg
77 get_imap_field(uid, 'RFC822.HEADER').gsub(/\r\n/, "\n")
80 def raw_full_message uid
81 connect or return broken_msg
82 get_imap_field(uid, 'RFC822').gsub(/\r\n/, "\n")
85 def get_imap_field uid, field
86 f = @imap.uid_fetch uid, field
87 raise SourceError, "null IMAP field '#{field}' for message with uid #{uid}" if f.nil?
90 private :get_imap_field
93 connect or return broken_msg
94 uids = @imap.uid_search ['UID', "#{cur_offset}:#{end_offset}"]
103 def start_offset; 1; end
105 connect or return start_offset
106 @imap.uid_search(['ALL']).last
110 Redwood::register_yaml(IMAP, %w(uri username password cur_offset usual archived id))