]> git.phdru.name Git - mimedecode.git/blobdiff - mimedecode.py
Avoid calling get_content_maintype, just split ctype instead
[mimedecode.git] / mimedecode.py
index 392e70774e5f1cb2537c5b94fa87906a71470f22..48a6aba65ff01450825798e128319e0479d4e917 100755 (executable)
@@ -1,10 +1,9 @@
 #! /usr/bin/env python
 """Decode MIME message"""
 
-from mimedecode_version import __version__, __author__, __copyright__, __license__
-
 import sys, os
-import email
+from mimedecode_version import __version__, \
+    __author__, __copyright__, __license__
 
 me = os.path.basename(sys.argv[0])
 
@@ -263,6 +262,18 @@ def totext(msg, instring):
     return s
 
 
+mimetypes = None
+
+def _guess_extension(ctype):
+    global mimetypes
+    if mimetypes is None:
+        import mimetypes
+        mimetypes.init()
+        user_mime_type = os.path.expanduser('~/.mime.types')
+        if os.path.exists(user_mime_type):
+            mimetypes._db.read(user_mime_type)
+    return mimetypes.guess_extension(ctype)
+
 def _save_message(msg, outstring, save_headers=False, save_body=False):
     for header, param in (
         ("Content-Disposition", "filename"),
@@ -270,12 +281,23 @@ def _save_message(msg, outstring, save_headers=False, save_body=False):
     ):
         fname = msg.get_param(param, header=header)
         if fname:
+            if isinstance(fname, tuple):
+                fname = fname[2] # Do not recode if it isn't recoded yet
+            try:
+                    for forbidden in chr(0), '/', '\\':
+                        if forbidden in fname:
+                            raise ValueError
+            except ValueError:
+                continue
             fname = '-' + fname
             break
     else:
         fname = ''
     g.save_counter += 1
     fname = str(g.save_counter) + fname
+    if '.' not in fname:
+        ext = _guess_extension(msg.get_content_type())
+        if ext: fname += ext
 
     global output
     save_output = output
@@ -299,8 +321,7 @@ def decode_part(msg):
     ctype = msg.get_content_type()
     if ctype:
         masks.append(ctype)
-    mtype = msg.get_content_maintype()
-    if mtype:
+        mtype = ctype.split('/')[0]
         masks.append(mtype + '/*')
     masks.append('*/*')
 
@@ -396,7 +417,16 @@ def decode_message(msg):
 
 
 def open_output_file(filename):
-    return open(os.path.join(g.destination_dir, filename), 'w')
+    fullpath = os.path.abspath(os.path.join(g.destination_dir, filename))
+    full_dir = os.path.dirname(fullpath)
+    create = not os.path.isdir(full_dir)
+    if create:
+        os.makedirs(full_dir)
+    try:
+        return open(fullpath, 'w')
+    except:
+        if create:
+            os.removedirs(full_dir)
 
 
 class GlobalOptions:
@@ -566,6 +596,7 @@ if __name__ == "__main__":
     g.outfile = outfile
     output = outfile.write
 
+    import email
     msg = email.message_from_file(infile)
 
     for header, value in g.set_header_value: