/
path_strings.py
287 lines (207 loc) · 8.62 KB
/
path_strings.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
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
import re
from urllib.parse import quote
class Path_Strings:
""" String operations for Path. """
def __getitem__(self, item):
""" Get character from path string.
:param generalfile.Path self: """
return self.Path(self.path.__getitem__(item))
@property
def get_part(self):
""" Split path using it's delimiter. item=0 with an absolute path gives an empty string on a posix system.
:param generalfile.Path self:
:param i: Index of part"""
return self.path.split(self.path_delimiter)
def get_replaced_alternative_characters(self):
""" Get a dictionary of all characters that are replaced for the alternative path.
:param generalfile.Path self: """
return {
self.path_delimiter: "/",
":": ":",
".": "."
}
def get_alternative_path(self):
""" Get path using alternative delimiter and alternative root for windows.
:param generalfile.Path self:
:rtype: generalfile.Path """
path = str(self.absolute())
for char, alternative in self.get_replaced_alternative_characters().items():
path = path.replace(char, alternative)
return self.Path(path)
def get_lock_path(self):
""" Get absolute lock path pointing to actual lock.
:param generalfile.Path self: """
return self.get_lock_dir() / self.absolute().get_alternative_path()
def get_path_from_alternative(self):
""" Get path from an alternative representation with or without leading lock dir.
:param generalfile.Path self:
:rtype: generalfile.Path """
path = str(self.remove_start(self.get_lock_dir()))
for char, alternative in self.get_replaced_alternative_characters().items():
path = path.replace(alternative, char)
return self.Path(path)
def absolute(self):
""" Get new Path as absolute.
:param generalfile.Path self:
:rtype: generalfile.Path """
if self.is_absolute():
return self
else:
return self.get_working_dir() / self
# return self.Path(self._path.absolute())
def relative(self, base=None):
""" Get new Path as relative.
:param generalfile.Path self:
:param base: Defaults to working dir. """
if self.is_relative() and base is None:
return self
else:
if base is None:
base = self.get_working_dir()
return self.Path() if self == base else self.Path(self._path.relative_to(str(base)))
def is_absolute(self):
""" Get whether this Path is absolute.
:param generalfile.Path self: """
return self._path.is_absolute()
def is_relative(self):
""" Get whether this Path is relative.
:param generalfile.Path self: """
return not self.is_absolute()
def startswith(self, path):
""" Get whether this Path starts with given string.
:param generalfile.Path self:
:param str or Path path:"""
path = self.Path(path)
return str(self).startswith(str(path))
def endswith(self, path):
""" Get whether this Path ends with given string.
:param generalfile.Path self:
:param str or Path path:"""
path = self.Path(path)
return str(self).endswith(str(path))
def remove_start(self, path):
""" Remove a string from the start of this Path.
:param generalfile.Path self:
:param str or Path path:"""
path = self.Path(path)
str_path = str(path)
if not self.startswith(str_path):
return self
else:
new_path = self.Path(str(self)[len(str_path):])
if str(new_path).startswith(path.path_delimiter):
return new_path[1:]
else:
return new_path
def remove_end(self, path):
""" Remove a string from the end of this Path.
:param generalfile.Path self:
:param str or Path path:"""
path = self.Path(path)
str_path = str(path)
if not self.endswith(str_path):
return self
else:
new_path = self.Path(str(self)[:-len(str_path)])
if str(new_path).endswith(path.path_delimiter):
return new_path[:-1]
else:
return new_path
def same_destination(self, path):
""" See if two paths point to the same destination.
:param generalfile.Path self:
:param str or Path path:"""
path = self.Path(path)
return self.absolute() == path.absolute()
def parts(self):
""" Split path using it's delimiter.
With an absolute path the first index is an empty string on a posix system. <- Note sure about that anymore, might be /
:param generalfile.Path self: """
return str(self).split(self.path_delimiter)
def name(self):
""" Get name of Path which is stem + suffix.
:param generalfile.Path self: """
return self._path.name
def with_name(self, name):
""" Get a new Path with new name which is stem + suffix.
:param name: Name.
:param generalfile.Path self:
:rtype: generalfile.Path """
return self.Path(self._path.with_name(str(name)))
def stem(self):
""" Get stem which is name without last suffix.
:param generalfile.Path self: """
return self._path.stem
def with_stem(self, stem):
""" Get a new Path with new stem which is name without last suffix.
:param stem: New stem.
:param generalfile.Path self:
:rtype: generalfile.Path """
return self.Path(self.with_name(f"{stem}{self.suffix()}"))
def true_stem(self):
""" Get true stem which is name without any suffixes.
:param generalfile.Path self: """
return self._path.stem.split(".")[0]
def with_true_stem(self, true_stem):
""" Get a new Path with new stem which is name without any suffixes.
:param true_stem: New true stem.
:param generalfile.Path self:
:rtype: generalfile.Path """
return self.Path(self.with_name(f"{true_stem}{''.join(self.suffixes())}"))
def suffix(self):
""" Get suffix which is name without stem.
:param generalfile.Path self: """
return self._path.suffix
def with_suffix(self, suffix, index=-1):
""" Get a new Path with a new suffix at any index.
Index is automatically clamped if it's outside index range.
Set suffix to `None` to remove a suffix.
:param generalfile.Path self:
:param suffix: New suffix, can be `None`.
:param index: Suffix index to alter.
:rtype: generalfile.Path """
suffixes = self.suffixes()
try:
suffixes[index]
except IndexError:
if index >= len(suffixes):
if suffix is None:
del suffixes[-1]
else:
suffixes.append(suffix)
else:
if suffix is None:
del suffixes[0]
else:
suffixes.insert(0, suffix)
else:
if suffix is None:
del suffixes[index]
else:
suffixes[index] = suffix
return self.with_name(f"{self.true_stem()}{''.join(suffixes)}")
def suffixes(self):
""" Get every suffix as a list.
:param generalfile.Path self: """
return self._path.suffixes
def with_suffixes(self, suffixes):
""" Get a new Path with a new list of suffixes.
:param list or tuple suffixes: New list of suffixes.
:param generalfile.Path self:
:rtype: generalfile.Path """
return self.Path(self.with_name(f"{self.true_stem()}{''.join(suffixes)}"))
def match(self, *lines):
""" Get whether any parts of this Path matches any given filter line.
:param generalfile.Path self: """
for part in self.parts():
for line in lines:
line = re.escape(line)
line = line.replace(r"\*", ".+")
pattern = f"^{line}$"
if re.match(pattern, part, re.IGNORECASE):
return True
return False
def encode(self):
""" Return a URL encoded string from this Path. """
url = str(self).replace("\\", "/")
return quote(url)