1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from .guts import Object, String
7import os.path as op
9guts_prefix = 'pf'
12def xjoin(basepath, path):
13 if path is None and basepath is not None:
14 return basepath
15 elif op.isabs(path) or basepath is None:
16 return path
17 else:
18 return op.join(basepath, path)
21def xrelpath(path, start):
22 if op.isabs(path):
23 return path
24 else:
25 return op.relpath(path, start)
28class Path(String):
29 pass
32class HasPaths(Object):
33 path_prefix = Path.T(optional=True)
35 def __init__(self, *args, **kwargs):
36 Object.__init__(self, *args, **kwargs)
37 self._basepath = None
38 self._parent_path_prefix = None
40 def ichildren(self):
41 for (prop, val) in self.T.ipropvals(self):
42 if isinstance(val, HasPaths):
43 yield val
45 elif prop.multivalued and val is not None:
46 for ele in val:
47 if isinstance(ele, HasPaths):
48 yield ele
50 def effective_path_prefix(self):
51 return self.path_prefix or self._parent_path_prefix
53 def set_basepath(self, basepath, parent_path_prefix=None):
54 self._basepath = basepath
55 self._parent_path_prefix = parent_path_prefix
56 for val in self.ichildren():
57 val.set_basepath(
58 basepath, self.effective_path_prefix())
60 def set_basepath_from(self, other):
61 self.set_basepath(other.get_basepath(), other.effective_path_prefix())
63 def get_basepath(self):
64 assert self._basepath is not None
66 return self._basepath
68 def change_basepath(self, new_basepath, parent_path_prefix=None):
69 assert self._basepath is not None
71 self._parent_path_prefix = parent_path_prefix
72 if self.path_prefix or not self._parent_path_prefix:
74 self.path_prefix = op.normpath(xjoin(xrelpath(
75 self._basepath, new_basepath), self.path_prefix))
77 for val in self.ichildren():
78 val.change_basepath(new_basepath, self.effective_path_prefix())
80 self._basepath = new_basepath
82 def expand_path(self, path, extra=None):
83 assert self._basepath is not None
85 if extra is None:
86 def extra(path):
87 return path
89 path_prefix = self.effective_path_prefix()
91 if path is None:
92 return None
94 elif isinstance(path, str):
95 return extra(
96 op.normpath(xjoin(self._basepath, xjoin(path_prefix, path))))
97 else:
98 return [
99 extra(
100 op.normpath(xjoin(self._basepath, xjoin(path_prefix, p))))
101 for p in path]
103 def rel_path(self, path):
104 return xrelpath(path, self.get_basepath())