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[A-Za-z0-9_\.-]+)(:(?P[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