-
-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathCleanPath.py
More file actions
executable file
·103 lines (76 loc) · 2.64 KB
/
Copy pathCleanPath.py
File metadata and controls
executable file
·103 lines (76 loc) · 2.64 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from pathlib import Path
class CleanPath(type(Path())):
"""
Subclass of Path that is more OS-agnostic and implements methods of
cleaning directories and filenames of bad characters. For example:
>>> p = CleanPath('./some_file: 123.jpg')
>>> print(p)
'./some_file: 123.jpg'
>>> print(p.sanitize())
>>> '{parent folders}/some_file - 123.jpg'
"""
"""Mapping of illegal filename characters and their replacements"""
ILLEGAL_FILE_CHARACTERS = {
'?': '!',
'<': '',
'>': '',
':':' -',
'"': '',
'|': '',
'*': '-',
'/': '+',
'\\': '+',
}
def __new__(cls, *pathsegments: str):
return super().__new__(cls, *pathsegments)
def finalize(self) -> 'CleanPath':
"""
Finalize this path by properly resolving if absolute or
relative.
Returns:
This object as a fully resolved path.
Raises:
OSError if the resolution fails (likely due to an
unresolvable filename).
"""
return (CleanPath.cwd() / self).resolve()
@staticmethod
def sanitize_name(filename: str) -> str:
"""
Sanitize the given filename to remove any illegal characters.
Args:
filename: Filename to remove illegal characters from.
Returns:
Sanitized filename.
"""
replacements = CleanPath.ILLEGAL_FILE_CHARACTERS
return filename.translate(str.maketrans(replacements))[:254]
@staticmethod
def _sanitize_parts(path: 'CleanPath') -> 'CleanPath':
"""
Sanitize all parts of the given path based on the current OS.
Args:
path: Path to sanitize.
Returns:
Sanitized path. This is a reconstructed CleanPath object
with each folder (or part), except the root/drive,
sanitized.
"""
return CleanPath(
path.parts[0],
*[CleanPath.sanitize_name(name) for name in path.parts[1:]]
)
def sanitize(self) -> 'CleanPath':
"""
Sanitize all parts (except the root) of this objects path.
Returns:
CleanPath object instantiated with sanitized names of each
part of this object's path.
"""
# Attempt to resolve immediately
try:
finalized_path = self.finalize()
# If path resolution raises an error, clean and then re-resolve
except Exception: # pylint: disable=broad-except
finalized_path =self._sanitize_parts(CleanPath.cwd()/self).resolve()
return self._sanitize_parts(finalized_path)