-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmimesplit.py
executable file
·64 lines (55 loc) · 2.09 KB
/
mimesplit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/usr/bin/python3
"""Unpacks a MIME message into a directory of files."""
import os
import email
import mimetypes
import re
from email.policy import default
from sys import stdin
from argparse import ArgumentParser, FileType
def main():
parser = ArgumentParser(description="""\
Unpack a MIME message into a directory of files.
""")
parser.add_argument('-d', '--directory', required=True,
help="""Unpack the MIME message into the named
directory, which will be created if it doesn't already
exist.""")
parser.add_argument('msgfile')
args = parser.parse_args()
with open(args.msgfile, 'rb') as fp:
msg = email.message_from_binary_file(fp, policy=default)
try:
os.mkdir(args.directory)
except FileExistsError:
pass
counter = 1
for part in msg.walk():
# multipart/* are just containers
if part.get_content_maintype() == 'multipart':
continue
filename = part.get_filename()
mime_type = part.get_content_type()
print(f'Part {counter}: ')
print(f'\tMIME Type: {str(mime_type)}')
print(f'\tDetected Name: {str(filename)}')
# Most attachments will have file names, but the text and html versions of the email body will not.
if not filename:
# directly specifying txt and html because the guess_extension function
# didn't work very well for those types
if mime_type == 'text/plain':
ext = '.txt'
elif mime_type == 'text/html':
ext = '.html'
else:
ext = mimetypes.guess_extension(mime_type, strict=False)
if not ext:
# Use a generic bag-of-bits extension
ext = '.bin'
filename = f'part-{counter:03d}{ext}'
print(f'\tOutput Name: {str(filename)}')
counter += 1
with open(os.path.join(args.directory, filename), 'wb') as fp:
fp.write(part.get_payload(decode=True))
if __name__ == '__main__':
main()