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 

17headline = 'Print configuration snippets.' 

18 

19path_prefix = ''' 

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

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

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

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

24path_prefix: '.' 

25'''.strip() 

26 

27 

28def _template_online_dataset(**kwargs): 

29 lqargs = [] 

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

31 if k in kwargs: 

32 v = kwargs.pop(k) 

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

34 

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

36 return ''' 

37--- !squirrel.Dataset 

38 

39{path_prefix} 

40 

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

42sources: 

43- !squirrel.FDSNSource 

44 

45 # URL or alias of FDSN site. 

46 site: {site} 

47 

48 # FDSN query arguments to make metadata queries. 

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

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

51 # automatically by Squirrel. 

52 query_args: {qargs} 

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

54 

55 

56templates = { 

57 'local.dataset': { 

58 'description': 

59 'A typical collection of local files.', 

60 'yaml': ''' 

61--- !squirrel.Dataset 

62 

63{path_prefix} 

64 

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

66sources: 

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

68 

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

70 paths: 

71 - 'catalogs/events.txt' 

72 - 'meta/stations.xml' 

73 - 'data/waveforms' 

74 

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

76 format: 'detect' 

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

78 

79 'geofon.dataset': { 

80 'description': 

81 'Everything available through GEOFON.', 

82 'yaml': _template_online_dataset( 

83 site='geofon', 

84 ), 

85 }, 

86 

87 'iris-seis.dataset': { 

88 'description': 

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

90 'yaml': _template_online_dataset( 

91 site='iris', 

92 channel='?H?,?L?', 

93 ), 

94 }, 

95 

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

97 'description': 

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

99 'yaml': _template_online_dataset( 

100 site='iris', 

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

102 ), 

103 }, 

104 

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

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

107 'yaml': _template_online_dataset( 

108 site='bgr', 

109 network='GR', 

110 channel='LH?', 

111 ), 

112 }, 

113} 

114 

115names = sorted(templates.keys()) 

116 

117template_listing = '\n'.join( 

118 '%-30s %s' % ( 

119 '%s:' % name, 

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

121 

122 

123def make_subparser(subparsers): 

124 return subparsers.add_parser( 

125 'template', 

126 help=headline, 

127 description=headline + ''' 

128 

129Available configuration SNIPPETs: 

130 

131{} 

132'''.format(template_listing).strip()) 

133 

134 

135def setup(parser): 

136 parser.add_argument( 

137 'name', 

138 choices=names, 

139 nargs='?', 

140 metavar='SNIPPET', 

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

142 

143 parser.add_argument( 

144 '--format', '-f', 

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

146 default='commented', 

147 metavar='FMT', 

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

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

150 

151 parser.add_argument( 

152 '--write', '-w', 

153 action='store_true', 

154 help='Write to file.') 

155 

156 

157def decomment(s): 

158 out = [] 

159 for line in s.splitlines(): 

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

161 if line.strip(): 

162 out.append(line) 

163 

164 return '\n'.join(out) 

165 

166 

167def brief(s): 

168 return dump(load_string(s)) 

169 

170 

171def run(parser, args): 

172 

173 if not args.name: 

174 print(template_listing) 

175 

176 else: 

177 func = { 

178 'brief': brief, 

179 'commented': lambda s: s, 

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

181 

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

183 

184 if args.write: 

185 path = args.name + '.yaml' 

186 try: 

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

188 f.write(s) 

189 f.write('\n') 

190 

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

192 

193 except FileExistsError: 

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

195 else: 

196 print(s)