1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6from __future__ import absolute_import, print_function 

7 

8from .guts import Object, String 

9import os.path as op 

10 

11guts_prefix = 'pf' 

12 

13 

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) 

21 

22 

23def xrelpath(path, start): 

24 if op.isabs(path): 

25 return path 

26 else: 

27 return op.relpath(path, start) 

28 

29 

30class Path(String): 

31 pass 

32 

33 

34class HasPaths(Object): 

35 path_prefix = Path.T(optional=True) 

36 

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

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

39 self._basepath = None 

40 self._parent_path_prefix = None 

41 

42 def ichildren(self): 

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

44 if isinstance(val, HasPaths): 

45 yield val 

46 

47 elif prop.multivalued and val is not None: 

48 for ele in val: 

49 if isinstance(ele, HasPaths): 

50 yield ele 

51 

52 def effective_path_prefix(self): 

53 return self.path_prefix or self._parent_path_prefix 

54 

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

61 

62 def set_basepath_from(self, other): 

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

64 

65 def get_basepath(self): 

66 assert self._basepath is not None 

67 

68 return self._basepath 

69 

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

71 assert self._basepath is not None 

72 

73 self._parent_path_prefix = parent_path_prefix 

74 if self.path_prefix or not self._parent_path_prefix: 

75 

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

77 self._basepath, new_basepath), self.path_prefix)) 

78 

79 for val in self.ichildren(): 

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

81 

82 self._basepath = new_basepath 

83 

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

85 assert self._basepath is not None 

86 

87 if extra is None: 

88 def extra(path): 

89 return path 

90 

91 path_prefix = self.effective_path_prefix() 

92 

93 if path is None: 

94 return None 

95 

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] 

104 

105 def rel_path(self, path): 

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