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 

8import re 

9import logging 

10 

11from pyrocko.guts import load_string, dump 

12 

13from pyrocko.squirrel.error import ToolError 

14 

15logger = logging.getLogger('psq.cli.template') 

16 

17path_prefix = ''' 

18# All file paths given below are treated relative to the location of this 

19# configuration file. Here we may give a common prefix. For example, if the 

20# configuration file is in the sub-directory 'PROJECT/config/', set it to '..' 

21# so that all paths are relative to 'PROJECT/'. 

22path_prefix: '.' 

23'''.strip() 

24 

25 

26def _template_online_dataset(**kwargs): 

27 lqargs = [] 

28 for k in ['network', 'station', 'channel']: 

29 if k in kwargs: 

30 v = kwargs.pop(k) 

31 lqargs.append(" %s: '%s'" % (k, v)) 

32 

33 kwargs['qargs'] = '\n' + '\n'.join(lqargs) if lqargs else '{}' 

34 return ''' 

35--- !squirrel.Dataset 

36 

37{path_prefix} 

38 

39# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...) 

40sources: 

41- !squirrel.FDSNSource 

42 

43 # URL or alias of FDSN site. 

44 site: {site} 

45 

46 # FDSN query arguments to make metadata queries. 

47 # See http://www.fdsn.org/webservices/fdsnws-station-1.1.pdf 

48 # Time span arguments should not be added here, because they are handled 

49 # automatically by Squirrel. 

50 query_args: {qargs} 

51'''.format(path_prefix=path_prefix, **kwargs).strip() 

52 

53 

54templates = { 

55 'local.dataset': { 

56 'description': 

57 'A typical collection of local files.', 

58 'yaml': ''' 

59--- !squirrel.Dataset 

60 

61{path_prefix} 

62 

63# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...) 

64sources: 

65- !squirrel.LocalData # This data source is for local files. 

66 

67 # These paths are scanned for waveforms, stations, events. 

68 paths: 

69 - 'catalogs/events.txt' 

70 - 'meta/stations.xml' 

71 - 'data/waveforms' 

72 

73 # Select file format or 'detect' for autodetection. 

74 format: 'detect' 

75'''.format(path_prefix=path_prefix).strip()}, 

76 

77 'geofon.dataset': { 

78 'description': 

79 'Everything available through GEOFON.', 

80 'yaml': _template_online_dataset( 

81 site='geofon', 

82 ), 

83 }, 

84 

85 'iris-seis.dataset': { 

86 'description': 

87 'All high- and low-gain seismometer channels at IRIS.', 

88 'yaml': _template_online_dataset( 

89 site='iris', 

90 channel='?H?,?L?', 

91 ), 

92 }, 

93 

94 'iris-seis-bb.dataset': { 

95 'description': 

96 'All broad-band high-gain seismometer channels at IRIS.', 

97 'yaml': _template_online_dataset( 

98 site='iris', 

99 channel='VH?,LH?,BH?,HH?', 

100 ), 

101 }, 

102 

103 'bgr-gr-lh.dataset': { 

104 'description': 'All LH channels for network GR from BGR.', 

105 'yaml': _template_online_dataset( 

106 site='bgr', 

107 network='GR', 

108 channel='LH?', 

109 ), 

110 }, 

111} 

112 

113names = sorted(templates.keys()) 

114 

115template_listing = '\n'.join( 

116 '%-30s %s' % ( 

117 '%s:' % name, 

118 templates[name]['description']) for name in templates) 

119 

120 

121def make_subparser(subparsers): 

122 return subparsers.add_parser( 

123 'template', 

124 help='Print configuration snippets.', 

125 description=''' 

126Available configuration SNIPPETs: 

127 

128{} 

129'''.format(template_listing).strip()) 

130 

131 

132def setup(parser): 

133 parser.add_argument( 

134 'name', 

135 choices=names, 

136 nargs='?', 

137 metavar='SNIPPET', 

138 help='Name of template snippet to print.') 

139 

140 parser.add_argument( 

141 '--format', '-f', 

142 choices=['commented', 'normal', 'brief'], 

143 default='commented', 

144 metavar='FMT', 

145 help='Set verbosity level of output YAML. Choices: %(choices)s. ' 

146 'Default: %(default)s.') 

147 

148 parser.add_argument( 

149 '--write', '-w', 

150 action='store_true', 

151 help='Write to file.') 

152 

153 

154def decomment(s): 

155 out = [] 

156 for line in s.splitlines(): 

157 line = re.sub(r'#.+', '', line) 

158 if line.strip(): 

159 out.append(line) 

160 

161 return '\n'.join(out) 

162 

163 

164def brief(s): 

165 return dump(load_string(s)) 

166 

167 

168def run(parser, args): 

169 

170 if not args.name: 

171 print(template_listing) 

172 

173 else: 

174 func = { 

175 'brief': brief, 

176 'commented': lambda s: s, 

177 'normal': decomment}[args.format] 

178 

179 s = func(templates[args.name]['yaml']) 

180 

181 if args.write: 

182 path = args.name + '.yaml' 

183 try: 

184 with open(path, 'x') as f: 

185 f.write(s) 

186 f.write('\n') 

187 

188 logger.info('File written: %s' % path) 

189 

190 except FileExistsError: 

191 raise ToolError('File exists: %s' % path) 

192 else: 

193 print(s)