Return a new name for `filename` that is portable across operating systems. In particular the returned file name is guaranteed to be: - a portable name on most OSses using a limited ASCII characters set including some limited punctuation. - a valid name on Linux, Windows and
(filename, preserve_spaces=False, posix_only=False)
| 186 | |
| 187 | |
| 188 | def portable_filename(filename, preserve_spaces=False, posix_only=False): |
| 189 | """ |
| 190 | Return a new name for `filename` that is portable across operating systems. |
| 191 | |
| 192 | In particular the returned file name is guaranteed to be: |
| 193 | - a portable name on most OSses using a limited ASCII characters set including |
| 194 | some limited punctuation. |
| 195 | - a valid name on Linux, Windows and Mac. |
| 196 | |
| 197 | Unicode file names are transliterated to plain ASCII. |
| 198 | |
| 199 | See for more details: |
| 200 | - http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html |
| 201 | - https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx |
| 202 | - http://www.boost.org/doc/libs/1_36_0/libs/filesystem/doc/portability_guide.htm |
| 203 | |
| 204 | Also inspired by Werkzeug: |
| 205 | https://raw.githubusercontent.com/pallets/werkzeug/8c2d63ce247ba1345e1b9332a68ceff93b2c07ab/werkzeug/utils.py |
| 206 | |
| 207 | If `preserve_spaces` is True, then spaces in `filename` will not be replaced. |
| 208 | """ |
| 209 | filename = toascii(filename, translit=True) |
| 210 | |
| 211 | if not filename: |
| 212 | return "_" |
| 213 | |
| 214 | if posix_only: |
| 215 | if preserve_spaces: |
| 216 | filename = replace_illegal_posix_chars_exc_spaces("_", filename) |
| 217 | else: |
| 218 | filename = replace_illegal_posix_chars("_", filename) |
| 219 | else: |
| 220 | if preserve_spaces: |
| 221 | filename = replace_illegal_chars_exc_spaces("_", filename) |
| 222 | else: |
| 223 | filename = replace_illegal_chars("_", filename) |
| 224 | |
| 225 | if not posix_only: |
| 226 | basename, dot, extension = filename.partition(".") |
| 227 | if basename.lower() in ILLEGAL_WINDOWS_NAMES: |
| 228 | filename = "".join([basename, "_", dot, extension]) |
| 229 | |
| 230 | # no name made only of dots. |
| 231 | if set(filename) == set(["."]): |
| 232 | filename = "dot" * len(filename) |
| 233 | |
| 234 | # replaced any leading dotdot |
| 235 | if filename != ".." and filename.startswith(".."): |
| 236 | while filename.startswith(".."): |
| 237 | filename = filename.replace("..", "__", 1) |
| 238 | |
| 239 | return filename |
| 240 | |
| 241 | |
| 242 | # |