232 lines
7.2 KiB
Plaintext
Executable File
232 lines
7.2 KiB
Plaintext
Executable File
#!/usr/bin/env seiscomp-python
|
|
# -*- coding: utf-8 -*-
|
|
############################################################################
|
|
# Copyright (C) GFZ Potsdam #
|
|
# All rights reserved. #
|
|
# #
|
|
# GNU Affero General Public License Usage #
|
|
# This file may be used under the terms of the GNU Affero #
|
|
# Public License version 3.0 as published by the Free Software Foundation #
|
|
# and appearing in the file LICENSE included in the packaging of this #
|
|
# file. Please review the following information to ensure the GNU Affero #
|
|
# Public License version 3.0 requirements will be met: #
|
|
# https://www.gnu.org/licenses/agpl-3.0.html. #
|
|
############################################################################
|
|
|
|
import os
|
|
import sys
|
|
|
|
import seiscomp.core
|
|
import seiscomp.client
|
|
import seiscomp.datamodel
|
|
|
|
|
|
def readXML(self):
|
|
ar = seiscomp.io.XMLArchive()
|
|
if not ar.open(self._inputFile):
|
|
print(f"Unable to open input file {self._inputFile}")
|
|
return []
|
|
|
|
obj = ar.readObject()
|
|
if obj is None:
|
|
raise TypeError("invalid input file format")
|
|
|
|
ep = seiscomp.datamodel.EventParameters.Cast(obj)
|
|
if ep is None:
|
|
raise ValueError("no event parameters found in input file")
|
|
|
|
originIDs = []
|
|
for i in range(ep.originCount()):
|
|
org = ep.origin(i)
|
|
|
|
# check time requirements
|
|
orgTime = org.time().value()
|
|
if orgTime < self._startTime:
|
|
continue
|
|
if orgTime > self._endTime:
|
|
continue
|
|
|
|
# check author requirements
|
|
if self.author:
|
|
try:
|
|
author = org.creationInfo().author()
|
|
except Exception:
|
|
continue
|
|
|
|
if author != self.author:
|
|
continue
|
|
|
|
try:
|
|
originIDs.append(org.publicID())
|
|
except Exception:
|
|
continue
|
|
|
|
return originIDs
|
|
|
|
|
|
class OriginList(seiscomp.client.Application):
|
|
def __init__(self, argc, argv):
|
|
seiscomp.client.Application.__init__(self, argc, argv)
|
|
|
|
self.setMessagingEnabled(False)
|
|
self.setDatabaseEnabled(True, False)
|
|
self.setDaemonEnabled(False)
|
|
|
|
self._startTime = seiscomp.core.Time()
|
|
self._endTime = seiscomp.core.Time.GMT()
|
|
self._delimiter = None
|
|
self._inputFile = None
|
|
|
|
def createCommandLineDescription(self):
|
|
self.commandline().addGroup("Input")
|
|
self.commandline().addStringOption(
|
|
"Input",
|
|
"input,i",
|
|
"Name of input XML file. Read from stdin if '-' is given. Deactivates "
|
|
"reading events from database",
|
|
)
|
|
self.commandline().addGroup("Origins")
|
|
self.commandline().addStringOption(
|
|
"Origins",
|
|
"begin",
|
|
"The lower bound of the time interval. Format: '1970-01-01 00:00:00'.",
|
|
)
|
|
self.commandline().addStringOption(
|
|
"Origins",
|
|
"end",
|
|
"The upper bound of the time interval. Format: '1970-01-01 00:00:00'.",
|
|
)
|
|
self.commandline().addStringOption(
|
|
"Origins", "author", "The author of the origins."
|
|
)
|
|
|
|
self.commandline().addGroup("Output")
|
|
self.commandline().addStringOption(
|
|
"Output",
|
|
"delimiter,D",
|
|
"The delimiter of the resulting origin IDs. Default: '\\n')",
|
|
)
|
|
return True
|
|
|
|
def validateParameters(self):
|
|
if not seiscomp.client.Application.validateParameters(self):
|
|
return False
|
|
|
|
try:
|
|
self._inputFile = self.commandline().optionString("input")
|
|
except RuntimeError:
|
|
pass
|
|
|
|
if self._inputFile:
|
|
self.setDatabaseEnabled(False, False)
|
|
|
|
return True
|
|
|
|
def init(self):
|
|
if not seiscomp.client.Application.init(self):
|
|
return False
|
|
|
|
try:
|
|
start = self.commandline().optionString("begin")
|
|
except RuntimeError:
|
|
start = "1900-01-01T00:00:00Z"
|
|
|
|
self._startTime = seiscomp.core.Time.FromString(start)
|
|
if self._startTime is None:
|
|
seiscomp.logging.error(f"Wrong 'begin' format '{start}'")
|
|
return False
|
|
|
|
try:
|
|
end = self.commandline().optionString("end")
|
|
except RuntimeError:
|
|
end = "2500-01-01T00:00:00Z"
|
|
|
|
self._endTime = seiscomp.core.Time.FromString(end)
|
|
if self._endTime is None:
|
|
seiscomp.logging.error(f"Wrong 'end' format '{end}'")
|
|
return False
|
|
|
|
if self._endTime <= self._startTime:
|
|
seiscomp.logging.error(
|
|
f"Invalid search interval: {self._startTime} - {self._endTime}"
|
|
)
|
|
return False
|
|
|
|
try:
|
|
self.author = self.commandline().optionString("author")
|
|
seiscomp.logging.debug(f"Filtering origins by author {self.author}")
|
|
except RuntimeError:
|
|
self.author = False
|
|
|
|
try:
|
|
self._delimiter = self.commandline().optionString("delimiter")
|
|
except RuntimeError:
|
|
self._delimiter = "\n"
|
|
|
|
return True
|
|
|
|
def printUsage(self):
|
|
print(
|
|
f"""Usage:
|
|
{os.path.basename(__file__)} [options]
|
|
|
|
List origin IDs available in a given time range and print to stdout."""
|
|
)
|
|
|
|
seiscomp.client.Application.printUsage(self)
|
|
|
|
print(
|
|
f"""Examples:
|
|
Print all origin IDs from year 2022 and thereafter
|
|
{os.path.basename(__file__)} -d mysql://sysop:sysop@localhost/seiscomp \
|
|
--begin "2022-01-01 00:00:00"
|
|
|
|
Print IDs of all events in XML file
|
|
{os.path.basename(__file__)} -i origins.xml
|
|
"""
|
|
)
|
|
|
|
def run(self):
|
|
if self._inputFile:
|
|
out = readXML(self)
|
|
print(f"{self._delimiter.join(out)}\n", file=sys.stdout)
|
|
return True
|
|
|
|
seiscomp.logging.debug(f"Search interval: {self._startTime} - {self._endTime}")
|
|
out = []
|
|
q = (
|
|
"select PublicObject.%s, Origin.* from Origin, PublicObject where Origin._oid=PublicObject._oid and Origin.%s >= '%s' and Origin.%s < '%s'"
|
|
% (
|
|
self.database().convertColumnName("publicID"),
|
|
self.database().convertColumnName("time_value"),
|
|
self.database().timeToString(self._startTime),
|
|
self.database().convertColumnName("time_value"),
|
|
self.database().timeToString(self._endTime),
|
|
)
|
|
)
|
|
|
|
if self.author:
|
|
q += " and Origin.%s = '%s' " % (
|
|
self.database().convertColumnName("creationInfo_author"),
|
|
self.query().toString(self.author),
|
|
)
|
|
|
|
for obj in self.query().getObjectIterator(
|
|
q, seiscomp.datamodel.Origin.TypeInfo()
|
|
):
|
|
org = seiscomp.datamodel.Origin.Cast(obj)
|
|
if org:
|
|
out.append(org.publicID())
|
|
|
|
print(f"{self._delimiter.join(out)}\n", file=sys.stdout)
|
|
return True
|
|
|
|
|
|
def main():
|
|
app = OriginList(len(sys.argv), sys.argv)
|
|
app()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|