| #!/usr/bin/env python | 
 |  | 
 | """Unpack a MIME message into a directory of files. | 
 |  | 
 | Usage: unpackmail [options] msgfile | 
 |  | 
 | Options: | 
 |     -h / --help | 
 |         Print this message and exit. | 
 |  | 
 |     -d directory | 
 |     --directory=directory | 
 |         Unpack the MIME message into the named directory, which will be | 
 |         created if it doesn't already exist. | 
 |  | 
 | msgfile is the path to the file containing the MIME message. | 
 | """ | 
 |  | 
 | import sys | 
 | import os | 
 | import getopt | 
 | import errno | 
 | import mimetypes | 
 | import email | 
 |  | 
 |  | 
 | def usage(code, msg=''): | 
 |     print >> sys.stderr, __doc__ | 
 |     if msg: | 
 |         print >> sys.stderr, msg | 
 |     sys.exit(code) | 
 |  | 
 |  | 
 | def main(): | 
 |     try: | 
 |         opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory=']) | 
 |     except getopt.error, msg: | 
 |         usage(1, msg) | 
 |  | 
 |     dir = os.curdir | 
 |     for opt, arg in opts: | 
 |         if opt in ('-h', '--help'): | 
 |             usage(0) | 
 |         elif opt in ('-d', '--directory'): | 
 |             dir = arg | 
 |  | 
 |     try: | 
 |         msgfile = args[0] | 
 |     except IndexError: | 
 |         usage(1) | 
 |  | 
 |     try: | 
 |         os.mkdir(dir) | 
 |     except OSError, e: | 
 |         # Ignore directory exists error | 
 |         if e.errno <> errno.EEXIST: raise | 
 |  | 
 |     fp = open(msgfile) | 
 |     msg = email.message_from_file(fp) | 
 |     fp.close() | 
 |  | 
 |     counter = 1 | 
 |     for part in msg.walk(): | 
 |         # multipart/* are just containers | 
 |         if part.get_content_maintype() == 'multipart': | 
 |             continue | 
 |         # Applications should really sanitize the given filename so that an | 
 |         # email message can't be used to overwrite important files | 
 |         filename = part.get_filename() | 
 |         if not filename: | 
 |             ext = mimetypes.guess_extension(part.get_type()) | 
 |             if not ext: | 
 |                 # Use a generic bag-of-bits extension | 
 |                 ext = '.bin' | 
 |             filename = 'part-%03d%s' % (counter, ext) | 
 |         counter += 1 | 
 |         fp = open(os.path.join(dir, filename), 'wb') | 
 |         fp.write(part.get_payload(decode=1)) | 
 |         fp.close() | 
 |  | 
 |  | 
 | if __name__ == '__main__': | 
 |     main() |