1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from __future__ import absolute_import, print_function
8from .guts import Object, String
9import os.path as op
11guts_prefix = 'pf'
14def xjoin(basepath, path):
15 if path is None and basepath is not None:
16 return basepath
17 elif op.isabs(path) or basepath is None:
18 return path
19 else:
20 return op.join(basepath, path)
23def xrelpath(path, start):
24 if op.isabs(path):
25 return path
26 else:
27 return op.relpath(path, start)
30class Path(String):
31 pass
34class HasPaths(Object):
35 path_prefix = Path.T(optional=True)
37 def __init__(self, *args, **kwargs):
38 Object.__init__(self, *args, **kwargs)
39 self._basepath = None
40 self._parent_path_prefix = None
42 def ichildren(self):
43 for (prop, val) in self.T.ipropvals(self):
44 if isinstance(val, HasPaths):
45 yield val
47 elif prop.multivalued and val is not None:
48 for ele in val:
49 if isinstance(ele, HasPaths):
50 yield ele
52 def effective_path_prefix(self):
53 return self.path_prefix or self._parent_path_prefix
55 def set_basepath(self, basepath, parent_path_prefix=None):
56 self._basepath = basepath
57 self._parent_path_prefix = parent_path_prefix
58 for val in self.ichildren():
59 val.set_basepath(
60 basepath, self.effective_path_prefix())
62 def set_basepath_from(self, other):
63 self.set_basepath(other.get_basepath(), other.effective_path_prefix())
65 def get_basepath(self):
66 assert self._basepath is not None
68 return self._basepath
70 def change_basepath(self, new_basepath, parent_path_prefix=None):
71 assert self._basepath is not None
73 self._parent_path_prefix = parent_path_prefix
74 if self.path_prefix or not self._parent_path_prefix:
76 self.path_prefix = op.normpath(xjoin(xrelpath(
77 self._basepath, new_basepath), self.path_prefix))
79 for val in self.ichildren():
80 val.change_basepath(new_basepath, self.effective_path_prefix())
82 self._basepath = new_basepath
84 def expand_path(self, path, extra=None):
85 assert self._basepath is not None
87 if extra is None:
88 def extra(path):
89 return path
91 path_prefix = self.effective_path_prefix()
93 if path is None:
94 return None
96 elif isinstance(path, str):
97 return extra(
98 op.normpath(xjoin(self._basepath, xjoin(path_prefix, path))))
99 else:
100 return [
101 extra(
102 op.normpath(xjoin(self._basepath, xjoin(path_prefix, p))))
103 for p in path]
105 def rel_path(self, path):
106 return xrelpath(path, self.get_basepath())