Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | #!/usr/bin/env python |
2 | ||
3 | """Unpack a MIME message into a directory of files. | |
4 | ||
5 | Usage: unpackmail [options] msgfile | |
6 | ||
7 | Options: | |
8 | -h / --help | |
9 | Print this message and exit. | |
10 | ||
11 | -d directory | |
12 | --directory=directory | |
13 | Unpack the MIME message into the named directory, which will be | |
14 | created if it doesn't already exist. | |
15 | ||
16 | msgfile is the path to the file containing the MIME message. | |
17 | """ | |
18 | ||
19 | import sys | |
20 | import os | |
21 | import getopt | |
22 | import errno | |
23 | import mimetypes | |
24 | import email | |
25 | ||
26 | ||
27 | def usage(code, msg=''): | |
28 | print >> sys.stderr, __doc__ | |
29 | if msg: | |
30 | print >> sys.stderr, msg | |
31 | sys.exit(code) | |
32 | ||
33 | ||
34 | def main(): | |
35 | try: | |
36 | opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory=']) | |
37 | except getopt.error, msg: | |
38 | usage(1, msg) | |
39 | ||
40 | dir = os.curdir | |
41 | for opt, arg in opts: | |
42 | if opt in ('-h', '--help'): | |
43 | usage(0) | |
44 | elif opt in ('-d', '--directory'): | |
45 | dir = arg | |
46 | ||
47 | try: | |
48 | msgfile = args[0] | |
49 | except IndexError: | |
50 | usage(1) | |
51 | ||
52 | try: | |
53 | os.mkdir(dir) | |
54 | except OSError, e: | |
55 | # Ignore directory exists error | |
56 | if e.errno <> errno.EEXIST: raise | |
57 | ||
58 | fp = open(msgfile) | |
59 | msg = email.message_from_file(fp) | |
60 | fp.close() | |
61 | ||
62 | counter = 1 | |
63 | for part in msg.walk(): | |
64 | # multipart/* are just containers | |
65 | if part.get_content_maintype() == 'multipart': | |
66 | continue | |
67 | # Applications should really sanitize the given filename so that an | |
68 | # email message can't be used to overwrite important files | |
69 | filename = part.get_filename() | |
70 | if not filename: | |
71 | ext = mimetypes.guess_extension(part.get_type()) | |
72 | if not ext: | |
73 | # Use a generic bag-of-bits extension | |
74 | ext = '.bin' | |
75 | filename = 'part-%03d%s' % (counter, ext) | |
76 | counter += 1 | |
77 | fp = open(os.path.join(dir, filename), 'wb') | |
78 | fp.write(part.get_payload(decode=1)) | |
79 | fp.close() | |
80 | ||
81 | ||
82 | if __name__ == '__main__': | |
83 | main() |