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

# http://pyrocko.org - GPLv3 

# 

# The Pyrocko Developers, 21st Century 

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

 

from __future__ import absolute_import, print_function 

 

from .guts import Object, String 

import os.path as op 

 

guts_prefix = 'pf' 

 

 

def xjoin(basepath, path): 

if path is None and basepath is not None: 

return basepath 

elif op.isabs(path) or basepath is None: 

return path 

else: 

return op.join(basepath, path) 

 

 

def xrelpath(path, start): 

if op.isabs(path): 

return path 

else: 

return op.relpath(path, start) 

 

 

class Path(String): 

pass 

 

 

class HasPaths(Object): 

path_prefix = Path.T(optional=True) 

 

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

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

self._basepath = None 

self._parent_path_prefix = None 

 

def ichildren(self): 

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

if isinstance(val, HasPaths): 

yield val 

 

elif prop.multivalued and val is not None: 

for ele in val: 

if isinstance(ele, HasPaths): 

yield ele 

 

def set_basepath(self, basepath, parent_path_prefix=None): 

self._basepath = basepath 

self._parent_path_prefix = parent_path_prefix 

for val in self.ichildren(): 

val.set_basepath( 

basepath, self.path_prefix or self._parent_path_prefix) 

 

def get_basepath(self): 

assert self._basepath is not None 

 

return self._basepath 

 

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

assert self._basepath is not None 

 

self._parent_path_prefix = parent_path_prefix 

if self.path_prefix or not self._parent_path_prefix: 

 

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

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

 

for val in self.ichildren(): 

val.change_basepath( 

new_basepath, self.path_prefix or self._parent_path_prefix) 

 

self._basepath = new_basepath 

 

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

assert self._basepath is not None 

 

if extra is None: 

def extra(path): 

return path 

 

path_prefix = self.path_prefix or self._parent_path_prefix 

 

if path is None: 

return None 

 

elif isinstance(path, str): 

return extra( 

op.normpath(xjoin(self._basepath, xjoin(path_prefix, path)))) 

else: 

return [ 

extra( 

op.normpath(xjoin(self._basepath, xjoin(path_prefix, p)))) 

for p in path] 

 

def rel_path(self, path): 

return xrelpath(path, self.get_basepath())