|
1 #!/usr/bin/env python |
|
2 |
|
3 """Unpack a MIME message into a directory of files.""" |
|
4 |
|
5 import os |
|
6 import sys |
|
7 import email |
|
8 import errno |
|
9 import mimetypes |
|
10 |
|
11 from optparse import OptionParser |
|
12 |
|
13 |
|
14 def main(): |
|
15 parser = OptionParser(usage="""\ |
|
16 Unpack a MIME message into a directory of files. |
|
17 |
|
18 Usage: %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, 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 |
|
67 if __name__ == '__main__': |
|
68 main() |