/Demo/scripts/mboxconvert.py

http://unladen-swallow.googlecode.com/ · Python · 124 lines · 105 code · 9 blank · 10 comment · 36 complexity · 01bf0562e1b618da39fb21aef0191134 MD5 · raw file

  1. #! /usr/bin/env python
  2. # Convert MH directories (1 message per file) or MMDF mailboxes (4x^A
  3. # delimited) to unix mailbox (From ... delimited) on stdout.
  4. # If -f is given, files contain one message per file (e.g. MH messages)
  5. import rfc822
  6. import sys
  7. import time
  8. import os
  9. import stat
  10. import getopt
  11. import re
  12. def main():
  13. dofile = mmdf
  14. try:
  15. opts, args = getopt.getopt(sys.argv[1:], 'f')
  16. except getopt.error, msg:
  17. sys.stderr.write('%s\n' % msg)
  18. sys.exit(2)
  19. for o, a in opts:
  20. if o == '-f':
  21. dofile = message
  22. if not args:
  23. args = ['-']
  24. sts = 0
  25. for arg in args:
  26. if arg == '-' or arg == '':
  27. sts = dofile(sys.stdin) or sts
  28. elif os.path.isdir(arg):
  29. sts = mh(arg) or sts
  30. elif os.path.isfile(arg):
  31. try:
  32. f = open(arg)
  33. except IOError, msg:
  34. sys.stderr.write('%s: %s\n' % (arg, msg))
  35. sts = 1
  36. continue
  37. sts = dofile(f) or sts
  38. f.close()
  39. else:
  40. sys.stderr.write('%s: not found\n' % arg)
  41. sts = 1
  42. if sts:
  43. sys.exit(sts)
  44. numeric = re.compile('[1-9][0-9]*')
  45. def mh(dir):
  46. sts = 0
  47. msgs = os.listdir(dir)
  48. for msg in msgs:
  49. if numeric.match(msg) != len(msg):
  50. continue
  51. fn = os.path.join(dir, msg)
  52. try:
  53. f = open(fn)
  54. except IOError, msg:
  55. sys.stderr.write('%s: %s\n' % (fn, msg))
  56. sts = 1
  57. continue
  58. sts = message(f) or sts
  59. return sts
  60. def mmdf(f):
  61. sts = 0
  62. while 1:
  63. line = f.readline()
  64. if not line:
  65. break
  66. if line == '\1\1\1\1\n':
  67. sts = message(f, line) or sts
  68. else:
  69. sys.stderr.write(
  70. 'Bad line in MMFD mailbox: %r\n' % (line,))
  71. return sts
  72. counter = 0 # for generating unique Message-ID headers
  73. def message(f, delimiter = ''):
  74. sts = 0
  75. # Parse RFC822 header
  76. m = rfc822.Message(f)
  77. # Write unix header line
  78. fullname, email = m.getaddr('From')
  79. tt = m.getdate('Date')
  80. if tt:
  81. t = time.mktime(tt)
  82. else:
  83. sys.stderr.write(
  84. 'Unparseable date: %r\n' % (m.getheader('Date'),))
  85. t = os.fstat(f.fileno())[stat.ST_MTIME]
  86. print 'From', email, time.ctime(t)
  87. # Copy RFC822 header
  88. for line in m.headers:
  89. print line,
  90. # Invent Message-ID header if none is present
  91. if not m.has_key('message-id'):
  92. global counter
  93. counter = counter + 1
  94. msgid = "<%s.%d>" % (hex(t), counter)
  95. sys.stderr.write("Adding Message-ID %s (From %s)\n" %
  96. (msgid, email))
  97. print "Message-ID:", msgid
  98. print
  99. # Copy body
  100. while 1:
  101. line = f.readline()
  102. if line == delimiter:
  103. break
  104. if not line:
  105. sys.stderr.write('Unexpected EOF in message\n')
  106. sts = 1
  107. break
  108. if line[:5] == 'From ':
  109. line = '>' + line
  110. print line,
  111. # Print trailing newline
  112. print
  113. return sts
  114. if __name__ == "__main__":
  115. main()