be-mbox-to-xml passes attributes on to each part of multipart messages.
authorW. Trevor King <wking@drexel.edu>
Sun, 12 Jul 2009 17:56:05 +0000 (13:56 -0400)
committerW. Trevor King <wking@drexel.edu>
Sun, 12 Jul 2009 17:56:05 +0000 (13:56 -0400)
Previously "message[<some-attr>]" just returned None if it wasn't set
for that message part, which overwrote anything passed in through
fields.

"from" and "date" added to list of attributes passed along.

For be-xml-to-mbox, "alt-id" was added to Comment._attrs,
and Comment.print_to_mbox was adjusted to handle the case where
we have no information about the parent bug.

With all of this, I can complete the loop
  be-mbox-to-xml example.mbox | be-xml-to-mbox > example2.mbox
without errors :p.

Finally, be-xml-to-mbox has been adjusted to also work on files (it
had previously only handled data via stdin).  We can't add stdin
handling to be-mbox-to-xml though, because the mailbox package needs
an actual file to work on, and I haven't setup a tmpfile workaround
yet...

xml/be-mbox-to-xml
xml/be-xml-to-mbox

index e9077b12e1bcad2f84faa7af9153bb029f522d0e..9054cfdadb0b9f9c407f463ea4f13225c3e2d4f8 100755 (executable)
@@ -22,13 +22,12 @@ Messages begin with a a From_ line, followed by RFC 822 email,
 followed by a blank line.
 """
 
-from mailbox import mbox, Message  # the mailbox people really want an on-disk copy
-import email.utils
-import types
-
 import base64
+import email.utils
 from libbe.encoding import get_encoding, set_IO_stream_encodings
+from mailbox import mbox, Message  # the mailbox people really want an on-disk copy
 from time import asctime, gmtime
+import types
 from xml.sax import make_parser
 from xml.sax.handler import ContentHandler
 from xml.sax.saxutils import escape
@@ -39,21 +38,32 @@ set_IO_stream_encodings(DEFAULT_ENCODING)
 def comment_message_to_xml(message, fields=None):
     if fields == None:
         fields = {}
-    fields[u'alt-id'] = message[u'message-id']
-    fields[u'in-reply-to'] = message[u'in-reply-to']
-    fields[u'from'] = message[u'from']
-    fields[u'date'] = message[u'date']
-    fields[u'content-type'] = message.get_content_type()
-    for k,v in fields.items():
+    new_fields = {}
+    new_fields[u'alt-id'] = message[u'message-id']
+    new_fields[u'in-reply-to'] = message[u'in-reply-to']
+    new_fields[u'from'] = message[u'from']
+    new_fields[u'date'] = message[u'date']
+    new_fields[u'content-type'] = message.get_content_type()
+    for k,v in new_fields.items():
         if v != None and type(v) != types.UnicodeType:
             fields[k] = unicode(v, encoding=DEFAULT_ENCODING)
+        elif v == None and k in fields:
+            new_fields[k] = fields[k]
+    for k,v in fields.items():
+        if k not in new_fields:
+            new_fields.k = fields[k]
+    fields = new_fields
 
     if message.is_multipart():
         ret = []
         alt_id = fields[u'alt-id']
+        from_str = fields[u'from']
+        date = fields[u'date']
         for m in message.walk():
             if m == message:
                 continue
+            fields[u'from'] = from_str
+            fields[u'date'] = date
             if len(ret) >= 0:
                 fields.pop(u'alt-id')
                 fields[u'in-reply-to'] = alt_id
index 5e59e8cc30754a6ac7a503562df5f5657ae71eab..b74a33df2cc2fcdd308987cf2021694f0ac2f03f 100755 (executable)
@@ -26,6 +26,7 @@ followed by a blank line.
 """
 
 #from mailbox import mbox, Message  # the mailbox people really want an on-disk copy
+import codecs
 import email.utils
 from libbe.encoding import get_encoding, set_IO_stream_encodings
 from libbe.utility import str_to_time as rfc2822_to_gmtime_integer
@@ -125,19 +126,34 @@ class Bug (LimitedAttrDict):
 
 class Comment (LimitedAttrDict):
     _attrs = [u"uuid",
+              u"alt-id",
               u"short-name",
               u"in-reply-to",
               u"from",
               u"date",
               u"content-type",
               u"body"]
-    def print_to_mbox(self, bug):
+    def print_to_mbox(self, bug=None):
+        if bug == None:
+            bug = Bug()
+            bug[u"uuid"] = u"no-uuid"
         name,addr = email.utils.parseaddr(self["from"])
         print "From %s %s" % (addr, rfc2822_to_asctime(self["date"]))
-        print "Message-ID: <%s@%s>" % (self["uuid"], DEFAULT_DOMAIN)
+        if "uuid" in self:     id = self["uuid"]
+        elif "alt-id" in self: id = self["alt-id"]
+        else:                  id = None
+        if id != None:
+            print "Message-ID: <%s@%s>" % (id, DEFAULT_DOMAIN)
         print "Date: %s" % self["date"]
         print "From: %s" % self["from"]
-        print "Subject: %s: %s" % (self["short-name"], bug["summary"])
+        subject = ""
+        if "short-name" in self:
+            subject += self["short-name"]+u": "
+        if "summary" in bug:
+            subject += bug["summary"]
+        else:
+            subject += u"no-subject"
+        print "Subject: %s" % subject
         if "in-reply-to" not in self.keys():
             self["in-reply-to"] = bug["uuid"]
         print "In-Reply-To: <%s@%s>" % (self["in-reply-to"], DEFAULT_DOMAIN)
@@ -179,8 +195,11 @@ def print_to_mbox(element):
 
 if __name__ == "__main__":
     import sys
-    
-    xml_unicode = sys.stdin.read()
+
+    if len(sys.argv) == 1: # no filename given, use stdin
+        xml_unicode = sys.stdin.read()
+    else:
+        xml_unicode = codecs.open(sys.argv[1], "r", DEFAULT_ENCODING).read()
     xml_str = xml_unicode.encode("unicode_escape").replace(r"\n", "\n")
     elist = ElementTree.XML(xml_str)
     print_to_mbox(elist)