You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
5.1 KiB
Python
157 lines
5.1 KiB
Python
1 year ago
|
import os
|
||
|
import glob
|
||
|
import sys
|
||
|
|
||
|
|
||
|
class CAPSProfile:
|
||
|
def __init__(self):
|
||
|
self.streams = [] # List of strings, e.g. XY.ABCD.*.*
|
||
|
self.stations = [] # List of network, station tuples, e.g. (XY,ABCD)
|
||
|
self.oldStates = [] # Content of old state file
|
||
|
|
||
|
|
||
|
'''
|
||
|
Plugin handler for the CAPS plugin.
|
||
|
'''
|
||
|
|
||
|
|
||
|
class SeedlinkPluginHandler:
|
||
|
# Create defaults
|
||
|
def __init__(self):
|
||
|
self.profiles = {}
|
||
|
|
||
|
def push(self, seedlink):
|
||
|
try:
|
||
|
maxTimeDiff = float(seedlink._get('plugins.caps.maxTimeDiff', False))
|
||
|
except:
|
||
|
maxTimeDiff = 86400
|
||
|
|
||
|
inOrder = ""
|
||
|
try:
|
||
|
if seedlink._get('plugins.caps.inOrder', False):
|
||
|
inOrder = " --in-order"
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
# Check and set defaults
|
||
|
try:
|
||
|
address = seedlink.param('sources.caps.address')
|
||
|
except KeyError:
|
||
|
address = "localhost:18002"
|
||
|
|
||
|
try:
|
||
|
streams = [chaId.strip() for chaId in seedlink.param(
|
||
|
'sources.caps.streams').split(',')]
|
||
|
except KeyError:
|
||
|
seedlink.setParam('sources.caps.streams', "*.*")
|
||
|
streams = ["*.*"]
|
||
|
|
||
|
try:
|
||
|
seedlink.param('sources.caps.encoding')
|
||
|
except KeyError:
|
||
|
seedlink.setParam('sources.caps.encoding', "STEIM2")
|
||
|
|
||
|
try:
|
||
|
seedlink.param('sources.caps.proc')
|
||
|
except KeyError:
|
||
|
seedlink.setParam('sources.caps.proc', "")
|
||
|
|
||
|
# parse address URL and create capsId of form:
|
||
|
# host[.port][_user]
|
||
|
addressFormatError = "Error: invalid address format, expected " \
|
||
|
"[[caps|capss]://][user:pass@]host[:port]"
|
||
|
|
||
|
# protocol
|
||
|
toks = address.split("://")
|
||
|
if len(toks) > 2:
|
||
|
raise Exception(addressFormatError)
|
||
|
elif len(toks) == 2:
|
||
|
protocol = toks[0]
|
||
|
address = toks[1]
|
||
|
if protocol != "caps" and protocol != "capss":
|
||
|
raise Exception(addressFormatError)
|
||
|
else:
|
||
|
protocol = "caps"
|
||
|
|
||
|
# authentication
|
||
|
toks = address.split("@")
|
||
|
if len(toks) > 2:
|
||
|
raise Exception(addressFormatError)
|
||
|
elif len(toks) == 2:
|
||
|
capsId = "%s_%s" % (toks[1].replace(
|
||
|
":", "."), toks[0].split(":")[0])
|
||
|
else:
|
||
|
capsId = address.replace(":", ".")
|
||
|
|
||
|
address = "%s://%s" % (protocol, address)
|
||
|
|
||
|
if capsId not in self.profiles:
|
||
|
profile = CAPSProfile()
|
||
|
self.profiles[capsId] = profile
|
||
|
else:
|
||
|
profile = self.profiles[capsId]
|
||
|
|
||
|
for chaId in streams:
|
||
|
toks = chaId.split('.')
|
||
|
if len(toks) != 2:
|
||
|
raise Exception(
|
||
|
"Error: invalid stream format, expected [LOC.CHA]")
|
||
|
|
||
|
streamID = seedlink.net + "." + seedlink.sta + "." + chaId
|
||
|
profile.streams.append(streamID)
|
||
|
profile.stations.append((seedlink.net, seedlink.sta))
|
||
|
|
||
|
log = os.path.join(seedlink.config_dir, "caps2sl.%s.state" % capsId)
|
||
|
streamsFile = os.path.join(
|
||
|
seedlink.config_dir, "caps2sl.%s.req" % capsId)
|
||
|
seedlink.setParam('sources.caps.address', address)
|
||
|
seedlink.setParam('sources.caps.log', log)
|
||
|
seedlink.setParam('sources.caps.streamsFile', streamsFile)
|
||
|
seedlink.setParam('sources.caps.maxTimeDiff', maxTimeDiff)
|
||
|
seedlink.setParam('sources.caps.inOrder', inOrder)
|
||
|
seedlink.setParam('seedlink.caps.id', capsId)
|
||
|
|
||
|
return capsId
|
||
|
|
||
|
def flush(self, seedlink):
|
||
|
# Populate request file per address
|
||
|
for id, profile in self.profiles.items():
|
||
|
caps2slreq = os.path.join(
|
||
|
seedlink.config_dir, "caps2sl.%s.req" % id)
|
||
|
fd = open(caps2slreq, "w")
|
||
|
for streamId in profile.streams:
|
||
|
fd.write("%s\n" % streamId)
|
||
|
fd.close()
|
||
|
|
||
|
try:
|
||
|
caps2slstate = os.path.join(seedlink.config_dir, "caps2sl.%s.state" % id)
|
||
|
# Read existing state file
|
||
|
fd = open(caps2slstate, "r")
|
||
|
profile.oldStates = [line.strip() for line in fd.readlines()]
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
# Delete all existing state files
|
||
|
for fl in glob.glob(os.path.join(seedlink.config_dir, "caps2sl.*.state")):
|
||
|
try:
|
||
|
os.remove(fl)
|
||
|
except:
|
||
|
sys.stderr.write("Failed to remove old state file: %s\n" % str(fl))
|
||
|
|
||
|
# Clean up state file to contain only configured stations
|
||
|
for id, profile in self.profiles.items():
|
||
|
caps2slstate = os.path.join(seedlink.config_dir, "caps2sl.%s.state" % id)
|
||
|
|
||
|
newStates = []
|
||
|
|
||
|
for (net, sta) in profile.stations:
|
||
|
for line in profile.oldStates:
|
||
|
if line.startswith(net + "." + sta + "."):
|
||
|
newStates.append(line)
|
||
|
|
||
|
if len(newStates) > 0:
|
||
|
fd = open(caps2slstate, "w")
|
||
|
for line in newStates:
|
||
|
fd.write(line + "\n")
|
||
|
fd.close()
|