1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6from .guts import Object, String 

7import os.path as op 

8 

9guts_prefix = 'pf' 

10 

11 

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) 

19 

20 

21def xrelpath(path, start): 

22 if op.isabs(path): 

23 return path 

24 else: 

25 return op.relpath(path, start) 

26 

27 

28class Path(String): 

29 pass 

30 

31 

32class HasPaths(Object): 

33 path_prefix = Path.T(optional=True) 

34 

35 def __init__(self, *args, **kwargs): 

36 Object.__init__(self, *args, **kwargs) 

37 self._basepath = None 

38 self._parent_path_prefix = None 

39 

40 def ichildren(self): 

41 for (prop, val) in self.T.ipropvals(self): 

42 if isinstance(val, HasPaths): 

43 yield val 

44 

45 elif prop.multivalued and val is not None: 

46 for ele in val: 

47 if isinstance(ele, HasPaths): 

48 yield ele 

49 

50 def effective_path_prefix(self): 

51 return self.path_prefix or self._parent_path_prefix 

52 

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()) 

59 

60 def set_basepath_from(self, other): 

61 self.set_basepath(other.get_basepath(), other.effective_path_prefix()) 

62 

63 def get_basepath(self): 

64 assert self._basepath is not None 

65 

66 return self._basepath 

67 

68 def change_basepath(self, new_basepath, parent_path_prefix=None): 

69 assert self._basepath is not None 

70 

71 self._parent_path_prefix = parent_path_prefix 

72 if self.path_prefix or not self._parent_path_prefix: 

73 

74 self.path_prefix = op.normpath(xjoin(xrelpath( 

75 self._basepath, new_basepath), self.path_prefix)) 

76 

77 for val in self.ichildren(): 

78 val.change_basepath(new_basepath, self.effective_path_prefix()) 

79 

80 self._basepath = new_basepath 

81 

82 def expand_path(self, path, extra=None): 

83 assert self._basepath is not None 

84 

85 if extra is None: 

86 def extra(path): 

87 return path 

88 

89 path_prefix = self.effective_path_prefix() 

90 

91 if path is None: 

92 return None 

93 

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] 

102 

103 def rel_path(self, path): 

104 return xrelpath(path, self.get_basepath())