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
14from .. import common
16logger = logging.getLogger('psq.cli.template')
18path_prefix = '''
19# All file paths given below are treated relative to the location of this
20# configuration file. Here we may give a common prefix. For example, if the
21# configuration file is in the sub-directory 'PROJECT/config/', set it to '..'
22# so that all paths are relative to 'PROJECT/'.
23path_prefix: '.'
24'''.strip()
27def _template_online_dataset(**kwargs):
28 lqargs = []
29 for k in ['network', 'station', 'channel']:
30 if k in kwargs:
31 v = kwargs.pop(k)
32 lqargs.append(" %s: '%s'" % (k, v))
34 kwargs['qargs'] = '\n' + '\n'.join(lqargs) if lqargs else '{}'
35 return '''
36--- !squirrel.Dataset
38{path_prefix}
40# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...)
41sources:
42- !squirrel.FDSNSource
44 # URL or alias of FDSN site.
45 site: {site}
47 # FDSN query arguments to make metadata queries.
48 # See http://www.fdsn.org/webservices/fdsnws-station-1.1.pdf
49 # Time span arguments should not be added here, because they are handled
50 # automatically by Squirrel.
51 query_args: {qargs}
52'''.format(path_prefix=path_prefix, **kwargs).strip()
55templates = {
56 'local.dataset.yaml': {
57 'description':
58 'A typical collection of local files.',
59 'yaml': '''
60--- !squirrel.Dataset
62{path_prefix}
64# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...)
65sources:
66- !squirrel.LocalData # This data source is for local files.
68 # These paths are scanned for waveforms, stations, events.
69 paths:
70 - 'catalogs/events.txt'
71 - 'meta/stations.xml'
72 - 'data/waveforms'
74 # Select file format or 'detect' for autodetection.
75 format: 'detect'
76'''.format(path_prefix=path_prefix).strip()},
78 'geofon.dataset.yaml': {
79 'description':
80 'Everything available through GEOFON.',
81 'yaml': _template_online_dataset(
82 site='geofon',
83 ),
84 },
86 'iris-seis.dataset.yaml': {
87 'description':
88 'All high- and low-gain seismometer channels at IRIS.',
89 'yaml': _template_online_dataset(
90 site='iris',
91 channel='?H?,?L?',
92 ),
93 },
95 'iris-seis-bb.dataset.yaml': {
96 'description':
97 'All broad-band high-gain seismometer channels at IRIS.',
98 'yaml': _template_online_dataset(
99 site='iris',
100 channel='VH?,LH?,BH?,HH?',
101 ),
102 },
104 'bgr-gr-bfo.dataset.yaml': {
105 'description': 'Station GR.BFO from BGR.',
106 'yaml': _template_online_dataset(
107 site='bgr',
108 network='GR',
109 station='BFO',
110 ),
111 },
112}
114names = sorted(templates.keys())
116template_listing = '\n'.join(
117 '%-30s %s' % (
118 '%s:' % name,
119 templates[name]['description']) for name in templates)
122def setup_subcommand(subparsers):
123 return common.add_parser(
124 subparsers, 'template',
125 help='Print configuration snippets.',
126 description='''
127Available configuration SNIPPETs:
129{}
130'''.format(template_listing).strip())
133def setup(parser):
134 parser.add_argument(
135 'name',
136 choices=names,
137 nargs='?',
138 metavar='SNIPPET',
139 help='Name of template snippet to print.')
141 parser.add_argument(
142 '--format', '-f',
143 choices=['commented', 'normal', 'brief'],
144 default='commented',
145 metavar='FMT',
146 help='Set verbosity level of output YAML. Choices: %(choices)s. '
147 'Default: %(default)s.')
149 parser.add_argument(
150 '--write', '-w',
151 action='store_true',
152 help='Write to file.')
155def decomment(s):
156 out = []
157 for line in s.splitlines():
158 line = re.sub(r'#.+', '', line)
159 if line.strip():
160 out.append(line)
162 return '\n'.join(out)
165def brief(s):
166 return dump(load_string(s))
169def call(parser, args):
171 if not args.name:
172 print(template_listing)
174 else:
175 func = {
176 'brief': brief,
177 'commented': lambda s: s,
178 'normal': decomment}[args.format]
180 s = func(templates[args.name]['yaml'])
182 if args.write:
183 try:
184 with open(args.name, 'x') as f:
185 f.write(s)
186 f.write('\n')
188 logger.info('File written: %s' % args.name)
190 except FileExistsError:
191 raise ToolError('File exists: %s' % args.name)
192 else:
193 print(s)