]> git.cworth.org Git - sup/blobdiff - lib/sup/mbox.rb
giving a block to PollManager#each_message_in_source is now optional
[sup] / lib / sup / mbox.rb
index a4f50462416de8703770ca5629b9bfdb7fb0a6d6..0ce52fe24fd9ff8bbba19bea2141dfd8e4d4625d 100644 (file)
@@ -1,10 +1,14 @@
 require "sup/mbox/loader"
 require "sup/mbox/ssh-file"
 require "sup/mbox/ssh-loader"
+require "sup/rfc2047"
 
 module Redwood
 
-## some utility functions
+## some utility functions. actually these are not mbox-specific at all
+## and should be moved somewhere else.
+##
+## TODO: move functionality to somewhere better, like message.rb
 module MBox
   BREAK_RE = /^From \S+/
 
@@ -16,31 +20,48 @@ module MBox
     ## when scanning over large mbox files.
     while(line = f.gets)
       case line
-      when /^(From):\s+(.*)$/i,
-        /^(To):\s+(.*)$/i,
-        /^(Cc):\s+(.*)$/i,
-        /^(Bcc):\s+(.*)$/i,
-        /^(Subject):\s+(.*)$/i,
-        /^(Date):\s+(.*)$/i,
-        /^(Message-Id):\s+<(.*)>$/i,
-        /^(References):\s+(.*)$/i,
-        /^(In-Reply-To):\s+(.*)$/i,
-        /^(Reply-To):\s+(.*)$/i,
-        /^(List-Post):\s+(.*)$/i,
-        /^(Status):\s+(.*)$/i: header[last = $1] = $2
+      when /^(From):\s+(.*?)\s*$/i,
+        /^(To):\s+(.*?)\s*$/i,
+        /^(Cc):\s+(.*?)\s*$/i,
+        /^(Bcc):\s+(.*?)\s*$/i,
+        /^(Subject):\s+(.*?)\s*$/i,
+        /^(Date):\s+(.*?)\s*$/i,
+        /^(References):\s+(.*?)\s*$/i,
+        /^(In-Reply-To):\s+(.*?)\s*$/i,
+        /^(Reply-To):\s+(.*?)\s*$/i,
+        /^(List-Post):\s+(.*?)\s*$/i,
+        /^(List-Subscribe):\s+(.*?)\s*$/i,
+        /^(List-Unsubscribe):\s+(.*?)\s*$/i,
+        /^(Status):\s+(.*?)\s*$/i: header[last = $1] = $2
+      when /^(Message-Id):\s+(.*?)\s*$/i: header[mid_field = last = $1] = $2
 
       ## these next three can occur multiple times, and we want the
       ## first one
       when /^(Delivered-To):\s+(.*)$/i,
         /^(X-Original-To):\s+(.*)$/i,
-        /^(Envelope-To):\s+(.*)$/i: header[last = $1.downcase] ||= $2
+        /^(Envelope-To):\s+(.*)$/i: header[last = $1] ||= $2
 
       when /^$/: break
-      when /:/: last = nil
+      when /^\S+: /: last = nil # some other header we don't care about
       else
         header[last] += " " + line.chomp.gsub(/^\s+/, "") if last
       end
     end
+
+    if mid_field && header[mid_field] && header[mid_field] =~ /<(.*?)>/
+      header[mid_field] = $1
+    end
+
+    header.each do |k, v|
+      next unless Rfc2047.is_encoded? v
+      header[k] =
+        begin
+          Rfc2047.decode_to $encoding, v
+        rescue Errno::EINVAL, Iconv::InvalidEncoding, Iconv::IllegalSequence => e
+          Redwood::log "warning: error decoding RFC 2047 header (#{e.class.name}): #{e.message}"
+          v
+        end
+    end
     header
   end