blob: 787c760c4d120893a8f782d2c80c1e46208b9911 [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossum524f1461994-09-05 11:51:33 +00002
3# Convert MH directories (1 message per file) or MMDF mailboxes (4x^A
4# delimited) to unix mailbox (From ... delimited) on stdout.
5# If -f is given, files contain one message per file (e.g. MH messages)
6
7import rfc822
8import sys
9import time
10import os
11import stat
12import getopt
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013import re
Guido van Rossum524f1461994-09-05 11:51:33 +000014
15def main():
Tim Peterse6ddc8b2004-07-18 05:56:09 +000016 dofile = mmdf
17 try:
18 opts, args = getopt.getopt(sys.argv[1:], 'f')
Guido van Rossumb940e112007-01-10 16:19:56 +000019 except getopt.error as msg:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000020 sys.stderr.write('%s\n' % msg)
21 sys.exit(2)
22 for o, a in opts:
23 if o == '-f':
24 dofile = message
25 if not args:
26 args = ['-']
27 sts = 0
28 for arg in args:
29 if arg == '-' or arg == '':
30 sts = dofile(sys.stdin) or sts
31 elif os.path.isdir(arg):
32 sts = mh(arg) or sts
33 elif os.path.isfile(arg):
34 try:
35 f = open(arg)
Guido van Rossumb940e112007-01-10 16:19:56 +000036 except IOError as msg:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000037 sys.stderr.write('%s: %s\n' % (arg, msg))
38 sts = 1
39 continue
40 sts = dofile(f) or sts
41 f.close()
42 else:
43 sys.stderr.write('%s: not found\n' % arg)
44 sts = 1
45 if sts:
46 sys.exit(sts)
Guido van Rossum524f1461994-09-05 11:51:33 +000047
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048numeric = re.compile('[1-9][0-9]*')
Guido van Rossum524f1461994-09-05 11:51:33 +000049
50def mh(dir):
Tim Peterse6ddc8b2004-07-18 05:56:09 +000051 sts = 0
52 msgs = os.listdir(dir)
53 for msg in msgs:
54 if numeric.match(msg) != len(msg):
55 continue
56 fn = os.path.join(dir, msg)
57 try:
58 f = open(fn)
Guido van Rossumb940e112007-01-10 16:19:56 +000059 except IOError as msg:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000060 sys.stderr.write('%s: %s\n' % (fn, msg))
61 sts = 1
62 continue
63 sts = message(f) or sts
64 return sts
Guido van Rossum524f1461994-09-05 11:51:33 +000065
66def mmdf(f):
Tim Peterse6ddc8b2004-07-18 05:56:09 +000067 sts = 0
68 while 1:
69 line = f.readline()
70 if not line:
71 break
72 if line == '\1\1\1\1\n':
73 sts = message(f, line) or sts
74 else:
75 sys.stderr.write(
76 'Bad line in MMFD mailbox: %r\n' % (line,))
77 return sts
Guido van Rossum524f1461994-09-05 11:51:33 +000078
Guido van Rossumee248111995-01-12 12:40:48 +000079counter = 0 # for generating unique Message-ID headers
80
Guido van Rossum524f1461994-09-05 11:51:33 +000081def message(f, delimiter = ''):
Tim Peterse6ddc8b2004-07-18 05:56:09 +000082 sts = 0
83 # Parse RFC822 header
84 m = rfc822.Message(f)
85 # Write unix header line
86 fullname, email = m.getaddr('From')
87 tt = m.getdate('Date')
88 if tt:
89 t = time.mktime(tt)
90 else:
91 sys.stderr.write(
92 'Unparseable date: %r\n' % (m.getheader('Date'),))
93 t = os.fstat(f.fileno())[stat.ST_MTIME]
Collin Winter6f2df4d2007-07-17 20:59:35 +000094 print('From', email, time.ctime(t))
Tim Peterse6ddc8b2004-07-18 05:56:09 +000095 # Copy RFC822 header
96 for line in m.headers:
Collin Winter6f2df4d2007-07-17 20:59:35 +000097 print(line, end=' ')
Tim Peterse6ddc8b2004-07-18 05:56:09 +000098 # Invent Message-ID header if none is present
Collin Winter6f2df4d2007-07-17 20:59:35 +000099 if 'message-id' not in m:
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000100 global counter
101 counter = counter + 1
102 msgid = "<%s.%d>" % (hex(t), counter)
103 sys.stderr.write("Adding Message-ID %s (From %s)\n" %
104 (msgid, email))
Collin Winter6f2df4d2007-07-17 20:59:35 +0000105 print("Message-ID:", msgid)
106 print()
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000107 # Copy body
108 while 1:
109 line = f.readline()
110 if line == delimiter:
111 break
112 if not line:
113 sys.stderr.write('Unexpected EOF in message\n')
114 sts = 1
115 break
116 if line[:5] == 'From ':
117 line = '>' + line
Collin Winter6f2df4d2007-07-17 20:59:35 +0000118 print(line, end=' ')
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000119 # Print trailing newline
Collin Winter6f2df4d2007-07-17 20:59:35 +0000120 print()
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000121 return sts
Guido van Rossum524f1461994-09-05 11:51:33 +0000122
Johannes Gijsbers7a8c43e2004-09-11 16:34:35 +0000123if __name__ == "__main__":
124 main()