1#!/usr/bin/env python
2
3"""Unpack a MIME message into a directory of files."""
4
5import os
6import sys
7import email
8import errno
9import mimetypes
10
11from optparse import OptionParser
12
13
14def main():
15    parser = OptionParser(usage="""\
16Unpack a MIME message into a directory of files.
17
18Usage: %prog [options] msgfile
19""")
20    parser.add_option('-d', '--directory',
21                      type='string', action='store',
22                      help="""Unpack the MIME message into the named
23                      directory, which will be created if it doesn't already
24                      exist.""")
25    opts, args = parser.parse_args()
26    if not opts.directory:
27        parser.print_help()
28        sys.exit(1)
29
30    try:
31        msgfile = args[0]
32    except IndexError:
33        parser.print_help()
34        sys.exit(1)
35
36    try:
37        os.mkdir(opts.directory)
38    except OSError as e:
39        # Ignore directory exists error
40        if e.errno != errno.EEXIST:
41            raise
42
43    fp = open(msgfile)
44    msg = email.message_from_file(fp)
45    fp.close()
46
47    counter = 1
48    for part in msg.walk():
49        # multipart/* are just containers
50        if part.get_content_maintype() == 'multipart':
51            continue
52        # Applications should really sanitize the given filename so that an
53        # email message can't be used to overwrite important files
54        filename = part.get_filename()
55        if not filename:
56            ext = mimetypes.guess_extension(part.get_content_type())
57            if not ext:
58                # Use a generic bag-of-bits extension
59                ext = '.bin'
60            filename = 'part-%03d%s' % (counter, ext)
61        counter += 1
62        fp = open(os.path.join(opts.directory, filename), 'wb')
63        fp.write(part.get_payload(decode=True))
64        fp.close()
65
66
67if __name__ == '__main__':
68    main()
69