203 lines
6.1 KiB
Python
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
|