diff options
Diffstat (limited to 'interfaces/xml/be-mbox-to-xml')
-rwxr-xr-x | interfaces/xml/be-mbox-to-xml | 151 |
1 files changed, 0 insertions, 151 deletions
diff --git a/interfaces/xml/be-mbox-to-xml b/interfaces/xml/be-mbox-to-xml deleted file mode 100755 index a740117..0000000 --- a/interfaces/xml/be-mbox-to-xml +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2009 W. Trevor King <wking@drexel.edu> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -""" -Convert an mbox into xml suitable for imput into be. - $ cat mbox | be-mbox-to-xml | be comment --xml <ID> - -mbox is a flat-file format, consisting of a series of messages. -Messages begin with a a From_ line, followed by RFC 822 email, -followed by a blank line. -""" - -import base64 -import email.utils -from libbe.encoding import get_encoding, set_IO_stream_encodings -from libbe.utility import time_to_str -from mailbox import mbox, Message # the mailbox people really want an on-disk copy -from time import asctime, gmtime, mktime -import types -from xml.sax.saxutils import escape - -DEFAULT_ENCODING = get_encoding() -set_IO_stream_encodings(DEFAULT_ENCODING) - -KNOWN_IDS = [] - -def normalize_email_address(address): - """ - Standardize whitespace, etc. - """ - return email.utils.formataddr(email.utils.parseaddr(address)) - -def normalize_RFC_2822_date(date): - """ - Some email clients write non-RFC 2822-compliant date tags like: - Fri, 18 Sep 2009 08:49:02 -0400 (EDT) - with the non-standard (EDT) timezone name. This funtion attempts - to deal with such inconsistencies. - """ - time_tuple = email.utils.parsedate(date) - assert time_tuple != None, \ - 'unparsable date: "%s"' % date - return time_to_str(mktime(time_tuple)) - -def comment_message_to_xml(message, fields=None): - if fields == None: - fields = {} - 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'author'] = normalize_email_address(message[u'from']) - new_fields[u'date'] = message[u'date'] - if new_fields[u'date'] != None: - new_fields[u'date'] = normalize_RFC_2822_date(new_fields[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 fields[u'in-reply-to'] == None: - if message[u'references'] != None: - refs = message[u'references'].split() - for ref in refs: # search for a known reference id. - if ref in KNOWN_IDS: - fields[u'in-reply-to'] = ref - break - if fields[u'in-reply-to'] == None and len(refs) > 0: - fields[u'in-reply-to'] = refs[0] # default to the first - else: # check for mutliple in-reply-to references. - refs = fields[u'in-reply-to'].split() - found_ref = False - for ref in refs: # search for a known reference id. - if ref in KNOWN_IDS: - fields[u'in-reply-to'] = ref - found_ref = True - break - if found_ref == False and len(refs) > 0: - fields[u'in-reply-to'] = refs[0] # default to the first - - if fields[u'alt-id'] != None: - KNOWN_IDS.append(fields[u'alt-id']) - - if message.is_multipart(): - ret = [] - alt_id = fields[u'alt-id'] - from_str = fields[u'author'] - date = fields[u'date'] - for m in message.walk(): - if m == message: - continue - fields[u'author'] = from_str - fields[u'date'] = date - if len(ret) > 0: # we've added one part already - fields.pop(u'alt-id') # don't pass alt-id to other parts - fields[u'in-reply-to'] = alt_id # others respond to first - ret.append(comment_message_to_xml(m, fields)) - return u'\n'.join(ret) - - charset = message.get_content_charset(DEFAULT_ENCODING).lower() - #assert charset == DEFAULT_ENCODING.lower(), \ - # u"Unknown charset: %s" % charset - - if message[u'content-transfer-encoding'] == None: - encoding = DEFAULT_ENCODING - else: - encoding = message[u'content-transfer-encoding'].lower() - body = message.get_payload(decode=True) # attempt to decode - assert body != None, "Unable to decode?" - if fields[u'content-type'].startswith(u"text/"): - body = unicode(body, encoding=charset).rstrip(u'\n') - else: - body = base64.encode(body) - fields[u'body'] = body - lines = [u"<comment>"] - for tag,body in fields.items(): - if body != None: - ebody = escape(body) - lines.append(u" <%s>%s</%s>" % (tag, ebody, tag)) - lines.append(u"</comment>") - return u'\n'.join(lines) - -def main(mbox_filename): - mb = mbox(mbox_filename) - print u'<?xml version="1.0" encoding="%s" ?>' % DEFAULT_ENCODING - print u"<comment-list>" - for message in mb: - print comment_message_to_xml(message) - print u"</comment-list>" - - -if __name__ == "__main__": - import sys - main(sys.argv[1]) |