From: _why Date: 2006-11-29T14:00:16+09:00 Subject: Re: [ANN] sup 0.0.1 Released -- rubies for emails --0OAP2g/MAC+5xKAE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Nov 29, 2006 at 08:01:57AM +0900, William Morgan wrote: > The goal of Sup is to become the email client of choice for nerds > everywhere. I am ((so)) into this. Here's a patch for IMAP support (SSL as well). Just do sup-import imaps://user:pass@host/mailbox You can only do one mailbox for now. _why --0OAP2g/MAC+5xKAE Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="sup-imap-rev44.patch" Index: lib/sup/imap.rb =================================================================== --- lib/sup/imap.rb (revision 0) +++ lib/sup/imap.rb (revision 0) @@ -0,0 +1,91 @@ +require 'thread' +require 'rmail' +require 'uri' +require 'net/imap' +require 'stringio' + +module Redwood + +class Imap + attr_reader :uri + bool_reader :usual, :archived, :read, :dirty + attr_accessor :id, :labels + + class Error < StandardError; end + + ## end_offset is the last offsets within the file which we've read. + ## everything after that is considered new messages that haven't + ## been indexed. + def initialize uri, end_offset=0, usual=true, archived=false, id=nil + @uri = URI(uri) + @end_offset = end_offset + @dirty = false + @usual = usual + @archived = archived + @id = id + @mutex = Mutex.new + @imap = Net::IMAP.new @uri.host, ssl? ? 993 : 143, ssl? + @imap.authenticate('LOGIN', @uri.user, @uri.password) + @imap.examine(mailbox) + @new = + if end_offset > 0 + @imap.search(['SINCE', Time.at(end_offset).strftime('%d-%b-%Y')]) + else + @imap.search(['ALL']) + end + @labels = ([ + :unread, + archived ? nil : :inbox, + ] + + if File.dirname(uri) =~ /\b(var|usr|spool)\b/ + [] + else + [File.basename(uri).intern] + end).compact + end + + def mailbox; @uri.path[1..-1] end + def ssl?; @uri.scheme == 'imaps' end + def reset!; @end_offset = 0; @dirty = true; end + def == o; o.is_a?(Loader) && o.uri == uri; end + def to_s; @uri.to_s; end + + def is_source_for? s + @uri.to_s == s + end + + def load_header msg_id=nil + msg = @imap.fetch(msg_id, ['RFC822.HEADER'])[0].attr + hdr = MBox::read_header(StringIO.new(msg['RFC822.HEADER'])) + hdr['Message-Id'] = "#{mailbox}##{msg_id}" + hdr + end + + def load_message msg_id + m = RMail::Parser.read(@imap.fetch(msg_id, 'RFC822')[0].attr['RFC822'].gsub(/\r\n/, "\n")) + m + end + + ## load the full header text + def load_header_text msg_id + @imap.fetch(msg_id, 'RFC822.HEADER')[0].attr['RFC822.HEADER'] + end + + def each + until @new.empty? + msg_id = @new.shift + yield msg_id, labels + end + end + + def each_header + each { |offset, labels| yield offset, labels, load_header(offset) } + end + + def done?; @new.empty?; end + def total; @new.count; end +end + +Redwood::register_yaml(Imap, %w(uri end_offset usual archived id)) + +end Index: lib/sup.rb =================================================================== --- lib/sup.rb (revision 44) +++ lib/sup.rb (working copy) @@ -93,6 +93,7 @@ require "sup/update" require "sup/message" require "sup/mbox" +require "sup/imap" require "sup/person" require "sup/account" require "sup/thread" Index: bin/sup-import =================================================================== --- bin/sup-import (revision 44) +++ bin/sup-import (working copy) @@ -83,7 +83,14 @@ sources = ARGV.map do |fn| source = index.source_for fn unless source - source = Redwood::MBox::Loader.new(fn, 0, !unusual, !!archive) + source = + case fn + when %r!^imaps?://! + require 'sup/imap' + Redwood::Imap.new(fn, 0, !unusual, !!archive) + else + Redwood::MBox::Loader.new(fn, 0, !unusual, !!archive) + end index.add_source source end source --0OAP2g/MAC+5xKAE--