Files
seiscomp-training/etc/init/rs2caps.py

203 lines
6.1 KiB
Python

from __future__ import absolute_import, division, print_function
import os
import sys
import re
import glob
import fnmatch
import seiscomp.kernel
import seiscomp.config
class Module(seiscomp.kernel.Module):
def __init__(self, env):
seiscomp.kernel.Module.__init__(self, env, env.moduleName(__file__))
self.net = None
self.sta = None
self.journalFile = None
def _readConfig(self):
cfg = seiscomp.config.Config()
cfg.readConfig(os.path.join(self.env.SEISCOMP_ROOT,
"etc", "defaults", self.name + ".cfg"))
cfg.readConfig(os.path.join(
self.env.SEISCOMP_ROOT, "etc", self.name + ".cfg"))
try:
cfg.readConfig(os.path.join(
os.environ['HOME'], ".seiscomp", self.name + ".cfg"))
except BaseException:
pass
self.journalFile = None
try:
if not cfg.getBool("journal.syncWithBindings"):
sys.stderr.write("! bindings synchronization disabled\n")
return
except BaseException:
sys.stderr.write("! bindings synchronization disabled\n")
return
try:
self.journalFile = cfg.getString("journal.file")
except BaseException:
self.journalFile = os.path.join(
self.env.SEISCOMP_ROOT, "var", "run", self.name + "/journal")
def _processStation(self, key_dir, profile):
if profile:
station_config_file = "profile_%s" % (profile,)
else:
station_config_file = "station_%s_%s" % (self.net, self.sta)
cfg = seiscomp.config.Config()
cfg.readConfig(os.path.join(key_dir, station_config_file))
lines = []
try:
selectors = cfg.getStrings("selectors")
except BaseException:
selectors = ["*.*"]
for s in selectors:
lines.append(self.net + "." + self.sta + "." + s)
return lines
def requiresKernelModules(self):
return False
def supportsAliases(self):
return True
def updateConfig(self):
self._readConfig()
if not self.journalFile:
return 0
rx_binding = re.compile(
r'(?P<module>[A-Za-z0-9_\.-]+)(:(?P<profile>[A-Za-z0-9_-]+))?$')
bindings_dir = os.path.join(self.env.SEISCOMP_ROOT, "etc", "key")
key_dir = os.path.join(bindings_dir, self.name)
journalEntries = []
requestedEntries = []
requestedEntriesSet = set()
requestedEntriesTree = {}
try:
journalFile = open(self.journalFile, "r")
for l in journalFile:
journalEntries.append(l.strip().split())
except BaseException:
pass
#raise Exception("Error: unable to create rs2caps request file '%s'" %
# self.journalFile)
files = glob.glob(os.path.join(bindings_dir, "station_*"))
for f in files:
try:
(path, net, sta) = f.split('_')[-3:]
if not path.endswith("station"):
print("invalid path", f)
except ValueError:
print("invalid path", f)
continue
self.net = net
self.sta = sta
if net not in requestedEntriesTree:
requestedEntriesTree[net] = {}
if sta not in requestedEntriesTree:
requestedEntriesTree[net][sta] = []
fd = open(f)
line = fd.readline()
while line:
line = line.strip()
if not line or line[0] == '#':
line = fd.readline()
continue
m = rx_binding.match(line)
if not m:
print("invalid binding in %s: %s" % (f, line))
line = fd.readline()
continue
if m.group('module') != self.name:
line = fd.readline()
continue
profile = m.group('profile')
lines = self._processStation(key_dir, profile)
if lines:
#for l in lines: journalFile.write("%s\n" % l)
for l in lines:
requestedEntries.append(l)
requestedEntriesSet.add(l)
requestedEntriesTree[net][sta].append(l)
break
fd.close()
# Intersect requests with journal
newJournalEntries = []
newRequests = []
oldJournalChannels = set()
for j in journalEntries:
oldJournalChannels.add(j[0])
if (j[0].find('*') >= 0) or (j[0].find('?') >= 0):
continue
foundMatch = False
if j[0] in requestedEntriesSet:
foundMatch = True
else:
n, s, _, _ = j[0].split('.')
try:
for r in requestedEntriesTree[n][s]:
if fnmatch.fnmatch(j[0], r):
foundMatch = True
break
except BaseException:
pass
if foundMatch:
newJournalEntries.append(j)
else:
sys.stderr.write("- %s\n" % j[0])
for r in requestedEntries:
foundMatch = False
for j in newJournalEntries:
if r == j[0]:
foundMatch = True
break
if not foundMatch:
newRequests.append(r)
if r not in oldJournalChannels:
sys.stderr.write("+ %s\n" % r)
try:
journalFile = open(self.journalFile, "w")
except BaseException:
raise Exception(
"Error: unable to write to rs2caps journal file '%s'" %
self.journalFile)
for r in newRequests:
journalFile.write(r + "\n")
for j in newJournalEntries:
journalFile.write(" ".join(j) + "\n")
return 0