| #! /usr/bin/env python | 
 |  | 
 | # Convert  MH directories (1 message per file) or MMDF mailboxes (4x^A | 
 | # delimited) to unix mailbox (From ... delimited) on stdout. | 
 | # If -f is given, files contain one message per file (e.g. MH messages) | 
 |  | 
 | import rfc822 | 
 | import sys | 
 | import time | 
 | import os | 
 | import stat | 
 | import getopt | 
 | import regex | 
 |  | 
 | def main(): | 
 |     dofile = mmdf | 
 |     try: | 
 |         opts, args = getopt.getopt(sys.argv[1:], 'f') | 
 |     except getopt.error, msg: | 
 |         sys.stderr.write('%s\n' % msg) | 
 |         sys.exit(2) | 
 |     for o, a in opts: | 
 |         if o == '-f': | 
 |             dofile = message | 
 |     if not args: | 
 |         args = ['-'] | 
 |     sts = 0 | 
 |     for arg in args: | 
 |         if arg == '-' or arg == '': | 
 |             sts = dofile(sys.stdin) or sts | 
 |         elif os.path.isdir(arg): | 
 |             sts = mh(arg) or sts | 
 |         elif os.path.isfile(arg): | 
 |             try: | 
 |                 f = open(arg) | 
 |             except IOError, msg: | 
 |                 sys.stderr.write('%s: %s\n' % (arg, msg)) | 
 |                 sts = 1 | 
 |                 continue | 
 |             sts = dofile(f) or sts | 
 |             f.close() | 
 |         else: | 
 |             sys.stderr.write('%s: not found\n' % arg) | 
 |             sts = 1 | 
 |     if sts: | 
 |         sys.exit(sts) | 
 |  | 
 | numeric = regex.compile('[1-9][0-9]*') | 
 |  | 
 | def mh(dir): | 
 |     sts = 0 | 
 |     msgs = os.listdir(dir) | 
 |     for msg in msgs: | 
 |         if numeric.match(msg) != len(msg): | 
 |             continue | 
 |         fn = os.path.join(dir, msg) | 
 |         try: | 
 |             f = open(fn) | 
 |         except IOError, msg: | 
 |             sys.stderr.write('%s: %s\n' % (fn, msg)) | 
 |             sts = 1 | 
 |             continue | 
 |         sts = message(f) or sts | 
 |     return sts | 
 |  | 
 | def mmdf(f): | 
 |     sts = 0 | 
 |     while 1: | 
 |         line = f.readline() | 
 |         if not line: | 
 |             break | 
 |         if line == '\1\1\1\1\n': | 
 |             sts = message(f, line) or sts | 
 |         else: | 
 |             sys.stderr.write( | 
 |                     'Bad line in MMFD mailbox: %r\n' % (line,)) | 
 |     return sts | 
 |  | 
 | counter = 0 # for generating unique Message-ID headers | 
 |  | 
 | def message(f, delimiter = ''): | 
 |     sts = 0 | 
 |     # Parse RFC822 header | 
 |     m = rfc822.Message(f) | 
 |     # Write unix header line | 
 |     fullname, email = m.getaddr('From') | 
 |     tt = m.getdate('Date') | 
 |     if tt: | 
 |         t = time.mktime(tt) | 
 |     else: | 
 |         sys.stderr.write( | 
 |                 'Unparseable date: %r\n' % (m.getheader('Date'),)) | 
 |         t = os.fstat(f.fileno())[stat.ST_MTIME] | 
 |     print 'From', email, time.ctime(t) | 
 |     # Copy RFC822 header | 
 |     for line in m.headers: | 
 |         print line, | 
 |     # Invent Message-ID header if none is present | 
 |     if not m.has_key('message-id'): | 
 |         global counter | 
 |         counter = counter + 1 | 
 |         msgid = "<%s.%d>" % (hex(t), counter) | 
 |         sys.stderr.write("Adding Message-ID %s (From %s)\n" % | 
 |                          (msgid, email)) | 
 |         print "Message-ID:", msgid | 
 |     print | 
 |     # Copy body | 
 |     while 1: | 
 |         line = f.readline() | 
 |         if line == delimiter: | 
 |             break | 
 |         if not line: | 
 |             sys.stderr.write('Unexpected EOF in message\n') | 
 |             sts = 1 | 
 |             break | 
 |         if line[:5] == 'From ': | 
 |             line = '>' + line | 
 |         print line, | 
 |     # Print trailing newline | 
 |     print | 
 |     return sts | 
 |  | 
 | if __name__ == "__main__": | 
 |     main() |