1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from __future__ import absolute_import, print_function
8import re
9import logging
11from pyrocko.guts import load_string, dump
13from pyrocko.squirrel.error import ToolError
15logger = logging.getLogger('psq.cli.template')
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()
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))
33 kwargs['qargs'] = '\n' + '\n'.join(lqargs) if lqargs else '{}'
34 return '''
35--- !squirrel.Dataset
37{path_prefix}
39# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...)
40sources:
41- !squirrel.FDSNSource
43 # URL or alias of FDSN site.
44 site: {site}
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()
54templates = {
55 'local.dataset': {
56 'description':
57 'A typical collection of local files.',
58 'yaml': '''
59--- !squirrel.Dataset
61{path_prefix}
63# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...)
64sources:
65- !squirrel.LocalData # This data source is for local files.
67 # These paths are scanned for waveforms, stations, events.
68 paths:
69 - 'catalogs/events.txt'
70 - 'meta/stations.xml'
71 - 'data/waveforms'
73 # Select file format or 'detect' for autodetection.
74 format: 'detect'
75'''.format(path_prefix=path_prefix).strip()},
77 'geofon.dataset': {
78 'description':
79 'Everything available through GEOFON.',
80 'yaml': _template_online_dataset(
81 site='geofon',
82 ),
83 },
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 },
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 },
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}
113names = sorted(templates.keys())
115template_listing = '\n'.join(
116 '%-30s %s' % (
117 '%s:' % name,
118 templates[name]['description']) for name in templates)
121def make_subparser(subparsers):
122 return subparsers.add_parser(
123 'template',
124 help='Print configuration snippets.',
125 description='''
126Available configuration SNIPPETs:
128{}
129'''.format(template_listing).strip())
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.')
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.')
148 parser.add_argument(
149 '--write', '-w',
150 action='store_true',
151 help='Write to file.')
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)
161 return '\n'.join(out)
164def brief(s):
165 return dump(load_string(s))
168def run(parser, args):
170 if not args.name:
171 print(template_listing)
173 else:
174 func = {
175 'brief': brief,
176 'commented': lambda s: s,
177 'normal': decomment}[args.format]
179 s = func(templates[args.name]['yaml'])
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')
188 logger.info('File written: %s' % path)
190 except FileExistsError:
191 raise ToolError('File exists: %s' % path)
192 else:
193 print(s)