11# -*- encoding: utf-8 -*-
2+ import os
3+ import re
24import six
5+ from unicodedata import normalize
36
47
58class dict2object (dict ):
69 """Dict to fake object that can use getattr.
710
811 Examples::
912
10- In [2]: obj = dict2object({'a':2, 'c':3})
13+ In [2]: obj = dict2object({'a': 2, 'c': 3})
1114
1215 In [3]: obj.a
1316 Out[3]: 2
@@ -26,3 +29,48 @@ def __setattr__(self, name, value):
2629 if not isinstance (name , six .string_types ):
2730 raise TypeError ('key must be string type.' )
2831 self [name ] = value
32+
33+
34+ def secure_filename (filename ):
35+ """Borrowed from werkzeug.utils.secure_filename. **Python3 only**.
36+
37+ Pass it a filename and it will return a secure version of it. This
38+ filename can then safely be stored on a regular file system and passed
39+ to :func:`os.path.join`.
40+
41+ On windows systems the function also makes sure that the file is not
42+ named after one of the special device files.
43+
44+ >>> secure_filename("My cool movie.mov")
45+ 'My_cool_movie.mov'
46+ >>> secure_filename("../../../etc/passwd")
47+ 'etc_passwd'
48+ >>> secure_filename(u'i contain cool \xfc ml\xe4 uts.txt')
49+ 'i_contain_cool_umlauts.txt'
50+ """
51+ for sep in os .path .sep , os .path .altsep :
52+ if sep :
53+ filename = filename .replace (sep , ' ' )
54+
55+ filename = '_' .join (filename .split ())
56+
57+ if isinstance (filename , six .text_type ):
58+ filename = normalize ('NFKD' , filename ).encode ('utf-8' )
59+ if not six .PY2 :
60+ filename = filename .decode ('utf-8' )
61+
62+ filename_strip_re = re .compile (r'[^A-Za-z0-9\u4e00-\u9fa5_.-]' )
63+ filename = filename_strip_re .sub ('' , filename ).strip ('._' )
64+
65+ # on nt a couple of special files are present in each folder. We
66+ # have to ensure that the target file is not such a filename. In
67+ # this case we prepend an underline
68+ windows_device_files = (
69+ 'CON' , 'AUX' , 'COM1' , 'COM2' , 'COM3' , 'COM4' , 'LPT1' ,
70+ 'LPT2' , 'LPT3' , 'PRN' , 'NUL' ,
71+ )
72+ if os .name == 'nt' and filename and \
73+ filename .split ('.' )[0 ].upper () in windows_device_files :
74+ filename = '_' + filename
75+
76+ return filename
0 commit comments