Merge pull request #660 from srcarter3/unidata_20.3.2-osx
Unidata 20.3.2 osx
This commit is contained in:
commit
956b11fd52
166 changed files with 50198 additions and 59115 deletions
23
build/awips-ade/Dockerfile.awips-ade-20.3.2-2.el7
Normal file
23
build/awips-ade/Dockerfile.awips-ade-20.3.2-2.el7
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
FROM tiffanym13/awips-devel-20.3.2-2:el7
|
||||||
|
ENV VERSION 20.3.2
|
||||||
|
ENV RELEASE 2
|
||||||
|
MAINTAINER Tiffany Meyer<tiffanym@ucar.edu>
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
COPY el7-dev.repo /etc/yum.repos.d/awips2.repo
|
||||||
|
|
||||||
|
RUN groupadd fxalpha && useradd -G fxalpha awips
|
||||||
|
|
||||||
|
RUN mkdir -p /home/awips/dev/unidata_20.3.2/awips2/dist/el7-dev-20231212/
|
||||||
|
ADD el7-dev-20231212 /home/awips/dev/unidata_20.3.2/awips2/dist/el7-dev-20231212
|
||||||
|
|
||||||
|
RUN yum -y clean all
|
||||||
|
|
||||||
|
RUN yum groupinstall awips2-ade -y
|
||||||
|
|
||||||
|
RUN mkdir -p /awips2/jenkins/buildspace/workspace/AWIPS2-UPC_build/baseline && mkdir -p /awips2/jenkins/buildspace/workspace/tmp
|
||||||
|
RUN mkdir -p /awips2/jenkins/build/rpms/awips2_latest/{x86_64,noarch}/
|
||||||
|
RUN chown -R awips:fxalpha /awips2/jenkins/
|
||||||
|
|
||||||
|
ENTRYPOINT ["/bin/bash"]
|
22
build/awips-ade/Dockerfile.awips-devel-20.3.2-2.el7
Normal file
22
build/awips-ade/Dockerfile.awips-devel-20.3.2-2.el7
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
FROM centos:7
|
||||||
|
ENV VERSION 20.3.2-2
|
||||||
|
ENV RELEASE 2
|
||||||
|
MAINTAINER Tiffany Meyer<tiffanym@ucar.edu>
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
RUN yum update yum -y
|
||||||
|
|
||||||
|
RUN yum groupinstall "Development tools" -y
|
||||||
|
RUN yum install epel-release -y
|
||||||
|
RUN yum clean all -y
|
||||||
|
|
||||||
|
ENV systemDeps="wget rsync git net-tools gzip libtool"
|
||||||
|
ENV rpmDeps="gcc-c++ gcc-gfortran rpm-build createrepo expat-devel lua-devel cyrus-sasl-devel cyrus-sasl-plain cyrus-sasl-md5 nss-devel nspr-devel libxml2-devel openldap-devel cmake"
|
||||||
|
ENV pythonDeps="tk-devel tcl-devel readline-devel bzip2-devel openssl-devel compat-libf2c-34"
|
||||||
|
ENV awipsDeps="netcdf netcdf-devel"
|
||||||
|
|
||||||
|
RUN yum install $systemDeps $rpmDeps $pythonDeps $awipsDeps -y
|
||||||
|
RUN yum update -y
|
||||||
|
|
||||||
|
ENTRYPOINT ["/bin/bash"]
|
|
@ -10,16 +10,17 @@ if [ -z "$1" ]; then
|
||||||
fi
|
fi
|
||||||
os_version=$1
|
os_version=$1
|
||||||
|
|
||||||
existing=$(sudo docker images |grep awips-ade | grep $1 | awk '{ print $3 }')
|
existing=$(docker images |grep awips-ade | grep $1 | awk '{ print $3 }')
|
||||||
if [ ! -z "$existing" ]; then
|
if [ ! -z "$existing" ]; then
|
||||||
sudo docker rmi $existing
|
docker rmi $existing
|
||||||
fi
|
fi
|
||||||
img="20.3.2-1"
|
img="20.3.2-2"
|
||||||
|
|
||||||
pushd /awips2/repo/awips2-builds/build/awips-ade
|
pushd /awips2/repo/awips2-builds/build/awips-ade
|
||||||
sudo docker build -t tiffanym13/awips-ade-${img} -f Dockerfile.awips-ade-${img}.${os_version} .
|
docker build -t tiffanym13/awips-ade-${img} -f Dockerfile.awips-ade-${img}.${os_version} .
|
||||||
dockerID=$(sudo docker images | grep awips-ade | grep latest | awk '{print $3}' | head -1 )
|
dockerID=$(docker images | grep awips-ade | awk '{print $3}' | head -1 )
|
||||||
#sudo docker tag $dockerID unidata/awips-ade:${AWIPSII_VERSION}-${os_version}
|
#docker tag $dockerID unidata/awips-ade:${AWIPSII_VERSION}-${os_version}
|
||||||
sudo docker tag $dockerID tiffanym13/awips-ade-${img}:${AWIPSII_VERSION}-${os_version}
|
docker tag $dockerID tiffanym13/awips-ade-${img}:${AWIPSII_VERSION}-${os_version}
|
||||||
sudo docker rmi tiffanym13/awips-ade-${img}:latest
|
docker rmi tiffanym13/awips-ade-${img}:latest
|
||||||
sudo docker push tiffanym13/awips-ade-${img}:${AWIPSII_VERSION}-${os_version}
|
#docker rmi tiffanym13/awips-ade-${img}:${AWIPSII_VERSION}-${os_version}
|
||||||
|
docker push tiffanym13/awips-ade-${img}:${AWIPSII_VERSION}-${os_version}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
dir="$( cd "$(dirname "$0")" ; pwd -P )"
|
dir="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||||
pushd $dir
|
pushd $dir
|
||||||
. ../buildEnvironment.sh
|
. ../buildEnvironment.sh
|
||||||
img="awips-devel-20.3.2-1"
|
img="awips-devel-20.3.2-2"
|
||||||
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
if [ -z "$1" ]; then
|
||||||
|
@ -13,11 +13,11 @@ os_version=$1
|
||||||
|
|
||||||
existing=$(sudo docker images |grep ${img} | grep $1 | awk '{ print $3 }')
|
existing=$(sudo docker images |grep ${img} | grep $1 | awk '{ print $3 }')
|
||||||
if [ ! -z "$existing" ]; then
|
if [ ! -z "$existing" ]; then
|
||||||
sudo docker rmi $existing
|
docker rmi $existing
|
||||||
fi
|
fi
|
||||||
pushd /awips2/repo/awips2-builds/build/awips-ade
|
pushd /awips2/repo/awips2-builds/build/awips-ade
|
||||||
sudo docker build -t tiffanym13/${img} -f Dockerfile.${img}.${os_version} .
|
docker build -t tiffanym13/${img} -f Dockerfile.${img}.${os_version} .
|
||||||
dockerID=$(sudo docker images | grep ${img} | grep latest | awk '{print $3}' | head -1 )
|
dockerID=$(docker images | grep ${img} | grep latest | awk '{print $3}' | head -1 )
|
||||||
sudo docker tag $dockerID tiffanym13/${img}:${os_version}
|
docker tag $dockerID tiffanym13/${img}:${os_version}
|
||||||
sudo docker rmi tiffanym13/${img}:latest
|
docker rmi tiffanym13/${img}:latest
|
||||||
sudo docker push tiffanym13/${img}:${os_version}
|
docker push tiffanym13/${img}:${os_version}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
[awips2repo]
|
[awips2repo]
|
||||||
name=AWIPS II Repository
|
name=AWIPS II Repository
|
||||||
#baseurl=http://www.unidata.ucar.edu/repos/yum/18.2.1-ade
|
#baseurl=http://www.unidata.ucar.edu/repos/yum/18.2.1-ade
|
||||||
baseurl=file:///home/awips/dev/build/rpmbuild/RPMS
|
#baseurl=file:///home/awips/dev/build/rpmbuild/RPMS
|
||||||
|
baseurl=file:///home/awips/dev/unidata_20.3.2/awips2/dist/el7-dev-20231212
|
||||||
enabled=1
|
enabled=1
|
||||||
protect=0
|
protect=0
|
||||||
gpgcheck=0
|
gpgcheck=0
|
||||||
|
|
|
@ -32,3 +32,4 @@ build/deploy.ignite.awips2
|
||||||
../awips2-ogc/foss/*
|
../awips2-ogc/foss/*
|
||||||
../awips2-ogc/edex/*
|
../awips2-ogc/edex/*
|
||||||
../awips2-ogc/features/*
|
../awips2-ogc/features/*
|
||||||
|
../python-awips
|
||||||
|
|
|
@ -52,7 +52,7 @@ fi
|
||||||
#
|
#
|
||||||
imgname=tiffanym13/awips-ade
|
imgname=tiffanym13/awips-ade
|
||||||
imgvers=20.3.2
|
imgvers=20.3.2
|
||||||
sudo docker run --entrypoint=/bin/bash --privileged -d -ti -e "container=docker" $dirs $imgname-$imgvers-1:$imgvers-$os_version
|
sudo docker run --entrypoint=/bin/bash --privileged -d -ti -e "container=docker" $dirs $imgname-$imgvers-2:$imgvers-$os_version
|
||||||
dockerID=$(sudo docker ps | grep awips-ade | awk '{print $1}' | head -1 )
|
dockerID=$(sudo docker ps | grep awips-ade | awk '{print $1}' | head -1 )
|
||||||
sudo docker logs $dockerID
|
sudo docker logs $dockerID
|
||||||
sudo docker exec -ti $dockerID /bin/bash -xec "/awips2/repo/awips2-builds/build/build_rpms.sh $os_version $rpmname";
|
sudo docker exec -ti $dockerID /bin/bash -xec "/awips2/repo/awips2-builds/build/build_rpms.sh $os_version $rpmname";
|
||||||
|
@ -77,11 +77,13 @@ if [[ $(whoami) == "awips" ]]; then # local build
|
||||||
sudo mv dist/${os_version}-dev dist/${os_version}-dev-${date}
|
sudo mv dist/${os_version}-dev dist/${os_version}-dev-${date}
|
||||||
sudo su - -c "createrepo -g /awips2/repo/awips2/dist/comps.xml /awips2/repo/awips2/dist/${os_version}-dev-${date}/"
|
sudo su - -c "createrepo -g /awips2/repo/awips2/dist/comps.xml /awips2/repo/awips2/dist/${os_version}-dev-${date}/"
|
||||||
sudo chown -R awips:fxalpha dist/${os_version}-dev-${date}
|
sudo chown -R awips:fxalpha dist/${os_version}-dev-${date}
|
||||||
echo "rsync -aP dist/${os_version}-dev-${date}"
|
echo "rsync -aP dist/${os_version}-dev-${date} tiffanym@fserv:/share/awips2/${AWIPSII_VERSION}/linux/"
|
||||||
#echo "rsync -aP dist/${os_version}-dev-${date} tiffanym@fserv:/share/awips2/${AWIPSII_VERSION}/linux/"
|
rsync -aP dist/${os_version}-dev-${date} tiffanym@fserv:/share/awips2/${AWIPSII_VERSION}/linux/
|
||||||
#rsync -aP dist/${os_version}-dev-${date} tiffanym@fserv:/share/awips2/${AWIPSII_VERSION}/linux/
|
cmd="cd /share/awips2/${AWIPSII_VERSION}/linux ; find ${os_version}-dev-${date} -type f | ../../git_nexus_tool/nexus-tools/bash/nexus-upload.sh -t downloads -u tiffanym -o awips2 -v ${AWIPSII_VERSION}/linux/rpms/"
|
||||||
|
echo "Need to run ssh@tiffanym '${cmd}' and provide -p [password]"
|
||||||
|
|
||||||
#rsync -aP dist/${os_version}-dev-${date} awips@edex3:/awips2/dev
|
#rsync -aP dist/${os_version}-dev-${date} awips@edex3:/awips2/dev
|
||||||
rsync -aP dist/${os_version}-dev-${date} awips@hardy:/awips2/dev
|
#rsync -aP dist/${os_version}-dev-${date} awips@hardy:/awips2/dev
|
||||||
#repomanage -k1 --old dist/${os_version}-dev | xargs rm -f
|
#repomanage -k1 --old dist/${os_version}-dev | xargs rm -f
|
||||||
#
|
#
|
||||||
# Push to web server
|
# Push to web server
|
||||||
|
|
|
@ -35,10 +35,10 @@ import argparse
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request.GfeClientRequest import GfeClientRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request.GfeClientRequest import GfeClientRequest
|
||||||
from dynamicserialize.dstypes.java.util import Date
|
from dynamicserialize.dstypes.java.util import Date
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreTimeAction
|
from awips.UsageArgumentParser import StoreTimeAction
|
||||||
from ufpy.UsageArgumentParser import TIME_FORMAT
|
from awips.UsageArgumentParser import TIME_FORMAT
|
||||||
|
|
||||||
def validateArgs(args=None):
|
def validateArgs(args=None):
|
||||||
|
|
||||||
|
|
|
@ -474,8 +474,8 @@ def validateArgs(args=None, parents=[]):
|
||||||
# imports required for this method must be here so it can be invoked
|
# imports required for this method must be here so it can be invoked
|
||||||
# from gfeClient.py
|
# from gfeClient.py
|
||||||
############################################################################
|
############################################################################
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreTimeAction
|
from awips.UsageArgumentParser import StoreTimeAction
|
||||||
|
|
||||||
global DEFAULT_OUTPUT_DIR
|
global DEFAULT_OUTPUT_DIR
|
||||||
DEFAULT_OUTPUT_DIR = '../products/IMAGE'
|
DEFAULT_OUTPUT_DIR = '../products/IMAGE'
|
||||||
|
|
|
@ -55,7 +55,7 @@ def runFormatter(args):
|
||||||
|
|
||||||
from com.raytheon.viz.gfe.core import DataManagerUIFactory
|
from com.raytheon.viz.gfe.core import DataManagerUIFactory
|
||||||
from com.raytheon.viz.gfe.core import DataManager
|
from com.raytheon.viz.gfe.core import DataManager
|
||||||
from ufpy.UsageArgumentParser import TIME_FORMAT
|
from awips.UsageArgumentParser import TIME_FORMAT
|
||||||
from com.raytheon.viz.gfe.core import DataManagerFactory
|
from com.raytheon.viz.gfe.core import DataManagerFactory
|
||||||
|
|
||||||
LOGGER.info("TextFormatter Starting")
|
LOGGER.info("TextFormatter Starting")
|
||||||
|
@ -88,10 +88,10 @@ def validateArgs(args=None, parents=[]):
|
||||||
# imports required for this method must be here so it can be invoked
|
# imports required for this method must be here so it can be invoked
|
||||||
# from gfeClient.py
|
# from gfeClient.py
|
||||||
############################################################################
|
############################################################################
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreDatabaseIDAction
|
from awips.UsageArgumentParser import StoreDatabaseIDAction
|
||||||
from ufpy.UsageArgumentParser import StoreTimeAction
|
from awips.UsageArgumentParser import StoreTimeAction
|
||||||
from ufpy.UsageArgumentParser import TIME_FORMAT
|
from awips.UsageArgumentParser import TIME_FORMAT
|
||||||
import time
|
import time
|
||||||
|
|
||||||
parser = UsageArgumentParser.UsageArgumentParser(conflict_handler="resolve",
|
parser = UsageArgumentParser.UsageArgumentParser(conflict_handler="resolve",
|
||||||
|
|
|
@ -170,8 +170,8 @@ def validateArgs(args=None, parents=[]):
|
||||||
# imports required for this method must be here so it can be invoked
|
# imports required for this method must be here so it can be invoked
|
||||||
# from gfeClient.py
|
# from gfeClient.py
|
||||||
############################################################################
|
############################################################################
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreTimeAction
|
from awips.UsageArgumentParser import StoreTimeAction
|
||||||
|
|
||||||
parser = UsageArgumentParser.UsageArgumentParser(conflict_handler="resolve",
|
parser = UsageArgumentParser.UsageArgumentParser(conflict_handler="resolve",
|
||||||
parents=parents,
|
parents=parents,
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
import time, string
|
import time, string
|
||||||
import logging
|
import logging
|
||||||
from ufpy import TimeUtil
|
from awips import TimeUtil
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
timeStr = ""
|
timeStr = ""
|
||||||
|
|
|
@ -55,7 +55,7 @@ import errno
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from ufpy.dataaccess import DataAccessLayer
|
from awips.dataaccess import DataAccessLayer
|
||||||
|
|
||||||
import GridManipulation
|
import GridManipulation
|
||||||
import HazardUtils
|
import HazardUtils
|
||||||
|
|
|
@ -75,22 +75,4 @@
|
||||||
name="Plot Models"
|
name="Plot Models"
|
||||||
category="com.raytheon.uf.viz.productbrowser.productbrowserpreferencespage"/>
|
category="com.raytheon.uf.viz.productbrowser.productbrowserpreferencespage"/>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
|
||||||
point="com.raytheon.viz.ui.contextualMenu">
|
|
||||||
<contextualMenu
|
|
||||||
actionClass="com.raytheon.viz.pointdata.def.ui.EditPlotResourceAction"
|
|
||||||
capabilityClass="com.raytheon.viz.pointdata.rsc.PlotResource"
|
|
||||||
name="com.raytheon.viz.pointdata.def.ui.EditPlotResourceAction"
|
|
||||||
sortID="600">
|
|
||||||
</contextualMenu>
|
|
||||||
</extension>
|
|
||||||
<extension
|
|
||||||
point="com.raytheon.viz.ui.contextualMenu">
|
|
||||||
<contextualMenu
|
|
||||||
actionClass="com.raytheon.viz.pointdata.def.ui.EditPlotBlendedResourceAction"
|
|
||||||
capabilityClass="com.raytheon.viz.pointdata.rsc.PlotBlendedResource"
|
|
||||||
name="com.raytheon.viz.pointdata.def.ui.EditPlotBlendedResourceAction"
|
|
||||||
sortID="601">
|
|
||||||
</contextualMenu>
|
|
||||||
</extension>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
145
dist/comps.xml
vendored
145
dist/comps.xml
vendored
|
@ -2,6 +2,46 @@
|
||||||
<!-- <meta> -->
|
<!-- <meta> -->
|
||||||
<!-- Meta Information Will Go Here Eventually -->
|
<!-- Meta Information Will Go Here Eventually -->
|
||||||
<!-- </meta> -->
|
<!-- </meta> -->
|
||||||
|
<group>
|
||||||
|
<id>awips2-ade</id>
|
||||||
|
<name>AWIPS Development</name>
|
||||||
|
<default>true</default>
|
||||||
|
<description>This Will Install All Of The AWIPS Components That Are Required For Deploying in Eclipse (non DB)</description>
|
||||||
|
<uservisible>true</uservisible>
|
||||||
|
<packagelist>
|
||||||
|
<packagereq type="default">awips2</packagereq>
|
||||||
|
<packagereq type="default">awips2-ant</packagereq>
|
||||||
|
<packagereq type="default">awips2-eclipse</packagereq>
|
||||||
|
<packagereq type="default">awips2-hdf5-devel</packagereq>
|
||||||
|
<packagereq type="default">awips2-maven</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-cheroot</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-contextlib2</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-cython</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-jaraco.functools</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-more-itertools</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-pkgconfig</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-portend</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-pycairo</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-pygobject</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-setuptools_scm_git_archive</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-setuptools_scm</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-tempora</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-zc.lockfile</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-numpy</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-dateutil</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-pyparsing</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-pbr</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-mock</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-numexpr</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-thrift</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-setuptools</packagereq>
|
||||||
|
<packagereq type="default">awips2-hdf5</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-six</packagereq>
|
||||||
|
<packagereq type="default">awips2-python-pytz</packagereq>
|
||||||
|
<packagereq type="default">awips2-netcdf-devel</packagereq>
|
||||||
|
<packagereq type="default">awips2-qpid-proton</packagereq>
|
||||||
|
</packagelist>
|
||||||
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<id>awips2-server</id>
|
<id>awips2-server</id>
|
||||||
<name>AWIPS EDEX Server</name>
|
<name>AWIPS EDEX Server</name>
|
||||||
|
@ -126,7 +166,6 @@
|
||||||
<packagereq type="mandatory">awips2-data.gfe</packagereq>
|
<packagereq type="mandatory">awips2-data.gfe</packagereq>
|
||||||
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -137,9 +176,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -270,7 +308,6 @@
|
||||||
<packagereq type="mandatory">awips2-rcm</packagereq>
|
<packagereq type="mandatory">awips2-rcm</packagereq>
|
||||||
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -281,9 +318,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -325,7 +361,6 @@
|
||||||
<packagereq type="mandatory">awips2-notification</packagereq>
|
<packagereq type="mandatory">awips2-notification</packagereq>
|
||||||
<packagereq type="mandatory">awips2-qpid-proton</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -336,9 +371,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -379,7 +413,6 @@
|
||||||
<packagereq type="mandatory">awips2-cli</packagereq>
|
<packagereq type="mandatory">awips2-cli</packagereq>
|
||||||
<packagereq type="mandatory">awips2-notification</packagereq>
|
<packagereq type="mandatory">awips2-notification</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -390,9 +423,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -521,7 +553,6 @@
|
||||||
<packagereq type="mandatory">awips2-notification</packagereq>
|
<packagereq type="mandatory">awips2-notification</packagereq>
|
||||||
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -532,9 +563,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -579,7 +609,6 @@
|
||||||
<packagereq type="mandatory">awips2-notification</packagereq>
|
<packagereq type="mandatory">awips2-notification</packagereq>
|
||||||
<packagereq type="mandatory">awips2-edex-hazards-scripts</packagereq>
|
<packagereq type="mandatory">awips2-edex-hazards-scripts</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -590,9 +619,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -629,7 +657,6 @@
|
||||||
<packagereq type="mandatory">awips2-pypies</packagereq>
|
<packagereq type="mandatory">awips2-pypies</packagereq>
|
||||||
<packagereq type="mandatory">awips2-data.hdf5-topo</packagereq>
|
<packagereq type="mandatory">awips2-data.hdf5-topo</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -640,9 +667,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -674,7 +700,6 @@
|
||||||
<packagereq type="mandatory">awips2-python-jep</packagereq>
|
<packagereq type="mandatory">awips2-python-jep</packagereq>
|
||||||
<packagereq type="mandatory">awips2-java</packagereq>
|
<packagereq type="mandatory">awips2-java</packagereq>
|
||||||
<packagereq type="mandatory">awips2-qpid-broker-j</packagereq>
|
<packagereq type="mandatory">awips2-qpid-broker-j</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -685,56 +710,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-pyparsing</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-pytz</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-six</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-stomp.py</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-cftime</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-netcdf4</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-hdf5</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-netcdf</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-netcdf-devel</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-localapps-environment</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-watchdog</packagereq>
|
|
||||||
</packagelist>
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<group>
|
|
||||||
<id>awips2-ldm-server</id>
|
|
||||||
<name>AWIPS II LDM Server</name>
|
|
||||||
<default>true</default>
|
|
||||||
<description>This Will Install The AWIPS II LDM Server.</description>
|
|
||||||
<uservisible>true</uservisible>
|
|
||||||
<packagelist>
|
|
||||||
<packagereq type="mandatory">awips2</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-version</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-jep</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-java</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-psql</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-ldm</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-cli</packagereq>
|
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-backports-lru_cache</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-matplotlib</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-setuptools</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-numpy</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -770,7 +747,6 @@
|
||||||
<packagereq type="default">awips2-cli</packagereq>
|
<packagereq type="default">awips2-cli</packagereq>
|
||||||
<packagereq type="default">awips2-notification</packagereq>
|
<packagereq type="default">awips2-notification</packagereq>
|
||||||
|
|
||||||
<packagereq type="default">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="default">awips2-python-h5py</packagereq>
|
<packagereq type="default">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="default">awips2-python-matplotlib</packagereq>
|
<packagereq type="default">awips2-python-matplotlib</packagereq>
|
||||||
<packagereq type="default">awips2-python-setuptools</packagereq>
|
<packagereq type="default">awips2-python-setuptools</packagereq>
|
||||||
|
@ -778,9 +754,8 @@
|
||||||
<packagereq type="default">awips2-qpid-proton-python</packagereq>
|
<packagereq type="default">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="default">awips2-python-scipy</packagereq>
|
<packagereq type="default">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="default">awips2-python-tables</packagereq>
|
<packagereq type="default">awips2-python-tables</packagereq>
|
||||||
<packagereq type="default">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="default">awips2-python-tpg</packagereq>
|
<packagereq type="default">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="default">awips2-python-ufpy</packagereq>
|
<packagereq type="default">awips2-python-awips</packagereq>
|
||||||
<packagereq type="default">awips2-python-werkzeug</packagereq>
|
<packagereq type="default">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="default">awips2-python-shapely</packagereq>
|
<packagereq type="default">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="default">awips2-python-dateutil</packagereq>
|
<packagereq type="default">awips2-python-dateutil</packagereq>
|
||||||
|
@ -878,7 +853,6 @@
|
||||||
<packagereq type="mandatory">awips2-postgresql</packagereq>
|
<packagereq type="mandatory">awips2-postgresql</packagereq>
|
||||||
<packagereq type="mandatory">awips2-psql</packagereq>
|
<packagereq type="mandatory">awips2-psql</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-jep</packagereq>
|
<packagereq type="mandatory">awips2-python-jep</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
|
@ -898,9 +872,8 @@
|
||||||
<packagereq type="mandatory">awips2-python-cftime</packagereq>
|
<packagereq type="mandatory">awips2-python-cftime</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-netcdf4</packagereq>
|
<packagereq type="mandatory">awips2-python-netcdf4</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-hdf5</packagereq>
|
<packagereq type="mandatory">awips2-hdf5</packagereq>
|
||||||
<packagereq type="mandatory">awips2-watchdog</packagereq>
|
<packagereq type="mandatory">awips2-watchdog</packagereq>
|
||||||
|
@ -1013,7 +986,6 @@
|
||||||
<packagereq type="default">awips2-notification</packagereq>
|
<packagereq type="default">awips2-notification</packagereq>
|
||||||
<packagereq type="default">awips2-aviation-shared</packagereq>
|
<packagereq type="default">awips2-aviation-shared</packagereq>
|
||||||
|
|
||||||
<packagereq type="default">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="default">awips2-python-h5py</packagereq>
|
<packagereq type="default">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="default">awips2-python-matplotlib</packagereq>
|
<packagereq type="default">awips2-python-matplotlib</packagereq>
|
||||||
<packagereq type="default">awips2-python-setuptools</packagereq>
|
<packagereq type="default">awips2-python-setuptools</packagereq>
|
||||||
|
@ -1021,9 +993,8 @@
|
||||||
<packagereq type="default">awips2-qpid-proton-python</packagereq>
|
<packagereq type="default">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="default">awips2-python-scipy</packagereq>
|
<packagereq type="default">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="default">awips2-python-tables</packagereq>
|
<packagereq type="default">awips2-python-tables</packagereq>
|
||||||
<packagereq type="default">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="default">awips2-python-tpg</packagereq>
|
<packagereq type="default">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="default">awips2-python-ufpy</packagereq>
|
<packagereq type="default">awips2-python-awips</packagereq>
|
||||||
<packagereq type="default">awips2-python-werkzeug</packagereq>
|
<packagereq type="default">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="default">awips2-python-shapely</packagereq>
|
<packagereq type="default">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="default">awips2-python-dateutil</packagereq>
|
<packagereq type="default">awips2-python-dateutil</packagereq>
|
||||||
|
@ -1145,7 +1116,6 @@
|
||||||
<packagereq type="mandatory">awips2-notification</packagereq>
|
<packagereq type="mandatory">awips2-notification</packagereq>
|
||||||
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
<packagereq type="mandatory">awips2-aviation-shared</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -1156,9 +1126,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -1257,7 +1226,6 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton</packagereq>
|
||||||
|
|
||||||
<packagereq type="mandatory">awips2-hydroapps-shared</packagereq>
|
<packagereq type="mandatory">awips2-hydroapps-shared</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
<packagereq type="mandatory">awips2-python-h5py</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
<packagereq type="mandatory">awips2-python-cycler</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
<packagereq type="mandatory">awips2-python-kiwisolver</packagereq>
|
||||||
|
@ -1268,9 +1236,8 @@
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
<packagereq type="mandatory">awips2-python-tables</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -1349,13 +1316,11 @@
|
||||||
<packagereq type="mandatory">awips2-bmh</packagereq>
|
<packagereq type="mandatory">awips2-bmh</packagereq>
|
||||||
<packagereq type="mandatory">awips2-edex-bmh</packagereq>
|
<packagereq type="mandatory">awips2-edex-bmh</packagereq>
|
||||||
<packagereq type="mandatory">awips2-neospeech</packagereq>
|
<packagereq type="mandatory">awips2-neospeech</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dynamicserialize</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-numpy</packagereq>
|
<packagereq type="mandatory">awips2-python-numpy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
<packagereq type="mandatory">awips2-qpid-proton-python</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
<packagereq type="mandatory">awips2-python-scipy</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-thrift</packagereq>
|
|
||||||
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
<packagereq type="mandatory">awips2-python-tpg</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
<packagereq type="mandatory">awips2-python-werkzeug</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
<packagereq type="mandatory">awips2-python-shapely</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
<packagereq type="mandatory">awips2-python-dateutil</packagereq>
|
||||||
|
@ -1428,7 +1393,7 @@
|
||||||
<packagereq type="mandatory">awips2-version</packagereq>
|
<packagereq type="mandatory">awips2-version</packagereq>
|
||||||
<packagereq type="mandatory">awips2-ignite</packagereq>
|
<packagereq type="mandatory">awips2-ignite</packagereq>
|
||||||
<packagereq type="mandatory">awips2-java</packagereq>
|
<packagereq type="mandatory">awips2-java</packagereq>
|
||||||
<packagereq type="mandatory">awips2-python-ufpy</packagereq>
|
<packagereq type="mandatory">awips2-python-awips</packagereq>
|
||||||
<packagereq type="mandatory">awips2-watchdog</packagereq>
|
<packagereq type="mandatory">awips2-watchdog</packagereq>
|
||||||
</packagelist>
|
</packagelist>
|
||||||
</group>
|
</group>
|
||||||
|
|
2
dist/getRPMOutput.pl
vendored
2
dist/getRPMOutput.pl
vendored
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
|
|
||||||
$date="20221018";
|
$date="20240108";
|
||||||
|
|
||||||
$path="/awips2/repo/awips2/dist/el7-dev-$date";
|
$path="/awips2/repo/awips2/dist/el7-dev-$date";
|
||||||
|
|
||||||
|
|
98188
dist/rpmOutput
vendored
98188
dist/rpmOutput
vendored
File diff suppressed because it is too large
Load diff
|
@ -176,7 +176,7 @@ These errors are actually happening because the Windows machine is using IPv6, w
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## MacOS
|
## macOS
|
||||||
|
|
||||||
### Monterey CAVE Warning
|
### Monterey CAVE Warning
|
||||||
|
|
||||||
|
@ -225,6 +225,23 @@ You may be able to fix this issue:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Model Data Not Rendering
|
||||||
|
|
||||||
|
This behavior has appeared with MacOS Sonoma (v14) -- model data is no longer loading and you see the following errors on the screen or in the AlertView:
|
||||||
|
> ERROR: An internal error occured during: "Initializing...".
|
||||||
|
>
|
||||||
|
> ERROR: An internal error occured during: "Product Loader".
|
||||||
|
>
|
||||||
|
> ERROR: An internal error occured during "Initializing...".
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
If you encounter this behavior, please close CAVE, [clear caveData as described above](#mac), then restart CAVE and try to load the data again.
|
||||||
|
|
||||||
|
If you still experience issues, please let us know at support-awips@unidata.ucar.edu
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Linux
|
## Linux
|
||||||
|
|
||||||
### Troubleshooting Uninstalling EDEX
|
### Troubleshooting Uninstalling EDEX
|
||||||
|
|
|
@ -179,6 +179,8 @@ A full list of all released blogs can be found below:
|
||||||
- [AWIPS 20.3.2-0.3 Beta CAVE Software Release](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-unidata-awips-202)
|
- [AWIPS 20.3.2-0.3 Beta CAVE Software Release](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-unidata-awips-202)
|
||||||
- [AWIPS 20.3.2-0.4 Beta Software Release - with EDEX!](https://www.unidata.ucar.edu/blogs/news/entry/unidata-awips-20-3-2)
|
- [AWIPS 20.3.2-0.4 Beta Software Release - with EDEX!](https://www.unidata.ucar.edu/blogs/news/entry/unidata-awips-20-3-2)
|
||||||
- [AWIPS 20.3.2-1 Production AWIPS Release](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-unidata-awips-203)
|
- [AWIPS 20.3.2-1 Production AWIPS Release](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-unidata-awips-203)
|
||||||
|
- [Changes Related to v20.3.2 AWIPS Release](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-changes-related-to)
|
||||||
|
- [AMS 2024 Highlight](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-ams-2024-highlight)
|
||||||
|
|
||||||
#### CAVE
|
#### CAVE
|
||||||
|
|
||||||
|
@ -209,6 +211,7 @@ A full list of all released blogs can be found below:
|
||||||
- [All About Sampling](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-all-about-sampling)
|
- [All About Sampling](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-all-about-sampling)
|
||||||
- [Maps Database Constraints](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-maps-database-constraints)
|
- [Maps Database Constraints](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-maps-database-constraints)
|
||||||
- [Measuring Up - Distance Tools in CAVE](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-measuring-up-distance)
|
- [Measuring Up - Distance Tools in CAVE](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-measuring-up-distance)
|
||||||
|
- [New RAWS Data](https://www.unidata.ucar.edu/blogs/news/entry/awips-tips-new-raws-data)
|
||||||
|
|
||||||
#### Python-AWIPS
|
#### Python-AWIPS
|
||||||
|
|
||||||
|
|
BIN
docs/images/macModelFailure.png
Normal file
BIN
docs/images/macModelFailure.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 226 KiB |
BIN
docs/images/workstationPlayer.png
Normal file
BIN
docs/images/workstationPlayer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
|
@ -51,6 +51,12 @@ Regardless of what Operating System CAVE is running on, these general requiremen
|
||||||
|
|
||||||
!!! note "While CentOS8 has reach End of Life as of Dec. 31, 2021, CentOS7 End of Life isn't until June 30, 2024."
|
!!! note "While CentOS8 has reach End of Life as of Dec. 31, 2021, CentOS7 End of Life isn't until June 30, 2024."
|
||||||
|
|
||||||
|
### Upgrade Existing Installation
|
||||||
|
|
||||||
|
Whether you have CAVE currently installed or not, you can follow the [Download and Installation Instructions](#download-and-installation-instructions) below. The script will remove the old version of CAVE if needed, and install the latest version.
|
||||||
|
|
||||||
|
If you would like to completely remove CAVE, please see the [uninstall instructions further down this page](#linux_1).
|
||||||
|
|
||||||
### Download and Installation Instructions
|
### Download and Installation Instructions
|
||||||
|
|
||||||
1. Download the following installer: [**awips_install.sh** <i class="fa fa-download"></i>](https://downloads.unidata.ucar.edu/awips2/current/linux/awips_install.sh)
|
1. Download the following installer: [**awips_install.sh** <i class="fa fa-download"></i>](https://downloads.unidata.ucar.edu/awips2/current/linux/awips_install.sh)
|
||||||
|
@ -78,10 +84,21 @@ For Windows, we offer two installation options: a [**Direct Windows Installation
|
||||||
|
|
||||||
!!! warning "The virtual machine option won't render RGB composites of satellite imagery."
|
!!! warning "The virtual machine option won't render RGB composites of satellite imagery."
|
||||||
|
|
||||||
!!! note "For those running CAVE in a lab or needing it installed at the system level for multiple users, please contact support-awips@ucar.unidata.edu"
|
|
||||||
|
|
||||||
### Method 1: Direct Windows Install
|
### Method 1: Direct Windows Install
|
||||||
|
|
||||||
|
We offer CAVE installers at both the user-level (no administrative permissions needed), and the system-level (useful in a lab setting for instance). If you need the system-level installer, please skip to the [System-Level Installation section](#system-level-installation), otherwise simply proceed with the next sections.
|
||||||
|
|
||||||
|
#### Upgrade Existing Installation
|
||||||
|
|
||||||
|
If you do not currently have CAVE installed, please go directly to the [Download and Installation Instructions](#download-and-installation-instructions_1).
|
||||||
|
|
||||||
|
If you already have CAVE installed:
|
||||||
|
|
||||||
|
1. First remove it by going to the **Installed Apps** settings dialog. You can access this window by: Start bar > Settings > Apps > Installed Apps.
|
||||||
|
- *Typing "remove" in the start bar should bring you to this screen as well*
|
||||||
|
2. Find AWIPS CAVE, click on it, and click Uninstall.
|
||||||
|
3. Once the uninstall is finished, simply [download and install the latest version](#download-and-installation-instructions_1) as instructed below.
|
||||||
|
|
||||||
#### Download and Installation Instructions
|
#### Download and Installation Instructions
|
||||||
|
|
||||||
1. Download and install: [**awips-cave.msi** <i class="fa fa-download"></i>](https://downloads.unidata.ucar.edu/awips2/current/windows/awips-cave.msi)
|
1. Download and install: [**awips-cave.msi** <i class="fa fa-download"></i>](https://downloads.unidata.ucar.edu/awips2/current/windows/awips-cave.msi)
|
||||||
|
@ -94,6 +111,12 @@ To run CAVE, either:
|
||||||
- Type "cave" in the start bar and hit enter
|
- Type "cave" in the start bar and hit enter
|
||||||
- Find and run CAVE app in the file browser: `C:\Users\%USER%\AppData\Roaming\UCAR Unidata\AWIPS CAVE\CAVE.bat`
|
- Find and run CAVE app in the file browser: `C:\Users\%USER%\AppData\Roaming\UCAR Unidata\AWIPS CAVE\CAVE.bat`
|
||||||
|
|
||||||
|
#### System-Level Installation
|
||||||
|
|
||||||
|
If you need a system-level installation of CAVE, please fill out [this brief access form](https://docs.google.com/forms/d/e/1FAIpQLScLLR1JGh_DHESBSc6W0TVlslhNojT5OJF3WiTCajXg7CjWTA/viewform?usp=sf_link) for the .msi, and then proceed with installation similar to that described above.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Method 2: Linux Virtual Machine
|
### Method 2: Linux Virtual Machine
|
||||||
|
|
||||||
Please note, running CAVE in a Virtual Machine does have reduced functionality than running CAVE directly on hardware (ex: rendering RGB satellite images).
|
Please note, running CAVE in a Virtual Machine does have reduced functionality than running CAVE directly on hardware (ex: rendering RGB satellite images).
|
||||||
|
@ -109,6 +132,17 @@ Please note, running CAVE in a Virtual Machine does have reduced functionality t
|
||||||
1. Check the "High DPI scaling ovveride" checkbox and choose "Application" in the enabled dropdown
|
1. Check the "High DPI scaling ovveride" checkbox and choose "Application" in the enabled dropdown
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Upgrade Existing Installation
|
||||||
|
|
||||||
|
If you do not currently have CAVE installed, please go directly to the [Download and Installation Instructions](#download-and-installation-instructions_2).
|
||||||
|
|
||||||
|
If you already have CAVE installed you can either:
|
||||||
|
|
||||||
|
- Download the new Virtual Machine ([as described below](#download-and-installation-instructions_2)) and you will see the new VM in VMware, similar to this screenshot:
|
||||||
|

|
||||||
|
|
||||||
|
- Upgrade the version of CAVE within the Virtual Machine by following the [Linux instructions](#upgrade-existing-installation)
|
||||||
|
|
||||||
|
|
||||||
#### Download and Installation Instructions
|
#### Download and Installation Instructions
|
||||||
|
@ -138,6 +172,16 @@ Once inside the VM, to run CAVE either:
|
||||||
|
|
||||||
- Nvidia Graphics Card (Some Intel Graphics cards seem to work as well)
|
- Nvidia Graphics Card (Some Intel Graphics cards seem to work as well)
|
||||||
|
|
||||||
|
### Upgrade Existing Installation
|
||||||
|
|
||||||
|
If you do not currently have CAVE installed, please go directly to the [Download and Installation Instructions](#download-and-installation-instructions_3).
|
||||||
|
|
||||||
|
If you already have CAVE installed:
|
||||||
|
|
||||||
|
1. Remove the existing installation by locating it (it maybe be in your **Applications** folder), and dragging it to the trash.
|
||||||
|
2. Clear CAVE's cache by removing caveData (<a href="/awips2/appendix/common-problems#mac" target="_blank">see these instructions for removal</a>).
|
||||||
|
3. Follow the [Download and Installation Instructions](#download-and-installation-instructions_3) from below to install the newest version of CAVE.
|
||||||
|
|
||||||
### Download and Installation Instructions
|
### Download and Installation Instructions
|
||||||
|
|
||||||
1. Download and install CAVE: [awips-cave.dmg](https://downloads.unidata.ucar.edu/awips2/current/mac/awips-cave.dmg)
|
1. Download and install CAVE: [awips-cave.dmg](https://downloads.unidata.ucar.edu/awips2/current/mac/awips-cave.dmg)
|
||||||
|
@ -177,7 +221,10 @@ You can reset CAVE by removing the **caveData** directory and reconnecting to an
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Uninstalling CAVE (Linux)
|
## Uninstalling CAVE
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
These are instructions to manually uninstall CAVE. However, the [`awips_install.sh`](#download-and-installation-instructions) script will do these steps for you if you are installing a newer version of CAVE.
|
These are instructions to manually uninstall CAVE. However, the [`awips_install.sh`](#download-and-installation-instructions) script will do these steps for you if you are installing a newer version of CAVE.
|
||||||
|
|
||||||
**1. Make sure you have exited out of any CAVE sessions**
|
**1. Make sure you have exited out of any CAVE sessions**
|
||||||
|
@ -208,3 +255,17 @@ sudo yum remove awips2-*
|
||||||
rm -rf /awips2/cave
|
rm -rf /awips2/cave
|
||||||
rm -rf ~/caveData
|
rm -rf ~/caveData
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
To completely remove CAVE:
|
||||||
|
|
||||||
|
1. Type "remove" in the search bar and select **Add or remove programs**. This will open the Applications settings.
|
||||||
|
2. From here, find **AWIPS CAVE** and select "Uninstall".
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
To completely remove CAVE:
|
||||||
|
|
||||||
|
1. Find where it is installed (might be the **Applications** folder) and drag into the trash.
|
||||||
|
2. Then <a href="/awips2/appendix/common-problems#mac" target="_blank">remove caveData</a>.
|
||||||
|
|
|
@ -229,7 +229,7 @@ def sendWfoMessage(siteID, msgFile):
|
||||||
logEvent("Message received from site: %s\n%s" % (siteID, message))
|
logEvent("Message received from site: %s\n%s" % (siteID, message))
|
||||||
|
|
||||||
# send to AlertViz
|
# send to AlertViz
|
||||||
from ufpy import NotificationMessage
|
from awips import NotificationMessage
|
||||||
msg = NotificationMessage.NotificationMessage(port='9581', message=message,
|
msg = NotificationMessage.NotificationMessage(port='9581', message=message,
|
||||||
category='GFE', priority='SIGNIFICANT', source='GFE')
|
category='GFE', priority='SIGNIFICANT', source='GFE')
|
||||||
msg.send()
|
msg.send()
|
||||||
|
|
|
@ -46,7 +46,7 @@ import sys
|
||||||
from os.path import dirname
|
from os.path import dirname
|
||||||
from os.path import abspath
|
from os.path import abspath
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ConfigureTextProductsRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ConfigureTextProductsRequest
|
||||||
|
|
||||||
SCRIPT_DIR = abspath(dirname(sys.argv[0]))
|
SCRIPT_DIR = abspath(dirname(sys.argv[0]))
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
import calendar
|
import calendar
|
||||||
import sys, os, time, re, getopt
|
import sys, os, time, re, getopt
|
||||||
|
|
||||||
from ufpy import TimeUtil
|
from awips import TimeUtil
|
||||||
|
|
||||||
from com.raytheon.uf.common.wmo import WMOTimeParser
|
from com.raytheon.uf.common.wmo import WMOTimeParser
|
||||||
from com.raytheon.uf.edex.decodertools.time import TimeTools
|
from com.raytheon.uf.edex.decodertools.time import TimeTools
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
import os, tempfile, shutil
|
import os, tempfile, shutil
|
||||||
import numpy
|
import numpy
|
||||||
import PythonOverriderCore
|
import PythonOverriderCore
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.auth.resp import SuccessfulExecution
|
from dynamicserialize.dstypes.com.raytheon.uf.common.auth.resp import SuccessfulExecution
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationContext
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationContext
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.localization.msgs import ListUtilityCommand
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization.msgs import ListUtilityCommand
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IData
|
from awips.dataaccess import IData
|
||||||
import JUtil, DataTime
|
import JUtil, DataTime
|
||||||
|
|
||||||
class JData(IData, JUtil.JavaWrapperClass):
|
class JData(IData, JUtil.JavaWrapperClass):
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IDataRequest
|
from awips.dataaccess import IDataRequest
|
||||||
from com.raytheon.uf.common.dataplugin.level import Level
|
from com.raytheon.uf.common.dataplugin.level import Level
|
||||||
import JUtil
|
import JUtil
|
||||||
import jep
|
import jep
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IGeometryData
|
from awips.dataaccess import IGeometryData
|
||||||
import JData
|
import JData
|
||||||
|
|
||||||
class JGeometryData(IGeometryData, JData.JData):
|
class JGeometryData(IGeometryData, JData.JData):
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IGridData
|
from awips.dataaccess import IGridData
|
||||||
import JData
|
import JData
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
|
@ -1697,7 +1697,7 @@ def refresh_impl(args, dry_run=False, rsync_dry_run=False,
|
||||||
continue
|
continue
|
||||||
dst_path = join(path, 'passwords.properties')
|
dst_path = join(path, 'passwords.properties')
|
||||||
# need full python path since this is run as root, which doesn't have appropriate path vars set
|
# need full python path since this is run as root, which doesn't have appropriate path vars set
|
||||||
cmd = ['ssh', host, f"/awips2/python/bin/python -c \"from ufpy import ignite_password; ignite_password.updateIgnitePasswords('{keystore_password}', '{truststore_password}', '{dst_path}')\""]
|
cmd = ['ssh', host, f"/awips2/python/bin/python -c \"from awips import ignite_password; ignite_password.updateIgnitePasswords('{keystore_password}', '{truststore_password}', '{dst_path}')\""]
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
try:
|
try:
|
||||||
run(cmd, echo_stdout=verbose, echo_stderr_filtered=True)
|
run(cmd, echo_stdout=verbose, echo_stderr_filtered=True)
|
||||||
|
|
|
@ -111,7 +111,7 @@ if exportFileName is None:
|
||||||
if idx > -1:
|
if idx > -1:
|
||||||
exportFileName = exportFileName[0:idx]
|
exportFileName = exportFileName[0:idx]
|
||||||
|
|
||||||
from ufpy.ThriftClient import *
|
from awips.ThriftClient import *
|
||||||
client = ThriftClient(server)
|
client = ThriftClient(server)
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.pointdata.requests import *
|
from dynamicserialize.dstypes.com.raytheon.uf.common.pointdata.requests import *
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
from ufpy.localization.LocalizationFileManager import (LocalizationFileManager,
|
from awips.localization.LocalizationFileManager import (LocalizationFileManager,
|
||||||
NON_EXISTENT_CHECKSUM,
|
NON_EXISTENT_CHECKSUM,
|
||||||
LocalizationFileIsNotDirectoryException)
|
LocalizationFileIsNotDirectoryException)
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import sys
|
||||||
import xml.dom.minidom as minidom
|
import xml.dom.minidom as minidom
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
import netCDF4
|
import netCDF4
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ import numpy as np
|
||||||
from scipy import ndimage
|
from scipy import ndimage
|
||||||
import netCDF4
|
import netCDF4
|
||||||
|
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ import os
|
||||||
# local-delivery messages
|
# local-delivery messages
|
||||||
#
|
#
|
||||||
|
|
||||||
from ufpy import NotificationMessage
|
from awips import NotificationMessage
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print('')
|
print('')
|
||||||
|
|
|
@ -47,7 +47,7 @@ import traceback
|
||||||
# May 25, 2022 DR 23144 aghanava Modify workstation filter to use the short name.
|
# May 25, 2022 DR 23144 aghanava Modify workstation filter to use the short name.
|
||||||
#
|
#
|
||||||
|
|
||||||
from ufpy import NotificationMessage
|
from awips import NotificationMessage
|
||||||
|
|
||||||
class PrintHelpOnErrorParser(ArgumentParser):
|
class PrintHelpOnErrorParser(ArgumentParser):
|
||||||
def error(self, message):
|
def error(self, message):
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen.request import RetrieveActivityMapRequest
|
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen.request import RetrieveActivityMapRequest
|
||||||
|
|
||||||
class ActivityUtil:
|
class ActivityUtil:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import os
|
import os
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.datastorage.records import StringDataRecord
|
from dynamicserialize.dstypes.com.raytheon.uf.common.datastorage.records import StringDataRecord
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.datastorage.records import ByteDataRecord
|
from dynamicserialize.dstypes.com.raytheon.uf.common.datastorage.records import ByteDataRecord
|
||||||
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen.request import RetrieveAllProductsRequest
|
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen.request import RetrieveAllProductsRequest
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import os
|
import os
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
#from dynamicserialize.dstypes.com.raytheon.uf.common.datastorage.records import ByteDataRecord
|
#from dynamicserialize.dstypes.com.raytheon.uf.common.datastorage.records import ByteDataRecord
|
||||||
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen.request import StoreActivityRequest
|
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen.request import StoreActivityRequest
|
||||||
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen import ResponseMessageValidate
|
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen import ResponseMessageValidate
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
import logging
|
import logging
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
|
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
import ProductRetriever
|
import ProductRetriever
|
||||||
import ActivityUtil
|
import ActivityUtil
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import os
|
||||||
import logging
|
import logging
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen import ActivityInfo
|
from dynamicserialize.dstypes.gov.noaa.nws.ncep.common.dataplugin.pgen import ActivityInfo
|
||||||
import ProductStorer
|
import ProductStorer
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.grid.request import DeleteAllGridDataRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.grid.request import DeleteAllGridDataRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
logger = None
|
logger = None
|
||||||
def __initLogger():
|
def __initLogger():
|
||||||
|
|
|
@ -50,7 +50,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
from lib.Util import time_limit, TimeoutException
|
from lib.Util import time_limit, TimeoutException
|
||||||
|
|
||||||
from ufpy import qpidingest
|
from awips import qpidingest
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO, datefmt='%H:%M:%S',
|
logging.basicConfig(level=logging.INFO, datefmt='%H:%M:%S',
|
||||||
format="[%(process)s] %(asctime)s %(levelname)s: %(message)s")
|
format="[%(process)s] %(asctime)s %(levelname)s: %(message)s")
|
||||||
|
|
|
@ -27,7 +27,7 @@ import lib.Util as util
|
||||||
import conf.SMConfig as config
|
import conf.SMConfig as config
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import Message, Header
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import Message, Header
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.text.subscription.request import SubscriptionRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.text.subscription.request import SubscriptionRequest
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
|
@ -39,7 +39,7 @@ import subscription.SubscriptionManager as SM
|
||||||
import conf.TDBConfig as config
|
import conf.TDBConfig as config
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import Message, Header
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import Message, Header
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.text.dbsrv import TextDBRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.text.dbsrv import TextDBRequest
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import os
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ProcessReceivedConfRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ProcessReceivedConfRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
|
|
||||||
#
|
#
|
||||||
# TODO: ADD DESCRIPTION
|
# TODO: ADD DESCRIPTION
|
||||||
|
|
|
@ -25,7 +25,7 @@ import os
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ProcessReceivedDigitalDataRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ProcessReceivedDigitalDataRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
|
|
||||||
#
|
#
|
||||||
# TODO: ADD DESCRIPTION
|
# TODO: ADD DESCRIPTION
|
||||||
|
|
|
@ -24,7 +24,7 @@ import os
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import IscDataRecRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import IscDataRecRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
|
|
||||||
#
|
#
|
||||||
# CLI tool to process incoming ISC requests. Receives incoming request via MHS
|
# CLI tool to process incoming ISC requests. Receives incoming request via MHS
|
||||||
|
|
|
@ -42,7 +42,7 @@ import dynamicserialize
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.server.notify import *
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.server.notify import *
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import VTECTableChangeNotification
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import VTECTableChangeNotification
|
||||||
|
|
||||||
from ufpy import QpidSubscriber
|
from awips import QpidSubscriber
|
||||||
|
|
||||||
printoutMap = OrderedDict([
|
printoutMap = OrderedDict([
|
||||||
('L', 'LOCK'),
|
('L', 'LOCK'),
|
||||||
|
|
|
@ -9,8 +9,8 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import SendPracticeProductRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import SendPracticeProductRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import TimeUtil
|
from awips import TimeUtil
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
|
@ -45,9 +45,9 @@ import sys
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import MergeActiveTableRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import MergeActiveTableRequest
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import TimeUtil
|
from awips import TimeUtil
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
import getopt, sys
|
import getopt, sys
|
||||||
import logging, time, traceback, gzip
|
import logging, time, traceback, gzip
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import DumpActiveTableRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import DumpActiveTableRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
|
|
||||||
## sorting function
|
## sorting function
|
||||||
#def sortFunc(r1, r2):
|
#def sortFunc(r1, r2):
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import GetActiveTableDictRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import GetActiveTableDictRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from getVtecAttribute import getVtecAttribute
|
from getVtecAttribute import getVtecAttribute
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import GetFourCharSitesRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import GetFourCharSitesRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
|
|
||||||
##
|
##
|
||||||
# Convert a list with 3-char site IDs to a list of 4-char site IDs.
|
# Convert a list with 3-char site IDs to a list of 4-char site IDs.
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import GetVtecAttributeRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import GetVtecAttributeRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
|
|
||||||
##
|
##
|
||||||
# Ask the server for an attribute from the VTECPartners script for a site.
|
# Ask the server for an attribute from the VTECPartners script for a site.
|
||||||
|
|
|
@ -39,8 +39,8 @@ import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import MergeVTEC
|
import MergeVTEC
|
||||||
from ufpy import TimeUtil
|
from awips import TimeUtil
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ import sys
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import RetrieveRemoteActiveTableRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import RetrieveRemoteActiveTableRequest
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
||||||
|
|
|
@ -41,8 +41,8 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import SendActiveTableRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.activetable.request import SendActiveTableRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
||||||
|
|
|
@ -30,8 +30,8 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.server.reque
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
#
|
#
|
||||||
# Provides a command-line utility to break all locks.
|
# Provides a command-line utility to break all locks.
|
||||||
|
|
|
@ -32,9 +32,9 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request impo
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import SaveASCIIGridsRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import SaveASCIIGridsRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
|
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.localization import LocalizationUtil
|
from awips.localization import LocalizationUtil
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -24,8 +24,8 @@ import os
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import SmartInitRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import SmartInitRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -41,10 +41,10 @@ import sys
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExecuteIfpNetCDFGridRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExecuteIfpNetCDFGridRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
|
from awips.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
|
||||||
from ufpy.UsageArgumentParser import AppendParmNameAndLevelAction as AppendParmNameAndLevelAction
|
from awips.UsageArgumentParser import AppendParmNameAndLevelAction as AppendParmNameAndLevelAction
|
||||||
|
|
||||||
|
|
||||||
RETRY_ATTEMPTS = 3
|
RETRY_ATTEMPTS = 3
|
||||||
|
|
|
@ -38,9 +38,9 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.localization import Localiz
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationType
|
from dynamicserialize.dstypes.com.raytheon.uf.common.localization import LocalizationType
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy.localization import LocalizationUtil
|
from awips.localization import LocalizationUtil
|
||||||
from ufpy.localization.LocalizationFileManager import LocalizationFileVersionConflictException
|
from awips.localization.LocalizationFileManager import LocalizationFileVersionConflictException
|
||||||
|
|
||||||
#
|
#
|
||||||
# The ifpServerText program. Stores, deletes, gets, and inventories text.
|
# The ifpServerText program. Stores, deletes, gets, and inventories text.
|
||||||
|
|
|
@ -22,10 +22,10 @@ import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
|
from awips.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
|
||||||
from ufpy.UsageArgumentParser import AppendParmNameAndLevelAction as AppendParmNameAndLevelAction
|
from awips.UsageArgumentParser import AppendParmNameAndLevelAction as AppendParmNameAndLevelAction
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExecuteIscMosaicRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExecuteIscMosaicRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
|
|
|
@ -31,10 +31,10 @@ import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.localization import LocalizationUtil
|
from awips.localization import LocalizationUtil
|
||||||
from ufpy.localization.LocalizationFileManager import LocalizationFileVersionConflictException
|
from awips.localization.LocalizationFileManager import LocalizationFileVersionConflictException
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.gfe import IFPClient
|
from awips.gfe import IFPClient
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
|
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
|
||||||
|
|
|
@ -40,9 +40,9 @@ import sys
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import PurgeGfeGridsRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import PurgeGfeGridsRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
from ufpy.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
|
from awips.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import RsyncGridsToCWFRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import RsyncGridsToCWFRequest
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -40,8 +40,8 @@ import argparse
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExportGridsRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExportGridsRequest
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
class SendGridsToNDFD:
|
class SendGridsToNDFD:
|
||||||
|
|
|
@ -37,7 +37,7 @@ import traceback
|
||||||
import dynamicserialize
|
import dynamicserialize
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.notify import ClusterActivationNotification
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.notify import ClusterActivationNotification
|
||||||
|
|
||||||
from ufpy import QpidSubscriber
|
from awips import QpidSubscriber
|
||||||
|
|
||||||
class ActivationTopicListener(threading.Thread):
|
class ActivationTopicListener(threading.Thread):
|
||||||
def __init__(self, host='localHost', port='5762', topic="edex.alerts.siteActivate", program="siteActivation" ):
|
def __init__(self, host='localHost', port='5762', topic="edex.alerts.siteActivate", program="siteActivation" ):
|
||||||
|
|
|
@ -35,8 +35,8 @@ import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import ActivateSiteRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import ActivateSiteRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
from ActivationTopicListener import ActivationTopicListener
|
from ActivationTopicListener import ActivationTopicListener
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ import time
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import DeactivateSiteRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import DeactivateSiteRequest
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
from ActivationTopicListener import ActivationTopicListener
|
from ActivationTopicListener import ActivationTopicListener
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@ import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import ValidateConfigRequest
|
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import ValidateConfigRequest
|
||||||
from ufpy import ThriftClient
|
from awips import ThriftClient
|
||||||
from ufpy import UsageArgumentParser
|
from awips import UsageArgumentParser
|
||||||
|
|
||||||
|
|
||||||
def validate_args():
|
def validate_args():
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Pure python logging mechanism for logging to AlertViz from
|
|
||||||
# pure python (ie not JEP). DO NOT USE IN PYTHON CALLED
|
|
||||||
# FROM JAVA.
|
|
||||||
#
|
|
||||||
# Sends local-delivery messages only, but needs to know the EDEX host name in
|
|
||||||
# order to forward the message. If the DEFAULT_HOST environment variable is
|
|
||||||
# not set correctly then this will not work.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 08/18/10 njensen Initial Creation.
|
|
||||||
# Apr 16, 2020 8144 tgurney Reference AlertViz stomp port
|
|
||||||
# specified in NotificationMessage
|
|
||||||
# Aug 25, 2020 8220 tgurney Change local-delivery strategy
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
from . import NotificationMessage
|
|
||||||
import socket
|
|
||||||
|
|
||||||
class AlertVizHandler(logging.Handler):
|
|
||||||
|
|
||||||
def __init__(self, host=None, port=None,
|
|
||||||
category='LOCAL', source='ANNOUNCER', level=logging.NOTSET, filters=None):
|
|
||||||
logging.Handler.__init__(self, level)
|
|
||||||
if host is None:
|
|
||||||
host = os.getenv('DEFAULT_HOST', 'localhost')
|
|
||||||
if port is None:
|
|
||||||
port = os.getenv('DEFAULT_PORT', 9581)
|
|
||||||
self._category = category
|
|
||||||
self._host = host
|
|
||||||
self._port = port
|
|
||||||
self._source = source
|
|
||||||
self._filters = filters
|
|
||||||
filters['WORKSTATION'] = socket.getfqdn()
|
|
||||||
|
|
||||||
|
|
||||||
def emit(self, record):
|
|
||||||
"Implements logging.Handler's interface. Record argument is a logging.LogRecord."
|
|
||||||
priority = None
|
|
||||||
if record.levelno >= 50:
|
|
||||||
priority = 'CRITICAL'
|
|
||||||
elif record.levelno >= 40:
|
|
||||||
priority = 'SIGNIFICANT'
|
|
||||||
elif record.levelno >= 30:
|
|
||||||
priority = 'PROBLEM'
|
|
||||||
elif record.levelno >= 20:
|
|
||||||
priority = 'EVENTA'
|
|
||||||
elif record.levelno >= 10:
|
|
||||||
priority = 'EVENTB'
|
|
||||||
else:
|
|
||||||
priority = 'VERBOSE'
|
|
||||||
|
|
||||||
msg = self.format(record)
|
|
||||||
|
|
||||||
notify = NotificationMessage.NotificationMessage(self._host, self._port, msg, priority, self._category, self._source,
|
|
||||||
filters=self._filters)
|
|
||||||
notify.send()
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
#
|
|
||||||
# A set of utility functions for dealing with configuration files.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 09/27/10 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
def parseKeyValueFile(fileName):
|
|
||||||
propDict= dict()
|
|
||||||
|
|
||||||
try:
|
|
||||||
propFile= open(fileName, "rU")
|
|
||||||
for propLine in propFile:
|
|
||||||
propDef= propLine.strip()
|
|
||||||
if len(propDef) == 0:
|
|
||||||
continue
|
|
||||||
if propDef[0] in ( '#' ):
|
|
||||||
continue
|
|
||||||
punctuation= [ propDef.find(c) for c in ':= ' ] + [ len(propDef) ]
|
|
||||||
found= min( [ pos for pos in punctuation if pos != -1 ] )
|
|
||||||
name= propDef[:found].rstrip()
|
|
||||||
value= propDef[found:].lstrip(":= ").rstrip()
|
|
||||||
propDict[name]= value
|
|
||||||
propFile.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return propDict
|
|
|
@ -1,107 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Functions for converting between the various "Java" dynamic serialize types
|
|
||||||
# used by EDEX to the native python time datetime.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/24/15 #4480 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import time
|
|
||||||
|
|
||||||
from dynamicserialize.dstypes.java.util import Date
|
|
||||||
from dynamicserialize.dstypes.java.sql import Timestamp
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
|
|
||||||
|
|
||||||
|
|
||||||
MAX_TIME = pow(2, 31) - 1
|
|
||||||
MICROS_IN_SECOND = 1000000
|
|
||||||
|
|
||||||
|
|
||||||
def convertToDateTime(timeArg):
|
|
||||||
"""
|
|
||||||
Converts the given object to a python datetime object. Supports native
|
|
||||||
python representations like datetime and struct_time, but also
|
|
||||||
the dynamicserialize types like Date and Timestamp. Raises TypeError
|
|
||||||
if no conversion can be performed.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
timeArg: a python object representing a date and time. Supported
|
|
||||||
types include datetime, struct_time, float, int, long and the
|
|
||||||
dynamicserialize types Date and Timestamp.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A datetime that represents the same date/time as the passed in object.
|
|
||||||
"""
|
|
||||||
if isinstance(timeArg, datetime.datetime):
|
|
||||||
return timeArg
|
|
||||||
elif isinstance(timeArg, time.struct_time):
|
|
||||||
return datetime.datetime(*timeArg[:6])
|
|
||||||
elif isinstance(timeArg, float):
|
|
||||||
# seconds as float, should be avoided due to floating point errors
|
|
||||||
totalSecs = int(timeArg)
|
|
||||||
micros = int((timeArg - totalSecs) * MICROS_IN_SECOND)
|
|
||||||
return _convertSecsAndMicros(totalSecs, micros)
|
|
||||||
elif isinstance(timeArg, int):
|
|
||||||
# seconds as integer
|
|
||||||
totalSecs = timeArg
|
|
||||||
return _convertSecsAndMicros(totalSecs, 0)
|
|
||||||
elif isinstance(timeArg, (Date, Timestamp)):
|
|
||||||
totalSecs = timeArg.getTime()
|
|
||||||
return _convertSecsAndMicros(totalSecs, 0)
|
|
||||||
else:
|
|
||||||
objType = str(type(timeArg))
|
|
||||||
raise TypeError("Cannot convert object of type " + objType + " to datetime.")
|
|
||||||
|
|
||||||
def _convertSecsAndMicros(seconds, micros):
|
|
||||||
if seconds < MAX_TIME:
|
|
||||||
rval = datetime.datetime.utcfromtimestamp(seconds)
|
|
||||||
else:
|
|
||||||
extraTime = datetime.timedelta(seconds=(seconds - MAX_TIME))
|
|
||||||
rval = datetime.datetime.utcfromtimestamp(MAX_TIME) + extraTime
|
|
||||||
return rval.replace(microsecond=micros)
|
|
||||||
|
|
||||||
def constructTimeRange(*args):
|
|
||||||
"""
|
|
||||||
Builds a python dynamicserialize TimeRange object from the given
|
|
||||||
arguments.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args*: must be a TimeRange or a pair of objects that can be
|
|
||||||
converted to a datetime via convertToDateTime().
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A TimeRange.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if len(args) == 1 and isinstance(args[0], TimeRange):
|
|
||||||
return args[0]
|
|
||||||
if len(args) != 2:
|
|
||||||
raise TypeError("constructTimeRange takes exactly 2 arguments, " + str(len(args)) + " provided.")
|
|
||||||
startTime = convertToDateTime(args[0])
|
|
||||||
endTime = convertToDateTime(args[1])
|
|
||||||
return TimeRange(startTime, endTime)
|
|
|
@ -1,136 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from . import ThriftClient
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.alertviz import AlertVizRequest
|
|
||||||
|
|
||||||
#
|
|
||||||
# Provides a capability of constructing notification messages and sending
|
|
||||||
# them to a STOMP data source.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 09/30/08 chammack Initial Creation.
|
|
||||||
# 11/03/10 5849 cjeanbap Moved to ufpy package from
|
|
||||||
# com.raytheon.uf.tools.cli
|
|
||||||
# 01/07/11 5645 cjeanbap Added audio file to Status Message.
|
|
||||||
# 05/27/11 3050 cjeanbap Added if-statement to check Priority
|
|
||||||
# value
|
|
||||||
# 07/27/15 4654 skorolev Added filters
|
|
||||||
# 11/11/15 5120 rferrel Cannot serialize empty filters.
|
|
||||||
# 03/05/18 6899 dgilling Update to latest version of stomp.py API.
|
|
||||||
# 09/14/18 7464 dgilling Only serialize audioFile if provided.
|
|
||||||
# Apr 16, 2020 8144 tgurney Change AlertViz stomp port to
|
|
||||||
# calculated value based on uid
|
|
||||||
# May 15, 2020 8144 tgurney Remove local-delivery logic
|
|
||||||
# (no longer works as of 19.3.4)
|
|
||||||
|
|
||||||
class NotificationMessage:
|
|
||||||
|
|
||||||
priorityMap = {
|
|
||||||
0: 'CRITICAL',
|
|
||||||
1: 'SIGNIFICANT',
|
|
||||||
2: 'PROBLEM',
|
|
||||||
3: 'EVENTA',
|
|
||||||
4: 'EVENTB',
|
|
||||||
5: 'VERBOSE'}
|
|
||||||
|
|
||||||
def __init__(self, host='localhost', port=9581, message='', priority='PROBLEM', category="LOCAL", source="ANNOUNCER", audioFile=None, filters=None):
|
|
||||||
self.host = host
|
|
||||||
self.port = port
|
|
||||||
self.message = message
|
|
||||||
self.audioFile = audioFile
|
|
||||||
self.source = source
|
|
||||||
self.category = category
|
|
||||||
self.filters = filters
|
|
||||||
|
|
||||||
priorityInt = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
priorityInt = int(priority)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if priorityInt is None:
|
|
||||||
#UFStatus.java contains mapping of Priority to Logging level mapping
|
|
||||||
if priority == 'CRITICAL' or priority == 'FATAL':
|
|
||||||
priorityInt = int(0)
|
|
||||||
elif priority == 'SIGNIFICANT' or priority == 'ERROR':
|
|
||||||
priorityInt = int(1)
|
|
||||||
elif priority == 'PROBLEM' or priority == 'WARN':
|
|
||||||
priorityInt = int(2)
|
|
||||||
elif priority == 'EVENTA' or priority == 'INFO':
|
|
||||||
priorityInt = int(3)
|
|
||||||
elif priority == 'EVENTB':
|
|
||||||
priorityInt = int(4)
|
|
||||||
elif priority == 'VERBOSE' or priority == 'DEBUG':
|
|
||||||
priorityInt = int(5)
|
|
||||||
|
|
||||||
if (priorityInt < 0 or priorityInt > 5):
|
|
||||||
print("Error occurred, supplied an invalid Priority value:", str(priorityInt))
|
|
||||||
print("Priority values are 0, 1, 2, 3, 4 and 5.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if priorityInt is not None:
|
|
||||||
self.priority = self.priorityMap[priorityInt]
|
|
||||||
else:
|
|
||||||
self.priority = priority
|
|
||||||
|
|
||||||
def send(self):
|
|
||||||
alertVizRequest = createRequest(self.message, self.priority, self.source, self.category, self.audioFile, self.filters)
|
|
||||||
thriftClient = ThriftClient.ThriftClient(self.host, self.port, "/services")
|
|
||||||
|
|
||||||
serverResponse = None
|
|
||||||
try:
|
|
||||||
serverResponse = thriftClient.sendRequest(alertVizRequest)
|
|
||||||
except Exception as ex:
|
|
||||||
print("Caught exception submitting AlertVizRequest:", str(ex))
|
|
||||||
|
|
||||||
if (serverResponse != "None"):
|
|
||||||
print("Error occurred submitting Notification Message to AlertViz receiver:", serverResponse)
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
print("Response:", str(serverResponse))
|
|
||||||
|
|
||||||
def createRequest(message, priority, source, category, audioFile, filters):
|
|
||||||
obj = AlertVizRequest()
|
|
||||||
|
|
||||||
obj.setMachine(socket.gethostname())
|
|
||||||
obj.setPriority(priority)
|
|
||||||
obj.setCategory(category)
|
|
||||||
obj.setSourceKey(source)
|
|
||||||
obj.setMessage(message)
|
|
||||||
if (audioFile is not None):
|
|
||||||
obj.setAudioFile(audioFile)
|
|
||||||
else:
|
|
||||||
obj.setAudioFile('\0')
|
|
||||||
obj.setFilters(filters)
|
|
||||||
return obj
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,170 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
#
|
|
||||||
# Provides a Python-based interface for subscribing to qpid queues and topics.
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------- -------- ------------ --------------------------------------------
|
|
||||||
# Nov 17, 2010 njensen Initial Creation.
|
|
||||||
# Aug 15, 2013 2169 bkowal Optionally gzip decompress any data that is read.
|
|
||||||
# Aug 04, 2016 2416 tgurney Add queueStarted property
|
|
||||||
# Feb 16, 2017 6084 bsteffen Support ssl connections
|
|
||||||
# Sep 07, 2017 6175 tgurney Remove "decompressing" log message
|
|
||||||
# Jul 23, 2019 7724 mrichardson Upgrade Qpid to Qpid Proton
|
|
||||||
# Nov 04, 2019 7724 tgurney Fix topic creation
|
|
||||||
# Jun 24, 2020 8187 randerso Added qpid connection_id
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import pwd
|
|
||||||
import socket
|
|
||||||
import zlib
|
|
||||||
from ssl import SSLContext, PROTOCOL_TLS
|
|
||||||
|
|
||||||
from proton import SSLDomain
|
|
||||||
from proton.handlers import MessagingHandler
|
|
||||||
from proton.reactor import Container
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO, datefmt='%H:%M:%S',
|
|
||||||
format='[%(process)s] %(asctime)s %(levelname)s: %(message)s')
|
|
||||||
log = logging.getLogger('QpidSubscriber')
|
|
||||||
|
|
||||||
SSL_PASSWORD = 'password'
|
|
||||||
QPID_USERNAME = 'guest'
|
|
||||||
QPID_PASSWORD = 'guest'
|
|
||||||
|
|
||||||
class QpidSubscriber(MessagingHandler):
|
|
||||||
|
|
||||||
def __init__(self, host='127.0.0.1', port=5672, decompress=False, ssl=None, program="QpidSubscriber"):
|
|
||||||
super(QpidSubscriber, self).__init__(auto_accept=True)
|
|
||||||
#__init__ should only handle setting up properties;
|
|
||||||
# any connection and subscription actions should be handled
|
|
||||||
# by the reactor functions
|
|
||||||
|
|
||||||
self.queues = {}
|
|
||||||
|
|
||||||
self.scheme = 'amqp'
|
|
||||||
self.rest_scheme = 'https'
|
|
||||||
self.ssl_context = None
|
|
||||||
self.host = host
|
|
||||||
self.port = port
|
|
||||||
self.decompress = decompress
|
|
||||||
self.__queueStarted = False
|
|
||||||
self.__subscribed = False
|
|
||||||
|
|
||||||
pwuid = pwd.getpwuid(os.getuid())
|
|
||||||
if "QPID_SSL_CERT_DB" in os.environ:
|
|
||||||
certdbloc = os.environ["QPID_SSL_CERT_DB"]
|
|
||||||
else:
|
|
||||||
certdbloc = pwuid.pw_dir + "/.qpid/"
|
|
||||||
if "QPID_SSL_CERT_NAME" in os.environ:
|
|
||||||
certname = os.environ["QPID_SSL_CERT_NAME"]
|
|
||||||
else:
|
|
||||||
certname = QPID_USERNAME
|
|
||||||
|
|
||||||
certfile = os.path.join(certdbloc, certname + ".crt")
|
|
||||||
certkey = os.path.join(certdbloc, certname + ".key")
|
|
||||||
if ssl or (ssl is None and os.path.isfile(certfile) and os.path.isfile(certkey)):
|
|
||||||
self.scheme = "amqps"
|
|
||||||
self.rest_scheme = 'https'
|
|
||||||
self.ssl_context = SSLContext(PROTOCOL_TLS)
|
|
||||||
self.ssl_context.load_cert_chain(certfile, certkey)
|
|
||||||
self.cert_file = certfile
|
|
||||||
self.cert_key = certkey
|
|
||||||
self.url = '{}://{}:{}@{}:{}'.format(self.scheme, QPID_USERNAME, QPID_PASSWORD, self.host, self.port)
|
|
||||||
self.clientID = ":".join([
|
|
||||||
socket.gethostname(),
|
|
||||||
pwuid.pw_name,
|
|
||||||
program,
|
|
||||||
str(os.getpid()),
|
|
||||||
])
|
|
||||||
|
|
||||||
def topicSubscribe(self, topicName, callback):
|
|
||||||
self.topicName = topicName
|
|
||||||
self.callback = callback
|
|
||||||
Container(self).run()
|
|
||||||
|
|
||||||
def on_start(self, event):
|
|
||||||
'''
|
|
||||||
# if the queue is edex.alerts, set decompress to true always for now to
|
|
||||||
# maintain compatibility with existing python scripts.
|
|
||||||
'''
|
|
||||||
if self.topicName == 'edex.alerts':
|
|
||||||
self.decompress = True
|
|
||||||
|
|
||||||
self.container = event.container
|
|
||||||
queueName = 'amq.topic/' + self.topicName
|
|
||||||
|
|
||||||
self.ssl_domain = None
|
|
||||||
if self.scheme == "amqps" and self.cert_file and self.cert_key:
|
|
||||||
self.ssl_domain = SSLDomain(mode=SSLDomain.MODE_CLIENT)
|
|
||||||
self.ssl_domain.set_credentials(self.cert_file, self.cert_key, SSL_PASSWORD)
|
|
||||||
|
|
||||||
event.container.container_id = self.clientID
|
|
||||||
self.conn = event.container.connect(self.url, ssl_domain=self.ssl_domain)
|
|
||||||
self.receiver = event.container.create_receiver(self.conn, queueName)
|
|
||||||
self.__queueStarted = True
|
|
||||||
self.__subscribed = True
|
|
||||||
|
|
||||||
def on_message(self, event):
|
|
||||||
message = event.message
|
|
||||||
content = message.body
|
|
||||||
self.process_message(content)
|
|
||||||
if not self.__subscribed:
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def process_message(self, content):
|
|
||||||
if (self.decompress):
|
|
||||||
try:
|
|
||||||
# http://stackoverflow.com/questions/2423866/python-decompressing-gzip-chunk-by-chunk
|
|
||||||
d = zlib.decompressobj(16 + zlib.MAX_WBITS)
|
|
||||||
content = d.decompress(content)
|
|
||||||
except Exception:
|
|
||||||
# decompression failed, return the original content
|
|
||||||
pass
|
|
||||||
self.callback(content)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.__queueStarted = False
|
|
||||||
self.unsubscribe()
|
|
||||||
try:
|
|
||||||
self.receiver.close()
|
|
||||||
self.conn.close()
|
|
||||||
except:
|
|
||||||
# already closed
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
def queueStarted(self):
|
|
||||||
return self.__queueStarted
|
|
||||||
|
|
||||||
@property
|
|
||||||
def subscribed(self):
|
|
||||||
return self.__subscribed
|
|
||||||
|
|
||||||
def unsubscribe(self):
|
|
||||||
self.__subscribed = False
|
|
|
@ -1,102 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
import http.client
|
|
||||||
|
|
||||||
from dynamicserialize import DynamicSerializationManager
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Provides a Python-based interface for executing Thrift requests.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 09/20/10 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
class ThriftClient:
|
|
||||||
|
|
||||||
# How to call this constructor:
|
|
||||||
# 1. Pass in all arguments separately (e.g.,
|
|
||||||
# ThriftClient.ThriftClient("localhost", 9581, "/services"))
|
|
||||||
# will return a Thrift client pointed at http://localhost:9581/services.
|
|
||||||
# 2. Pass in all arguments through the host string (e.g.,
|
|
||||||
# ThriftClient.ThriftClient("localhost:9581/services"))
|
|
||||||
# will return a Thrift client pointed at http://localhost:9581/services.
|
|
||||||
# 3. Pass in host/port arguments through the host string (e.g.,
|
|
||||||
# ThriftClient.ThriftClient("localhost:9581", "/services"))
|
|
||||||
# will return a Thrift client pointed at http://localhost:9581/services.
|
|
||||||
def __init__(self, host, port=9581, uri="/services"):
|
|
||||||
hostParts = host.split("/", 1)
|
|
||||||
if (len(hostParts) > 1):
|
|
||||||
hostString = hostParts[0]
|
|
||||||
self.__uri = "/" + hostParts[1]
|
|
||||||
self.__httpConn = http.client.HTTPConnection(hostString)
|
|
||||||
else:
|
|
||||||
if (port is None):
|
|
||||||
self.__httpConn = http.client.HTTPConnection(host)
|
|
||||||
else:
|
|
||||||
self.__httpConn = http.client.HTTPConnection(host, port)
|
|
||||||
|
|
||||||
self.__uri = uri
|
|
||||||
|
|
||||||
self.__dsm = DynamicSerializationManager.DynamicSerializationManager()
|
|
||||||
|
|
||||||
def sendRequest(self, request, uri="/thrift"):
|
|
||||||
message = self.__dsm.serializeObject(request)
|
|
||||||
|
|
||||||
self.__httpConn.connect()
|
|
||||||
self.__httpConn.request("POST", self.__uri + uri, message)
|
|
||||||
|
|
||||||
response = self.__httpConn.getresponse()
|
|
||||||
if (response.status != 200):
|
|
||||||
raise ThriftRequestException("Unable to post request to server")
|
|
||||||
|
|
||||||
rval = self.__dsm.deserializeBytes(response.read())
|
|
||||||
self.__httpConn.close()
|
|
||||||
|
|
||||||
# let's verify we have an instance of ServerErrorResponse
|
|
||||||
# IF we do, through an exception up to the caller along
|
|
||||||
# with the original Java stack trace
|
|
||||||
# ELSE: we have a valid response and pass it back
|
|
||||||
try:
|
|
||||||
forceError = rval.getException()
|
|
||||||
raise ThriftRequestException(forceError)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return rval
|
|
||||||
|
|
||||||
|
|
||||||
class ThriftRequestException(Exception):
|
|
||||||
def __init__(self, value):
|
|
||||||
self.parameter = value
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return repr(self.parameter)
|
|
||||||
|
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
# This software is in the public domain, furnished "as is", without technical
|
|
||||||
# support, and with no warranty, express or implied, as to its usefulness for
|
|
||||||
# any purpose.
|
|
||||||
#
|
|
||||||
# offsetTime.py
|
|
||||||
# Handles Displaced Real Time for various applications
|
|
||||||
#
|
|
||||||
# Author: hansen/romberg
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
# Given the timeStr, return the offset (in seconds)
|
|
||||||
# from the current time.
|
|
||||||
# Also return the launchStr i.e. Programs launched from this
|
|
||||||
# offset application will use the launchStr as the -z argument.
|
|
||||||
# The offset will be positive for time in the future,
|
|
||||||
# negative for time in the past.
|
|
||||||
#
|
|
||||||
# May still want it to be normalized to the most recent midnight.
|
|
||||||
#
|
|
||||||
# NOTES about synchronizing:
|
|
||||||
# --With synchronizing on, the "current time" for all processes started
|
|
||||||
# within a given hour will be the same.
|
|
||||||
# This guarantees that GFE's have the same current time and ISC grid
|
|
||||||
# time stamps are syncrhonized and can be exchanged.
|
|
||||||
# Formatters launched from the GFE in this mode will be synchronized as
|
|
||||||
# well by setting the launchStr to use the time difference format
|
|
||||||
# (YYYYMMDD_HHMM,YYYYMMDD_HHMM).
|
|
||||||
# --This does not solve the problem in the general case.
|
|
||||||
# For example, if someone starts the GFE at 12:59 and someone
|
|
||||||
# else starts it at 1:01, they will have different offsets and
|
|
||||||
# current times.
|
|
||||||
# --With synchronizing off, when the process starts, the current time
|
|
||||||
# matches the drtTime in the command line. However, with synchronizing
|
|
||||||
# on, the current time will be offset by the fraction of the hour at
|
|
||||||
# which the process was started. Examples:
|
|
||||||
# Actual Starting time: 20040617_1230
|
|
||||||
# drtTime 20040616_0000
|
|
||||||
# Synchronizing off:
|
|
||||||
# GFE Spatial Editor at StartUp: 20040616_0000
|
|
||||||
# Synchronizing on:
|
|
||||||
# GFE Spatial Editor at StartUp: 20040616_0030
|
|
||||||
#
|
|
||||||
def determineDrtOffset(timeStr):
|
|
||||||
launchStr = timeStr
|
|
||||||
# Check for time difference
|
|
||||||
if timeStr.find(",") >=0:
|
|
||||||
times = timeStr.split(",")
|
|
||||||
t1 = makeTime(times[0])
|
|
||||||
t2 = makeTime(times[1])
|
|
||||||
#print "time offset", t1-t2, (t1-t2)/3600
|
|
||||||
return t1-t2, launchStr
|
|
||||||
# Check for synchronized mode
|
|
||||||
synch = 0
|
|
||||||
if timeStr[0] == "S":
|
|
||||||
timeStr = timeStr[1:]
|
|
||||||
synch = 1
|
|
||||||
drt_t = makeTime(timeStr)
|
|
||||||
#print "input", year, month, day, hour, minute
|
|
||||||
gm = time.gmtime()
|
|
||||||
cur_t = time.mktime(gm)
|
|
||||||
|
|
||||||
# Synchronize to most recent hour
|
|
||||||
# i.e. "truncate" cur_t to most recent hour.
|
|
||||||
#print "gmtime", gm
|
|
||||||
if synch:
|
|
||||||
cur_t = time.mktime((gm[0], gm[1], gm[2], gm[3], 0, 0, 0, 0, 0))
|
|
||||||
curStr = time.strftime('%Y%m%d_%H00\n', gm)
|
|
||||||
launchStr = timeStr + "," + curStr
|
|
||||||
|
|
||||||
#print "drt, cur", drt_t, cur_t
|
|
||||||
offset = drt_t - cur_t
|
|
||||||
#print "offset", offset, offset/3600, launchStr
|
|
||||||
return int(offset), launchStr
|
|
||||||
|
|
||||||
def makeTime(timeStr):
|
|
||||||
year = int(timeStr[0:4])
|
|
||||||
month = int(timeStr[4:6])
|
|
||||||
day = int(timeStr[6:8])
|
|
||||||
hour = int(timeStr[9:11])
|
|
||||||
minute = int(timeStr[11:13])
|
|
||||||
# Do not use daylight savings because gmtime is not in daylight
|
|
||||||
# savings time.
|
|
||||||
return time.mktime((year, month, day, hour, minute, 0, 0, 0, 0))
|
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------- -------- --------- ---------------------------------------------
|
|
||||||
# Feb 13, 2017 6092 randerso Added StoreTimeAction
|
|
||||||
#
|
|
||||||
##
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import ParmID
|
|
||||||
|
|
||||||
TIME_FORMAT = "%Y%m%d_%H%M"
|
|
||||||
|
|
||||||
class UsageArgumentParser(argparse.ArgumentParser):
|
|
||||||
"""
|
|
||||||
A subclass of ArgumentParser that overrides error() to print the
|
|
||||||
whole help text, rather than just the usage string.
|
|
||||||
"""
|
|
||||||
def error(self, message):
|
|
||||||
sys.stderr.write('%s: error: %s\n' % (self.prog, message))
|
|
||||||
self.print_help()
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
## Custom actions for ArgumentParser objects ##
|
|
||||||
class StoreDatabaseIDAction(argparse.Action):
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
|
||||||
did = DatabaseID(values)
|
|
||||||
if did.isValid():
|
|
||||||
setattr(namespace, self.dest, did)
|
|
||||||
else:
|
|
||||||
parser.error("DatabaseID [" + values + "] not a valid identifier")
|
|
||||||
|
|
||||||
class AppendParmNameAndLevelAction(argparse.Action):
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
|
||||||
tx = ParmID.parmNameAndLevel(values)
|
|
||||||
comp = tx[0] + '_' + tx[1]
|
|
||||||
if (hasattr(namespace, self.dest)) and \
|
|
||||||
(getattr(namespace, self.dest) is not None):
|
|
||||||
currentValues = getattr(namespace, self.dest)
|
|
||||||
currentValues.append(comp)
|
|
||||||
setattr(namespace, self.dest, currentValues)
|
|
||||||
else:
|
|
||||||
setattr(namespace, self.dest, [comp])
|
|
||||||
|
|
||||||
class StoreTimeAction(argparse.Action):
|
|
||||||
"""
|
|
||||||
argparse.Action subclass to validate GFE formatted time strings
|
|
||||||
and parse them to time.struct_time
|
|
||||||
"""
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
|
||||||
try:
|
|
||||||
timeStruct = time.strptime(values, TIME_FORMAT)
|
|
||||||
except:
|
|
||||||
parser.error(str(values) + " is not a valid time string of the format YYYYMMDD_hhmm")
|
|
||||||
|
|
||||||
setattr(namespace, self.dest, timeStruct)
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from optparse import OptionParser
|
|
||||||
|
|
||||||
class UsageOptionParser(OptionParser):
|
|
||||||
"""
|
|
||||||
A subclass of OptionParser that prints that overrides error() to print the
|
|
||||||
whole help text, rather than just the usage string.
|
|
||||||
"""
|
|
||||||
def error(self, msg):
|
|
||||||
"""
|
|
||||||
Print the help text and exit.
|
|
||||||
"""
|
|
||||||
self.print_help(sys.stderr)
|
|
||||||
sys.stderr.write("\n")
|
|
||||||
sys.stderr.write(msg)
|
|
||||||
sys.stderr.write("\n")
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# __init__.py for ufpy package
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 09/21/10 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
]
|
|
|
@ -1,100 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Method for performing a DAF time query where all parameter/level/location
|
|
||||||
# combinations must be available at the same time.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/22/16 #5591 bsteffen Initial Creation.
|
|
||||||
#
|
|
||||||
|
|
||||||
from ufpy.dataaccess import DataAccessLayer
|
|
||||||
|
|
||||||
def getAvailableTimes(request, refTimeOnly=False):
|
|
||||||
return __getAvailableTimesForEachParameter(request, refTimeOnly)
|
|
||||||
|
|
||||||
def __getAvailableTimesForEachParameter(request, refTimeOnly=False):
|
|
||||||
parameters = request.getParameters()
|
|
||||||
if parameters:
|
|
||||||
times = None
|
|
||||||
for parameter in parameters:
|
|
||||||
specificRequest = __cloneRequest(request)
|
|
||||||
specificRequest.setParameters(parameter)
|
|
||||||
specificTimes = __getAvailableTimesForEachLevel(specificRequest, refTimeOnly)
|
|
||||||
if times is None:
|
|
||||||
times = specificTimes
|
|
||||||
else:
|
|
||||||
times.intersection_update(specificTimes)
|
|
||||||
if not times:
|
|
||||||
break
|
|
||||||
return times
|
|
||||||
else:
|
|
||||||
return __getAvailableTimesForEachLevel(request, refTimeOnly)
|
|
||||||
|
|
||||||
def __getAvailableTimesForEachLevel(request, refTimeOnly=False):
|
|
||||||
levels = request.getLevels()
|
|
||||||
if levels:
|
|
||||||
times = None
|
|
||||||
for level in levels:
|
|
||||||
specificRequest = __cloneRequest(request)
|
|
||||||
specificRequest.setLevels(level)
|
|
||||||
specificTimes = __getAvailableTimesForEachLocation(specificRequest, refTimeOnly)
|
|
||||||
if times is None:
|
|
||||||
times = specificTimes
|
|
||||||
else:
|
|
||||||
times.intersection_update(specificTimes)
|
|
||||||
if not times:
|
|
||||||
break
|
|
||||||
return times
|
|
||||||
else:
|
|
||||||
return __getAvailableTimesForEachLocation(request, refTimeOnly)
|
|
||||||
|
|
||||||
def __getAvailableTimesForEachLocation(request, refTimeOnly=False):
|
|
||||||
locations = request.getLocationNames()
|
|
||||||
if locations:
|
|
||||||
times = None
|
|
||||||
for location in locations:
|
|
||||||
specificRequest = __cloneRequest(request)
|
|
||||||
specificRequest.setLocationNames(location)
|
|
||||||
specificTimes = DataAccessLayer.getAvailableTimes(specificRequest, refTimeOnly)
|
|
||||||
if times is None:
|
|
||||||
times = set(specificTimes)
|
|
||||||
else:
|
|
||||||
times.intersection_update(specificTimes)
|
|
||||||
if not times:
|
|
||||||
break
|
|
||||||
return times
|
|
||||||
else:
|
|
||||||
return DataAccessLayer.getAvailableTimes(request, refTimeOnly)
|
|
||||||
|
|
||||||
|
|
||||||
def __cloneRequest(request):
|
|
||||||
return DataAccessLayer.newDataRequest(datatype = request.getDatatype(),
|
|
||||||
parameters = request.getParameters(),
|
|
||||||
levels = request.getLevels(),
|
|
||||||
locationNames = request.getLocationNames(),
|
|
||||||
envelope = request.getEnvelope(),
|
|
||||||
**request.getIdentifiers())
|
|
|
@ -1,276 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Published interface for ufpy.dataaccess package
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 12/10/12 njensen Initial Creation.
|
|
||||||
# Feb 14, 2013 1614 bsteffen refactor data access framework
|
|
||||||
# to use single request.
|
|
||||||
# 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args
|
|
||||||
# 05/29/13 2023 dgilling Hook up ThriftClientRouter.
|
|
||||||
# 03/03/14 2673 bsteffen Add ability to query only ref times.
|
|
||||||
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
|
|
||||||
# 07/30/14 3185 njensen Renamed valid identifiers to optional
|
|
||||||
# Apr 26, 2015 4259 njensen Updated for new JEP API
|
|
||||||
# Apr 13, 2016 5379 tgurney Add getIdentifierValues()
|
|
||||||
# Jun 01, 2016 5587 tgurney Add new signatures for
|
|
||||||
# getRequiredIdentifiers() and
|
|
||||||
# getOptionalIdentifiers()
|
|
||||||
# Oct 18, 2016 5916 bsteffen Add setLazyLoadGridLatLon
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
THRIFT_HOST = subprocess.check_output(
|
|
||||||
"source /awips2/fxa/bin/setup.env; echo $DEFAULT_HOST",
|
|
||||||
shell=True).decode().strip()
|
|
||||||
|
|
||||||
|
|
||||||
USING_NATIVE_THRIFT = False
|
|
||||||
|
|
||||||
|
|
||||||
if 'jep' in sys.modules:
|
|
||||||
# intentionally do not catch if this fails to import, we want it to
|
|
||||||
# be obvious that something is configured wrong when running from within
|
|
||||||
# Java instead of allowing false confidence and fallback behavior
|
|
||||||
import JepRouter
|
|
||||||
router = JepRouter
|
|
||||||
else:
|
|
||||||
from ufpy.dataaccess import ThriftClientRouter
|
|
||||||
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
|
|
||||||
USING_NATIVE_THRIFT = True
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getAvailableTimes(request, refTimeOnly=False):
|
|
||||||
"""
|
|
||||||
Get the times of available data to the request.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the IDataRequest to get data for
|
|
||||||
refTimeOnly: optional, use True if only unique refTimes should be
|
|
||||||
returned (without a forecastHr)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of DataTimes
|
|
||||||
"""
|
|
||||||
return router.getAvailableTimes(request, refTimeOnly)
|
|
||||||
|
|
||||||
|
|
||||||
def getGridData(request, times=[]):
|
|
||||||
"""
|
|
||||||
Gets the grid data that matches the request at the specified times. Each
|
|
||||||
combination of parameter, level, and dataTime will be returned as a
|
|
||||||
separate IGridData.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the IDataRequest to get data for
|
|
||||||
times: a list of DataTimes, a TimeRange, or None if the data is time
|
|
||||||
agnostic
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of IGridData
|
|
||||||
"""
|
|
||||||
return router.getGridData(request, times)
|
|
||||||
|
|
||||||
|
|
||||||
def getGeometryData(request, times=[]):
|
|
||||||
"""
|
|
||||||
Gets the geometry data that matches the request at the specified times.
|
|
||||||
Each combination of geometry, level, and dataTime will be returned as a
|
|
||||||
separate IGeometryData.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the IDataRequest to get data for
|
|
||||||
times: a list of DataTimes, a TimeRange, or None if the data is time
|
|
||||||
agnostic
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of IGeometryData
|
|
||||||
"""
|
|
||||||
return router.getGeometryData(request, times)
|
|
||||||
|
|
||||||
|
|
||||||
def getAvailableLocationNames(request):
|
|
||||||
"""
|
|
||||||
Gets the available location names that match the request without actually
|
|
||||||
requesting the data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the request to find matching location names for
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of available location names.
|
|
||||||
"""
|
|
||||||
return router.getAvailableLocationNames(request)
|
|
||||||
|
|
||||||
|
|
||||||
def getAvailableParameters(request):
|
|
||||||
"""
|
|
||||||
Gets the available parameters names that match the request without actually
|
|
||||||
requesting the data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the request to find matching parameter names for
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of available parameter names.
|
|
||||||
"""
|
|
||||||
return router.getAvailableParameters(request)
|
|
||||||
|
|
||||||
|
|
||||||
def getAvailableLevels(request):
|
|
||||||
"""
|
|
||||||
Gets the available levels that match the request without actually
|
|
||||||
requesting the data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the request to find matching levels for
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of available levels.
|
|
||||||
"""
|
|
||||||
return router.getAvailableLevels(request)
|
|
||||||
|
|
||||||
|
|
||||||
def getRequiredIdentifiers(request):
|
|
||||||
"""
|
|
||||||
Gets the required identifiers for this request. These identifiers
|
|
||||||
must be set on a request for the request of this datatype to succeed.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the request to find required identifiers for
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of required identifiers
|
|
||||||
"""
|
|
||||||
if str(request) == request:
|
|
||||||
warnings.warn("Use getRequiredIdentifiers(IDataRequest) instead",
|
|
||||||
DeprecationWarning)
|
|
||||||
return router.getRequiredIdentifiers(request)
|
|
||||||
|
|
||||||
|
|
||||||
def getOptionalIdentifiers(request):
|
|
||||||
"""
|
|
||||||
Gets the optional identifiers for this request.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the request to find optional identifiers for
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of optional identifiers
|
|
||||||
"""
|
|
||||||
if str(request) == request:
|
|
||||||
warnings.warn("Use getOptionalIdentifiers(IDataRequest) instead",
|
|
||||||
DeprecationWarning)
|
|
||||||
return router.getOptionalIdentifiers(request)
|
|
||||||
|
|
||||||
|
|
||||||
def getIdentifierValues(request, identifierKey):
|
|
||||||
"""
|
|
||||||
Gets the allowed values for a particular identifier on this datatype.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the request to find identifier values for
|
|
||||||
identifierKey: the identifier to find values for
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of allowed values for the specified identifier
|
|
||||||
"""
|
|
||||||
return router.getIdentifierValues(request, identifierKey)
|
|
||||||
|
|
||||||
def newDataRequest(datatype=None, **kwargs):
|
|
||||||
""""
|
|
||||||
Creates a new instance of IDataRequest suitable for the runtime environment.
|
|
||||||
All args are optional and exist solely for convenience.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
datatype: the datatype to create a request for
|
|
||||||
parameters: a list of parameters to set on the request
|
|
||||||
levels: a list of levels to set on the request
|
|
||||||
locationNames: a list of locationNames to set on the request
|
|
||||||
envelope: an envelope to limit the request
|
|
||||||
**kwargs: any leftover kwargs will be set as identifiers
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a new IDataRequest
|
|
||||||
"""
|
|
||||||
return router.newDataRequest(datatype, **kwargs)
|
|
||||||
|
|
||||||
def getSupportedDatatypes():
|
|
||||||
"""
|
|
||||||
Gets the datatypes that are supported by the framework
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of supported datatypes
|
|
||||||
"""
|
|
||||||
return router.getSupportedDatatypes()
|
|
||||||
|
|
||||||
|
|
||||||
def changeEDEXHost(newHostName):
|
|
||||||
"""
|
|
||||||
Changes the EDEX host the Data Access Framework is communicating with. Only
|
|
||||||
works if using the native Python client implementation, otherwise, this
|
|
||||||
method will throw a TypeError.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
newHostHame: the EDEX host to connect to
|
|
||||||
"""
|
|
||||||
if USING_NATIVE_THRIFT:
|
|
||||||
global THRIFT_HOST
|
|
||||||
THRIFT_HOST = newHostName
|
|
||||||
global router
|
|
||||||
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
|
|
||||||
else:
|
|
||||||
raise TypeError("Cannot call changeEDEXHost when using JepRouter.")
|
|
||||||
|
|
||||||
def setLazyLoadGridLatLon(lazyLoadGridLatLon):
|
|
||||||
"""
|
|
||||||
Provide a hint to the Data Access Framework indicating whether to load the
|
|
||||||
lat/lon data for a grid immediately or wait until it is needed. This is
|
|
||||||
provided as a performance tuning hint and should not affect the way the
|
|
||||||
Data Access Framework is used. Depending on the internal implementation of
|
|
||||||
the Data Access Framework this hint might be ignored. Examples of when this
|
|
||||||
should be set to True are when the lat/lon information is not used or when
|
|
||||||
it is used only if certain conditions within the data are met. It could be
|
|
||||||
set to False if it is guaranteed that all lat/lon information is needed and
|
|
||||||
it would be better to get any performance overhead for generating the
|
|
||||||
lat/lon data out of the way during the initial request.
|
|
||||||
|
|
||||||
|
|
||||||
Args:
|
|
||||||
lazyLoadGridLatLon: Boolean value indicating whether to lazy load.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
router.setLazyLoadGridLatLon(lazyLoadGridLatLon)
|
|
||||||
except AttributeError:
|
|
||||||
# The router is not required to support this capability.
|
|
||||||
pass
|
|
|
@ -1,154 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Published interface for retrieving data updates via ufpy.dataaccess package
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------- -------- ------------ --------------------------------------------
|
|
||||||
# May 26, 2016 2416 rjpeter Initial Creation.
|
|
||||||
# Aug 01, 2016 2416 tgurney Finish implementation
|
|
||||||
# Nov 05, 2019 7884 tgurney Python 3 fixes
|
|
||||||
# Jun 24, 2020 8187 randerso Added program for qpid connection_id
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
|
||||||
Interface for the DAF's data notification feature, which allows continuous
|
|
||||||
retrieval of new data as it is coming into the system.
|
|
||||||
|
|
||||||
There are two ways to access this feature:
|
|
||||||
|
|
||||||
1. The DataQueue module (ufpy.dataaccess.DataQueue) offers a collection that
|
|
||||||
automatically fills up with new data as it receives notifications. See that
|
|
||||||
module for more information.
|
|
||||||
|
|
||||||
2. Depending on the type of data you want, use either getGridDataUpdates() or
|
|
||||||
getGeometryDataUpdates() in this module. Either one will give you back an
|
|
||||||
object that will retrieve new data for you and will call a function you specify
|
|
||||||
each time new data is received.
|
|
||||||
|
|
||||||
Example code follows. This example prints temperature as observed from KOMA
|
|
||||||
each time a METAR is received from there.
|
|
||||||
|
|
||||||
from ufpy.dataaccess import DataAccessLayer as DAL
|
|
||||||
from ufpy.dataaccess import DataNotificationLayer as DNL
|
|
||||||
|
|
||||||
def process_obs(list_of_data):
|
|
||||||
for item in list_of_data:
|
|
||||||
print(item.getNumber('temperature'))
|
|
||||||
|
|
||||||
request = DAL.newDataRequest('obs')
|
|
||||||
request.setParameters('temperature')
|
|
||||||
request.setLocationNames('KOMA')
|
|
||||||
|
|
||||||
notifier = DNL.getGeometryDataUpdates(request)
|
|
||||||
notifier.subscribe(process_obs)
|
|
||||||
# process_obs will called with a list of data each time new data comes in
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
from ufpy.dataaccess.PyGeometryNotification import PyGeometryNotification
|
|
||||||
from ufpy.dataaccess.PyGridNotification import PyGridNotification
|
|
||||||
|
|
||||||
|
|
||||||
THRIFT_HOST = subprocess.check_output(
|
|
||||||
"source /awips2/fxa/bin/setup.env; echo $DEFAULT_HOST",
|
|
||||||
shell=True).decode().strip()
|
|
||||||
|
|
||||||
USING_NATIVE_THRIFT = False
|
|
||||||
|
|
||||||
if 'jep' in sys.modules:
|
|
||||||
# intentionally do not catch if this fails to import, we want it to
|
|
||||||
# be obvious that something is configured wrong when running from within
|
|
||||||
# Java instead of allowing false confidence and fallback behavior
|
|
||||||
import JepRouter
|
|
||||||
router = JepRouter
|
|
||||||
else:
|
|
||||||
from ufpy.dataaccess import ThriftClientRouter
|
|
||||||
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
|
|
||||||
USING_NATIVE_THRIFT = True
|
|
||||||
|
|
||||||
|
|
||||||
def _getJmsConnectionInfo(notifFilterResponse):
|
|
||||||
serverString = notifFilterResponse.getJmsConnectionInfo()
|
|
||||||
try:
|
|
||||||
host, port = serverString.split(':')
|
|
||||||
except Exception as e:
|
|
||||||
raise ValueError('Got bad JMS connection info from server: "' + serverString + '"') from e
|
|
||||||
return {'host': host, 'port': port}
|
|
||||||
|
|
||||||
|
|
||||||
def getGridDataUpdates(request):
|
|
||||||
"""
|
|
||||||
Get a notification object that receives updates to grid data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the IDataRequest specifying the data you want to receive
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
an update request object that you can listen for updates to by
|
|
||||||
calling its subscribe() method
|
|
||||||
"""
|
|
||||||
response = router.getNotificationFilter(request)
|
|
||||||
filter = response.getNotificationFilter()
|
|
||||||
jmsInfo = _getJmsConnectionInfo(response)
|
|
||||||
notifier = PyGridNotification(request, filter, requestHost=THRIFT_HOST, program="daf-gridDataUpdates", **jmsInfo)
|
|
||||||
return notifier
|
|
||||||
|
|
||||||
|
|
||||||
def getGeometryDataUpdates(request):
|
|
||||||
"""
|
|
||||||
Get a notification object that receives updates to geometry data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: the IDataRequest specifying the data you want to receive
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
an update request object that you can listen for updates to by
|
|
||||||
calling its subscribe() method
|
|
||||||
"""
|
|
||||||
response = router.getNotificationFilter(request)
|
|
||||||
filter = response.getNotificationFilter()
|
|
||||||
jmsInfo = _getJmsConnectionInfo(response)
|
|
||||||
notifier = PyGeometryNotification(request, filter, requestHost=THRIFT_HOST, program="daf-geometryDataUpdates", **jmsInfo)
|
|
||||||
return notifier
|
|
||||||
|
|
||||||
|
|
||||||
def changeEDEXHost(newHostName):
|
|
||||||
"""
|
|
||||||
Changes the EDEX host the Data Access Framework is communicating with. Only
|
|
||||||
works if using the native Python client implementation, otherwise, this
|
|
||||||
method will throw a TypeError.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
newHostHame: the EDEX host to connect to
|
|
||||||
"""
|
|
||||||
if USING_NATIVE_THRIFT:
|
|
||||||
global THRIFT_HOST
|
|
||||||
THRIFT_HOST = newHostName
|
|
||||||
global router
|
|
||||||
router = ThriftClientRouter.ThriftClientRouter(THRIFT_HOST)
|
|
||||||
else:
|
|
||||||
raise TypeError("Cannot call changeEDEXHost when using JepRouter.")
|
|
|
@ -1,209 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Convenience class for using the DAF's notifications feature. This is a
|
|
||||||
# collection that, once connected to EDEX by calling start(), fills with
|
|
||||||
# data as notifications come in. Runs on a separate thread to allow
|
|
||||||
# non-blocking data retrieval.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 07/29/16 2416 tgurney Initial creation
|
|
||||||
#
|
|
||||||
|
|
||||||
from ufpy.dataaccess import DataNotificationLayer as DNL
|
|
||||||
|
|
||||||
import time
|
|
||||||
from threading import Thread
|
|
||||||
|
|
||||||
|
|
||||||
from queue import Queue, Empty
|
|
||||||
|
|
||||||
|
|
||||||
"""Used to indicate a DataQueue that will produce geometry data."""
|
|
||||||
GEOMETRY = object()
|
|
||||||
|
|
||||||
|
|
||||||
"""Used to indicate a DataQueue that will produce grid data."""
|
|
||||||
GRID = object()
|
|
||||||
|
|
||||||
|
|
||||||
"""Default maximum queue size."""
|
|
||||||
_DEFAULT_MAXSIZE = 100
|
|
||||||
|
|
||||||
|
|
||||||
class Closed(Exception):
|
|
||||||
"""Raised when attempting to get data from a closed queue."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DataQueue(object):
|
|
||||||
|
|
||||||
"""
|
|
||||||
Convenience class for using the DAF's notifications feature. This is a
|
|
||||||
collection that, once connected to EDEX by calling start(), fills with
|
|
||||||
data as notifications come in.
|
|
||||||
|
|
||||||
Example for getting obs data:
|
|
||||||
|
|
||||||
from DataQueue import DataQueue, GEOMETRY
|
|
||||||
request = DataAccessLayer.newDataRequest('obs')
|
|
||||||
request.setParameters('temperature')
|
|
||||||
request.setLocationNames('KOMA')
|
|
||||||
q = DataQueue(GEOMETRY, request)
|
|
||||||
q.start()
|
|
||||||
for item in q:
|
|
||||||
print(item.getNumber('temperature'))
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, dtype, request, maxsize=_DEFAULT_MAXSIZE):
|
|
||||||
"""
|
|
||||||
Create a new DataQueue.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
dtype: Either GRID or GEOMETRY; must match the type of data
|
|
||||||
requested.
|
|
||||||
request: IDataRequest describing the data you want. It must at
|
|
||||||
least have datatype set. All data produced will satisfy the
|
|
||||||
constraints you specify.
|
|
||||||
maxsize: Maximum number of data objects the queue can hold at
|
|
||||||
one time. If the limit is reached, any data coming in after
|
|
||||||
that will not appear until one or more items are removed using
|
|
||||||
DataQueue.get().
|
|
||||||
"""
|
|
||||||
assert maxsize > 0
|
|
||||||
assert dtype in (GEOMETRY, GRID)
|
|
||||||
self._maxsize = maxsize
|
|
||||||
self._queue = Queue(maxsize=maxsize)
|
|
||||||
self._thread = None
|
|
||||||
if dtype is GEOMETRY:
|
|
||||||
self._notifier = DNL.getGeometryDataUpdates(request)
|
|
||||||
elif dtype is GRID:
|
|
||||||
self._notifier = DNL.getGridDataUpdates(request)
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""Start listening for notifications and requesting data."""
|
|
||||||
if self._thread is not None:
|
|
||||||
# Already started
|
|
||||||
return
|
|
||||||
kwargs = {'callback': self._data_received}
|
|
||||||
self._thread = Thread(target=self._notifier.subscribe, kwargs=kwargs)
|
|
||||||
self._thread.daemon = True
|
|
||||||
self._thread.start()
|
|
||||||
timer = 0
|
|
||||||
while not self._notifier.subscribed:
|
|
||||||
time.sleep(0.1)
|
|
||||||
timer += 1
|
|
||||||
if timer >= 100: # ten seconds
|
|
||||||
raise RuntimeError('timed out when attempting to subscribe')
|
|
||||||
|
|
||||||
def _data_received(self, data):
|
|
||||||
for d in data:
|
|
||||||
if not isinstance(d, list):
|
|
||||||
d = [d]
|
|
||||||
for item in d:
|
|
||||||
self._queue.put(item)
|
|
||||||
|
|
||||||
def get(self, block=True, timeout=None):
|
|
||||||
"""
|
|
||||||
Get and return the next available data object. By default, if there is
|
|
||||||
no data yet available, this method will not return until data becomes
|
|
||||||
available.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
block: Specifies behavior when the queue is empty. If True, wait
|
|
||||||
until an item is available before returning (the default). If
|
|
||||||
False, return None immediately if the queue is empty.
|
|
||||||
timeout: If block is True, wait this many seconds, and return None
|
|
||||||
if data is not received in that time.
|
|
||||||
Returns:
|
|
||||||
IData
|
|
||||||
"""
|
|
||||||
if self.closed:
|
|
||||||
raise Closed
|
|
||||||
try:
|
|
||||||
return self._queue.get(block, timeout)
|
|
||||||
except Empty:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_all(self):
|
|
||||||
"""
|
|
||||||
Get all data waiting for processing, in a single list. Always returns
|
|
||||||
immediately. Returns an empty list if no data has arrived yet.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List of IData
|
|
||||||
"""
|
|
||||||
data = []
|
|
||||||
for _ in range(self._maxsize):
|
|
||||||
next_item = self.get(False)
|
|
||||||
if next_item is None:
|
|
||||||
break
|
|
||||||
data.append(next_item)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
"""Close the queue. May not be re-opened after closing."""
|
|
||||||
if not self.closed:
|
|
||||||
self._notifier.close()
|
|
||||||
self._thread.join()
|
|
||||||
|
|
||||||
def qsize(self):
|
|
||||||
"""Return number of items in the queue."""
|
|
||||||
return self._queue.qsize()
|
|
||||||
|
|
||||||
def empty(self):
|
|
||||||
"""Return True if the queue is empty."""
|
|
||||||
return self._queue.empty()
|
|
||||||
|
|
||||||
def full(self):
|
|
||||||
"""Return True if the queue is full."""
|
|
||||||
return self._queue.full()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def closed(self):
|
|
||||||
"""True if the queue has been closed."""
|
|
||||||
return not self._notifier.subscribed
|
|
||||||
|
|
||||||
@property
|
|
||||||
def maxsize(self):
|
|
||||||
"""
|
|
||||||
Maximum number of data objects the queue can hold at one time.
|
|
||||||
If this limit is reached, any data coming in after that will not appear
|
|
||||||
until one or more items are removed using get().
|
|
||||||
"""
|
|
||||||
return self._maxsize
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
if self._thread is not None:
|
|
||||||
while not self.closed:
|
|
||||||
yield self.get()
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
self.start()
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, *unused):
|
|
||||||
self.close()
|
|
|
@ -1,57 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
#
|
|
||||||
# Implements IData for use by native Python clients to the Data Access
|
|
||||||
# Framework.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/03/13 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IData
|
|
||||||
|
|
||||||
class PyData(IData):
|
|
||||||
|
|
||||||
def __init__(self, dataRecord):
|
|
||||||
self.__time = dataRecord.getTime()
|
|
||||||
self.__level = dataRecord.getLevel()
|
|
||||||
self.__locationName = dataRecord.getLocationName()
|
|
||||||
self.__attributes = dataRecord.getAttributes()
|
|
||||||
|
|
||||||
def getAttribute(self, key):
|
|
||||||
return self.__attributes[key]
|
|
||||||
|
|
||||||
def getAttributes(self):
|
|
||||||
return list(self.__attributes.keys())
|
|
||||||
|
|
||||||
def getDataTime(self):
|
|
||||||
return self.__time
|
|
||||||
|
|
||||||
def getLevel(self):
|
|
||||||
return self.__level
|
|
||||||
|
|
||||||
def getLocationName(self):
|
|
||||||
return self.__locationName
|
|
|
@ -1,76 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
#
|
|
||||||
# Implements IGeometryData for use by native Python clients to the Data Access
|
|
||||||
# Framework.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/03/13 dgilling Initial Creation.
|
|
||||||
# 01/06/14 2537 bsteffen Share geometry WKT.
|
|
||||||
# 03/19/14 2882 dgilling Raise an exception when getNumber()
|
|
||||||
# is called for data that is not a
|
|
||||||
# numeric Type.
|
|
||||||
# 06/09/16 5574 mapeters Handle 'SHORT' type in getNumber().
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IGeometryData
|
|
||||||
from ufpy.dataaccess import PyData
|
|
||||||
|
|
||||||
class PyGeometryData(IGeometryData, PyData.PyData):
|
|
||||||
|
|
||||||
def __init__(self, geoDataRecord, geometry):
|
|
||||||
PyData.PyData.__init__(self, geoDataRecord)
|
|
||||||
self.__geometry = geometry
|
|
||||||
self.__dataMap = {}
|
|
||||||
tempDataMap = geoDataRecord.getDataMap()
|
|
||||||
for key, value in tempDataMap.items():
|
|
||||||
self.__dataMap[key] = (value[0], value[1], value[2])
|
|
||||||
|
|
||||||
def getGeometry(self):
|
|
||||||
return self.__geometry
|
|
||||||
|
|
||||||
def getParameters(self):
|
|
||||||
return list(self.__dataMap.keys())
|
|
||||||
|
|
||||||
def getString(self, param):
|
|
||||||
value = self.__dataMap[param][0]
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
def getNumber(self, param):
|
|
||||||
value = self.__dataMap[param][0]
|
|
||||||
t = self.getType(param)
|
|
||||||
if t in ('INT', 'SHORT', 'LONG'):
|
|
||||||
return int(value)
|
|
||||||
elif t in ('DOUBLE', 'FLOAT'):
|
|
||||||
return float(value)
|
|
||||||
else:
|
|
||||||
raise TypeError("Data for parameter " + param + " is not a numeric type.")
|
|
||||||
|
|
||||||
def getUnit(self, param):
|
|
||||||
return self.__dataMap[param][2]
|
|
||||||
|
|
||||||
def getType(self, param):
|
|
||||||
return self.__dataMap[param][1]
|
|
|
@ -1,55 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Notification object that produces geometry data
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 07/22/2016 2416 tgurney Initial creation
|
|
||||||
# 09/07/2017 6175 tgurney Override messageReceived
|
|
||||||
# 11/05/2019 7884 tgurney Add missing import
|
|
||||||
#
|
|
||||||
|
|
||||||
import dynamicserialize
|
|
||||||
import traceback
|
|
||||||
from ufpy.dataaccess.PyNotification import PyNotification
|
|
||||||
|
|
||||||
class PyGeometryNotification(PyNotification):
|
|
||||||
|
|
||||||
def messageReceived(self, msg):
|
|
||||||
dataUriMsg = dynamicserialize.deserialize(msg)
|
|
||||||
dataUris = dataUriMsg.getDataURIs()
|
|
||||||
dataTimes = set()
|
|
||||||
for dataUri in dataUris:
|
|
||||||
if self.notificationFilter.accept(dataUri):
|
|
||||||
dataTimes.add(self.getDataTime(dataUri))
|
|
||||||
if dataTimes:
|
|
||||||
try:
|
|
||||||
data = self.getData(self.request, list(dataTimes))
|
|
||||||
self.callback(data)
|
|
||||||
except Exception as e:
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
def getData(self, request, dataTimes):
|
|
||||||
return self.DAL.getGeometryData(request, dataTimes)
|
|
|
@ -1,81 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Implements IGridData for use by native Python clients to the Data Access
|
|
||||||
# Framework.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/03/13 #2023 dgilling Initial Creation.
|
|
||||||
# 10/13/16 #5916 bsteffen Correct grid shape, allow lat/lon
|
|
||||||
# 11/10/16 #5900 bsteffen Correct grid shape
|
|
||||||
# to be requested by a delegate
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
import numpy
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from ufpy.dataaccess import IGridData
|
|
||||||
from ufpy.dataaccess import PyData
|
|
||||||
|
|
||||||
NO_UNIT_CONVERT_WARNING = """
|
|
||||||
The ability to unit convert grid data is not currently available in this version of the Data Access Framework.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class PyGridData(IGridData, PyData.PyData):
|
|
||||||
|
|
||||||
def __init__(self, gridDataRecord, nx, ny, latLonGrid = None, latLonDelegate = None):
|
|
||||||
PyData.PyData.__init__(self, gridDataRecord)
|
|
||||||
nx = nx
|
|
||||||
ny = ny
|
|
||||||
self.__parameter = gridDataRecord.getParameter()
|
|
||||||
self.__unit = gridDataRecord.getUnit()
|
|
||||||
self.__gridData = numpy.reshape(numpy.array(gridDataRecord.getGridData()), (ny, nx))
|
|
||||||
self.__latLonGrid = latLonGrid
|
|
||||||
self.__latLonDelegate = latLonDelegate
|
|
||||||
|
|
||||||
|
|
||||||
def getParameter(self):
|
|
||||||
return self.__parameter
|
|
||||||
|
|
||||||
def getUnit(self):
|
|
||||||
return self.__unit
|
|
||||||
|
|
||||||
def getRawData(self, unit=None):
|
|
||||||
# TODO: Find a proper python library that deals will with numpy and
|
|
||||||
# javax.measure style unit strings and hook it in to this method to
|
|
||||||
# allow end-users to perform unit conversion for grid data.
|
|
||||||
if unit is not None:
|
|
||||||
warnings.warn(NO_UNIT_CONVERT_WARNING, stacklevel=2)
|
|
||||||
return self.__gridData
|
|
||||||
|
|
||||||
def getLatLonCoords(self):
|
|
||||||
if self.__latLonGrid is not None:
|
|
||||||
return self.__latLonGrid
|
|
||||||
elif self.__latLonDelegate is not None:
|
|
||||||
return self.__latLonDelegate()
|
|
||||||
return self.__latLonGrid
|
|
|
@ -1,60 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Notification object that produces grid data
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/03/2016 2416 rjpeter Initial Creation.
|
|
||||||
# 09/06/2017 6175 tgurney Override messageReceived
|
|
||||||
# 11/05/2019 7884 tgurney Add missing import
|
|
||||||
#
|
|
||||||
|
|
||||||
import dynamicserialize
|
|
||||||
import traceback
|
|
||||||
from ufpy.dataaccess.PyNotification import PyNotification
|
|
||||||
|
|
||||||
class PyGridNotification(PyNotification):
|
|
||||||
|
|
||||||
def messageReceived(self, msg):
|
|
||||||
dataUriMsg = dynamicserialize.deserialize(msg)
|
|
||||||
dataUris = dataUriMsg.getDataURIs()
|
|
||||||
for dataUri in dataUris:
|
|
||||||
if not self.notificationFilter.accept(dataUri):
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
# This improves performance over requesting by datatime since it requests only the
|
|
||||||
# parameter that the notification was received for (instead of this and all previous
|
|
||||||
# parameters for the same forecast hour)
|
|
||||||
# TODO: This utterly fails for derived requests
|
|
||||||
newReq = self.DAL.newDataRequest(self.request.getDatatype())
|
|
||||||
newReq.addIdentifier("dataURI", dataUri)
|
|
||||||
newReq.setParameters(self.request.getParameters())
|
|
||||||
data = self.getData(newReq, [])
|
|
||||||
self.callback(data)
|
|
||||||
except Exception as e:
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
def getData(self, request, dataTimes):
|
|
||||||
return self.DAL.getGridData(request, dataTimes)
|
|
|
@ -1,110 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
#
|
|
||||||
# Implements IData for use by native Python clients to the Data Access
|
|
||||||
# Framework.
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------- -------- ------------ --------------------------------------------
|
|
||||||
# Jun 22, 2016 2416 rjpeter Initial creation
|
|
||||||
# Jul 22, 2016 2416 tgurney Finish implementation
|
|
||||||
# Sep 07, 2017 6175 tgurney Override messageReceived in subclasses
|
|
||||||
# Nov 05, 2019 7884 tgurney Fix in subscribed()
|
|
||||||
# Jun 24, 2020 8187 randerso Added program for qpid connection_id
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
import abc
|
|
||||||
|
|
||||||
from ufpy.dataaccess import DataAccessLayer
|
|
||||||
from ufpy.dataaccess import INotificationSubscriber
|
|
||||||
from ufpy.QpidSubscriber import QpidSubscriber
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.time import DataTime
|
|
||||||
|
|
||||||
|
|
||||||
class PyNotification(INotificationSubscriber, metaclass=abc.ABCMeta):
|
|
||||||
"""
|
|
||||||
Receives notifications for new data and retrieves the data that meets
|
|
||||||
specified filtering criteria.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, request, filter, host='localhost', port=5672, requestHost='localhost', program="PyNotification"):
|
|
||||||
self.DAL = DataAccessLayer
|
|
||||||
self.DAL.changeEDEXHost(requestHost)
|
|
||||||
self.request = request
|
|
||||||
self.notificationFilter = filter
|
|
||||||
self.host = host
|
|
||||||
self.port = port
|
|
||||||
self.program=program
|
|
||||||
self.__topicName = "edex.alerts"
|
|
||||||
self.callback = None
|
|
||||||
|
|
||||||
def subscribe(self, callback):
|
|
||||||
"""
|
|
||||||
Start listening for notifications.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
callback: Function to call with a list of received data objects.
|
|
||||||
Will be called once for each request made for data.
|
|
||||||
"""
|
|
||||||
assert hasattr(callback, '__call__'), 'callback arg must be callable'
|
|
||||||
self.callback = callback
|
|
||||||
self.qs = QpidSubscriber(host=self.host, port=self.port, decompress=True, program=self.program)
|
|
||||||
self.qs.topicSubscribe(self.__topicName, self.messageReceived)
|
|
||||||
# Blocks here
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.qs.close()
|
|
||||||
|
|
||||||
def getDataTime(self, dataURI):
|
|
||||||
dataTimeStr = dataURI.split('/')[2]
|
|
||||||
return DataTime(dataTimeStr)
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def messageReceived(self, msg):
|
|
||||||
"""Called when a message is received from QpidSubscriber.
|
|
||||||
|
|
||||||
This method must call self.callback once for each request made for data
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getData(self, request, dataTimes):
|
|
||||||
"""
|
|
||||||
Retrieve and return data
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: IDataRequest to send to the server
|
|
||||||
dataTimes: list of data times
|
|
||||||
Returns:
|
|
||||||
list of IData
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
def subscribed(self):
|
|
||||||
"""True if currently subscribed to notifications."""
|
|
||||||
try:
|
|
||||||
return self.qs.queueStarted
|
|
||||||
except AttributeError:
|
|
||||||
return False
|
|
|
@ -1,283 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Classes for retrieving soundings based on gridded data from the Data Access
|
|
||||||
# Framework
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 06/24/15 #4480 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
|
|
||||||
from collections import defaultdict
|
|
||||||
from shapely.geometry import Point
|
|
||||||
|
|
||||||
from ufpy import DateTimeConverter
|
|
||||||
from ufpy.dataaccess import DataAccessLayer
|
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.time import DataTime
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.level import Level
|
|
||||||
|
|
||||||
|
|
||||||
def getSounding(modelName, weatherElements, levels, samplePoint, refTime=None, timeRange=None):
|
|
||||||
""""
|
|
||||||
Performs a series of Data Access Framework requests to retrieve a sounding object
|
|
||||||
based on the specified request parameters.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
modelName: the grid model datasetid to use as the basis of the sounding.
|
|
||||||
weatherElements: a list of parameters to return in the sounding.
|
|
||||||
levels: a list of levels to sample the given weather elements at
|
|
||||||
samplePoint: a lat/lon pair to perform the sampling of data at.
|
|
||||||
refTime: (optional) the grid model reference time to use for the sounding.
|
|
||||||
If not specified, the latest ref time in the system will be used.
|
|
||||||
timeRange: (optional) a TimeRange to specify which forecast hours to use.
|
|
||||||
If not specified, will default to all forecast hours.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A _SoundingCube instance, which acts a 3-tiered dictionary, keyed
|
|
||||||
by DataTime, then by level and finally by weather element. If no
|
|
||||||
data is available for the given request parameters, None is returned.
|
|
||||||
"""
|
|
||||||
|
|
||||||
(locationNames, parameters, levels, envelope, refTime, timeRange) = \
|
|
||||||
__sanitizeInputs(modelName, weatherElements, levels, samplePoint, refTime, timeRange)
|
|
||||||
|
|
||||||
requestArgs = { 'datatype' : 'grid',
|
|
||||||
'locationNames' : locationNames,
|
|
||||||
'parameters' : parameters,
|
|
||||||
'levels' : levels,
|
|
||||||
'envelope' : envelope,
|
|
||||||
}
|
|
||||||
|
|
||||||
req = DataAccessLayer.newDataRequest(**requestArgs)
|
|
||||||
|
|
||||||
forecastHours = __determineForecastHours(req, refTime, timeRange)
|
|
||||||
if not forecastHours:
|
|
||||||
return None
|
|
||||||
|
|
||||||
response = DataAccessLayer.getGeometryData(req, forecastHours)
|
|
||||||
soundingObject = _SoundingCube(response)
|
|
||||||
|
|
||||||
return soundingObject
|
|
||||||
|
|
||||||
def setEDEXHost(host):
|
|
||||||
"""
|
|
||||||
Changes the EDEX host the Data Access Framework is communicating with.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
host: the EDEX host to connect to
|
|
||||||
"""
|
|
||||||
|
|
||||||
if host:
|
|
||||||
DataAccessLayer.changeEDEXHost(str(host))
|
|
||||||
|
|
||||||
def __sanitizeInputs(modelName, weatherElements, levels, samplePoint, refTime, timeRange):
|
|
||||||
locationNames = [str(modelName)]
|
|
||||||
parameters = __buildStringList(weatherElements)
|
|
||||||
levels = __buildStringList(levels)
|
|
||||||
envelope = Point(samplePoint)
|
|
||||||
if refTime is not None:
|
|
||||||
refTime = DataTime(refTime=DateTimeConverter.convertToDateTime(refTime))
|
|
||||||
if timeRange is not None:
|
|
||||||
timeRange = DateTimeConverter.constructTimeRange(*timeRange)
|
|
||||||
return (locationNames, parameters, levels, envelope, refTime, timeRange)
|
|
||||||
|
|
||||||
def __determineForecastHours(request, refTime, timeRange):
|
|
||||||
dataTimes = DataAccessLayer.getAvailableTimes(request, False)
|
|
||||||
timesGen = [(DataTime(refTime=dataTime.getRefTime()), dataTime) for dataTime in dataTimes]
|
|
||||||
dataTimesMap = defaultdict(list)
|
|
||||||
for baseTime, dataTime in timesGen:
|
|
||||||
dataTimesMap[baseTime].append(dataTime)
|
|
||||||
|
|
||||||
if refTime is None:
|
|
||||||
refTime = max(dataTimesMap.keys())
|
|
||||||
|
|
||||||
forecastHours = dataTimesMap[refTime]
|
|
||||||
if timeRange is None:
|
|
||||||
return forecastHours
|
|
||||||
else:
|
|
||||||
return [forecastHour for forecastHour in forecastHours if timeRange.contains(forecastHour.getValidPeriod())]
|
|
||||||
|
|
||||||
def __buildStringList(param):
|
|
||||||
if __notStringIter(param):
|
|
||||||
return [str(item) for item in param]
|
|
||||||
else:
|
|
||||||
return [str(param)]
|
|
||||||
|
|
||||||
def __notStringIter(iterable):
|
|
||||||
if not isinstance(iterable, str):
|
|
||||||
try:
|
|
||||||
iter(iterable)
|
|
||||||
return True
|
|
||||||
except TypeError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _SoundingCube(object):
|
|
||||||
"""
|
|
||||||
The top-level sounding object returned when calling SoundingsSupport.getSounding.
|
|
||||||
|
|
||||||
This object acts as a 3-tiered dict which is keyed by time then level
|
|
||||||
then parameter name. Calling times() will return all valid keys into this
|
|
||||||
object.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, geometryDataObjects):
|
|
||||||
self._dataDict = {}
|
|
||||||
self._sortedTimes = []
|
|
||||||
if geometryDataObjects:
|
|
||||||
for geometryData in geometryDataObjects:
|
|
||||||
dataTime = geometryData.getDataTime()
|
|
||||||
level = geometryData.getLevel()
|
|
||||||
for parameter in geometryData.getParameters():
|
|
||||||
self.__addItem(parameter, dataTime, level, geometryData.getNumber(parameter))
|
|
||||||
|
|
||||||
def __addItem(self, parameter, dataTime, level, value):
|
|
||||||
timeLayer = self._dataDict.get(dataTime, _SoundingTimeLayer(dataTime))
|
|
||||||
self._dataDict[dataTime] = timeLayer
|
|
||||||
timeLayer._addItem(parameter, level, value)
|
|
||||||
if dataTime not in self._sortedTimes:
|
|
||||||
self._sortedTimes.append(dataTime)
|
|
||||||
self._sortedTimes.sort()
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return self._dataDict[key]
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._dataDict)
|
|
||||||
|
|
||||||
def times(self):
|
|
||||||
"""
|
|
||||||
Returns the valid times for this sounding.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list containing the valid DataTimes for this sounding in order.
|
|
||||||
"""
|
|
||||||
return self._sortedTimes
|
|
||||||
|
|
||||||
|
|
||||||
class _SoundingTimeLayer(object):
|
|
||||||
"""
|
|
||||||
The second-level sounding object returned when calling SoundingsSupport.getSounding.
|
|
||||||
|
|
||||||
This object acts as a 2-tiered dict which is keyed by level then parameter
|
|
||||||
name. Calling levels() will return all valid keys into this
|
|
||||||
object. Calling time() will return the DataTime for this particular layer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, dataTime):
|
|
||||||
self._dataTime = dataTime
|
|
||||||
self._dataDict = {}
|
|
||||||
|
|
||||||
def _addItem(self, parameter, level, value):
|
|
||||||
asString = str(level)
|
|
||||||
levelLayer = self._dataDict.get(asString, _SoundingTimeAndLevelLayer(self._dataTime, asString))
|
|
||||||
levelLayer._addItem(parameter, value)
|
|
||||||
self._dataDict[asString] = levelLayer
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
asString = str(key)
|
|
||||||
if asString in self._dataDict:
|
|
||||||
return self._dataDict[asString]
|
|
||||||
else:
|
|
||||||
raise KeyError("Level " + str(key) + " is not a valid level for this sounding.")
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._dataDict)
|
|
||||||
|
|
||||||
def time(self):
|
|
||||||
"""
|
|
||||||
Returns the DataTime for this sounding cube layer.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The DataTime for this sounding layer.
|
|
||||||
"""
|
|
||||||
return self._dataTime
|
|
||||||
|
|
||||||
def levels(self):
|
|
||||||
"""
|
|
||||||
Returns the valid levels for this sounding.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list containing the valid levels for this sounding in order of
|
|
||||||
closest to surface to highest from surface.
|
|
||||||
"""
|
|
||||||
sortedLevels = [Level(level) for level in list(self._dataDict.keys())]
|
|
||||||
sortedLevels.sort()
|
|
||||||
return [str(level) for level in sortedLevels]
|
|
||||||
|
|
||||||
|
|
||||||
class _SoundingTimeAndLevelLayer(object):
|
|
||||||
"""
|
|
||||||
The bottom-level sounding object returned when calling SoundingsSupport.getSounding.
|
|
||||||
|
|
||||||
This object acts as a dict which is keyed by parameter name. Calling
|
|
||||||
parameters() will return all valid keys into this object. Calling time()
|
|
||||||
will return the DataTime for this particular layer. Calling level() will
|
|
||||||
return the level for this layer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, time, level):
|
|
||||||
self._time = time
|
|
||||||
self._level = level
|
|
||||||
self._parameters = {}
|
|
||||||
|
|
||||||
def _addItem(self, parameter, value):
|
|
||||||
self._parameters[parameter] = value
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return self._parameters[key]
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._parameters)
|
|
||||||
|
|
||||||
def level(self):
|
|
||||||
"""
|
|
||||||
Returns the level for this sounding cube layer.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The level for this sounding layer.
|
|
||||||
"""
|
|
||||||
return self._level
|
|
||||||
|
|
||||||
def parameters(self):
|
|
||||||
"""
|
|
||||||
Returns the valid parameters for this sounding.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list containing the valid parameter names.
|
|
||||||
"""
|
|
||||||
return list(self._parameters.keys())
|
|
||||||
|
|
||||||
def time(self):
|
|
||||||
"""
|
|
||||||
Returns the DataTime for this sounding cube layer.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The DataTime for this sounding layer.
|
|
||||||
"""
|
|
||||||
return self._time
|
|
|
@ -1,247 +0,0 @@
|
||||||
# #
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
# #
|
|
||||||
|
|
||||||
#
|
|
||||||
# Routes requests to the Data Access Framework through Python Thrift.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 05/21/13 2023 dgilling Initial Creation.
|
|
||||||
# 01/06/14 2537 bsteffen Share geometry WKT.
|
|
||||||
# 03/03/14 2673 bsteffen Add ability to query only ref times.
|
|
||||||
# 07/22/14 3185 njensen Added optional/default args to newDataRequest
|
|
||||||
# 07/23/14 3185 njensen Added new methods
|
|
||||||
# 07/30/14 3185 njensen Renamed valid identifiers to optional
|
|
||||||
# 06/30/15 4569 nabowle Use hex WKB for geometries.
|
|
||||||
# 04/13/15 5379 tgurney Add getIdentifierValues()
|
|
||||||
# 06/01/16 5587 tgurney Add new signatures for
|
|
||||||
# getRequiredIdentifiers() and
|
|
||||||
# getOptionalIdentifiers()
|
|
||||||
# 08/01/16 2416 tgurney Add getNotificationFilter()
|
|
||||||
# 10/13/16 5916 bsteffen Correct grid shape, allow lazy grid lat/lon
|
|
||||||
# 10/26/16 5919 njensen Speed up geometry creation in getGeometryData()
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
import numpy
|
|
||||||
import shapely.wkb
|
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.impl import DefaultDataRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableLocationNamesRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableTimesRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetGeometryDataRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetGridDataRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetGridLatLonRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableParametersRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableLevelsRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetRequiredIdentifiersRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetOptionalIdentifiersRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetIdentifierValuesRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetSupportedDatatypesRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetNotificationFilterRequest
|
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
|
||||||
from ufpy.dataaccess import PyGeometryData
|
|
||||||
from ufpy.dataaccess import PyGridData
|
|
||||||
|
|
||||||
|
|
||||||
class LazyGridLatLon(object):
|
|
||||||
|
|
||||||
def __init__(self, client, nx, ny, envelope, crsWkt):
|
|
||||||
self._latLonGrid = None
|
|
||||||
self._client = client
|
|
||||||
self._request = GetGridLatLonRequest()
|
|
||||||
self._request.setNx(nx)
|
|
||||||
self._request.setNy(ny)
|
|
||||||
self._request.setEnvelope(envelope)
|
|
||||||
self._request.setCrsWkt(crsWkt)
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
# Its important that the data is cached internally so that if multiple
|
|
||||||
# GridData are sharing the same delegate then they can also share a
|
|
||||||
# single request for the LatLon information.
|
|
||||||
if self._latLonGrid is None:
|
|
||||||
response = self._client.sendRequest(self._request)
|
|
||||||
nx = response.getNx()
|
|
||||||
ny = response.getNy()
|
|
||||||
latData = numpy.reshape(numpy.array(response.getLats()), (ny, nx))
|
|
||||||
lonData = numpy.reshape(numpy.array(response.getLons()), (ny, nx))
|
|
||||||
self._latLonGrid = (lonData, latData)
|
|
||||||
return self._latLonGrid
|
|
||||||
|
|
||||||
|
|
||||||
class ThriftClientRouter(object):
|
|
||||||
|
|
||||||
def __init__(self, host='localhost'):
|
|
||||||
self._client = ThriftClient.ThriftClient(host)
|
|
||||||
self._lazyLoadGridLatLon = False
|
|
||||||
|
|
||||||
def setLazyLoadGridLatLon(self, lazyLoadGridLatLon):
|
|
||||||
self._lazyLoadGridLatLon = lazyLoadGridLatLon
|
|
||||||
|
|
||||||
def getAvailableTimes(self, request, refTimeOnly):
|
|
||||||
timesRequest = GetAvailableTimesRequest()
|
|
||||||
timesRequest.setRequestParameters(request)
|
|
||||||
timesRequest.setRefTimeOnly(refTimeOnly)
|
|
||||||
response = self._client.sendRequest(timesRequest)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getGridData(self, request, times):
|
|
||||||
gridDataRequest = GetGridDataRequest()
|
|
||||||
gridDataRequest.setIncludeLatLonData(not self._lazyLoadGridLatLon)
|
|
||||||
gridDataRequest.setRequestParameters(request)
|
|
||||||
# if we have an iterable times instance, then the user must have asked
|
|
||||||
# for grid data with the List of DataTime objects
|
|
||||||
# else, we assume it was a single TimeRange that was meant for the
|
|
||||||
# request
|
|
||||||
try:
|
|
||||||
iter(times)
|
|
||||||
gridDataRequest.setRequestedTimes(times)
|
|
||||||
except TypeError:
|
|
||||||
gridDataRequest.setRequestedPeriod(times)
|
|
||||||
response = self._client.sendRequest(gridDataRequest)
|
|
||||||
|
|
||||||
locSpecificData = {}
|
|
||||||
locNames = list(response.getSiteNxValues().keys())
|
|
||||||
for location in locNames:
|
|
||||||
nx = response.getSiteNxValues()[location]
|
|
||||||
ny = response.getSiteNyValues()[location]
|
|
||||||
if self._lazyLoadGridLatLon:
|
|
||||||
envelope = response.getSiteEnvelopes()[location]
|
|
||||||
crsWkt = response.getSiteCrsWkt()[location]
|
|
||||||
delegate = LazyGridLatLon(
|
|
||||||
self._client, nx, ny, envelope, crsWkt)
|
|
||||||
locSpecificData[location] = (nx, ny, delegate)
|
|
||||||
else:
|
|
||||||
latData = numpy.reshape(numpy.array(
|
|
||||||
response.getSiteLatGrids()[location]), (ny, nx))
|
|
||||||
lonData = numpy.reshape(numpy.array(
|
|
||||||
response.getSiteLonGrids()[location]), (ny, nx))
|
|
||||||
locSpecificData[location] = (nx, ny, (lonData, latData))
|
|
||||||
retVal = []
|
|
||||||
for gridDataRecord in response.getGridData():
|
|
||||||
locationName = gridDataRecord.getLocationName()
|
|
||||||
locData = locSpecificData[locationName]
|
|
||||||
if self._lazyLoadGridLatLon:
|
|
||||||
retVal.append(PyGridData.PyGridData(gridDataRecord, locData[
|
|
||||||
0], locData[1], latLonDelegate=locData[2]))
|
|
||||||
else:
|
|
||||||
retVal.append(PyGridData.PyGridData(
|
|
||||||
gridDataRecord, locData[0], locData[1], locData[2]))
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
def getGeometryData(self, request, times):
|
|
||||||
geoDataRequest = GetGeometryDataRequest()
|
|
||||||
geoDataRequest.setRequestParameters(request)
|
|
||||||
# if we have an iterable times instance, then the user must have asked
|
|
||||||
# for geometry data with the List of DataTime objects
|
|
||||||
# else, we assume it was a single TimeRange that was meant for the
|
|
||||||
# request
|
|
||||||
try:
|
|
||||||
iter(times)
|
|
||||||
geoDataRequest.setRequestedTimes(times)
|
|
||||||
except TypeError:
|
|
||||||
geoDataRequest.setRequestedPeriod(times)
|
|
||||||
response = self._client.sendRequest(geoDataRequest)
|
|
||||||
geometries = []
|
|
||||||
for wkb in response.getGeometryWKBs():
|
|
||||||
# the wkb is a numpy.ndarray of dtype int8
|
|
||||||
# convert the bytearray to a byte string and load it
|
|
||||||
geometries.append(shapely.wkb.loads(wkb.tostring()))
|
|
||||||
|
|
||||||
retVal = []
|
|
||||||
for geoDataRecord in response.getGeoData():
|
|
||||||
geom = geometries[geoDataRecord.getGeometryWKBindex()]
|
|
||||||
retVal.append(PyGeometryData.PyGeometryData(geoDataRecord, geom))
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
def getAvailableLocationNames(self, request):
|
|
||||||
locNamesRequest = GetAvailableLocationNamesRequest()
|
|
||||||
locNamesRequest.setRequestParameters(request)
|
|
||||||
response = self._client.sendRequest(locNamesRequest)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getAvailableParameters(self, request):
|
|
||||||
paramReq = GetAvailableParametersRequest()
|
|
||||||
paramReq.setRequestParameters(request)
|
|
||||||
response = self._client.sendRequest(paramReq)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getAvailableLevels(self, request):
|
|
||||||
levelReq = GetAvailableLevelsRequest()
|
|
||||||
levelReq.setRequestParameters(request)
|
|
||||||
response = self._client.sendRequest(levelReq)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getRequiredIdentifiers(self, request):
|
|
||||||
if str(request) == request:
|
|
||||||
# Handle old version getRequiredIdentifiers(str)
|
|
||||||
request = self.newDataRequest(request)
|
|
||||||
idReq = GetRequiredIdentifiersRequest()
|
|
||||||
idReq.setRequest(request)
|
|
||||||
response = self._client.sendRequest(idReq)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getOptionalIdentifiers(self, request):
|
|
||||||
if str(request) == request:
|
|
||||||
# Handle old version getOptionalIdentifiers(str)
|
|
||||||
request = self.newDataRequest(request)
|
|
||||||
idReq = GetOptionalIdentifiersRequest()
|
|
||||||
idReq.setRequest(request)
|
|
||||||
response = self._client.sendRequest(idReq)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getIdentifierValues(self, request, identifierKey):
|
|
||||||
idValReq = GetIdentifierValuesRequest()
|
|
||||||
idValReq.setIdentifierKey(identifierKey)
|
|
||||||
idValReq.setRequestParameters(request)
|
|
||||||
response = self._client.sendRequest(idValReq)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def newDataRequest(self, datatype, parameters=[], levels=[], locationNames=[], envelope=None, **kwargs):
|
|
||||||
req = DefaultDataRequest()
|
|
||||||
if datatype:
|
|
||||||
req.setDatatype(datatype)
|
|
||||||
if parameters:
|
|
||||||
req.setParameters(*parameters)
|
|
||||||
if levels:
|
|
||||||
req.setLevels(*levels)
|
|
||||||
if locationNames:
|
|
||||||
req.setLocationNames(*locationNames)
|
|
||||||
if envelope:
|
|
||||||
req.setEnvelope(envelope)
|
|
||||||
if kwargs:
|
|
||||||
# any args leftover are assumed to be identifiers
|
|
||||||
req.identifiers = kwargs
|
|
||||||
return req
|
|
||||||
|
|
||||||
def getSupportedDatatypes(self):
|
|
||||||
response = self._client.sendRequest(GetSupportedDatatypesRequest())
|
|
||||||
return response
|
|
||||||
|
|
||||||
def getNotificationFilter(self, request):
|
|
||||||
notifReq = GetNotificationFilterRequest()
|
|
||||||
notifReq.setRequestParameters(request)
|
|
||||||
response = self._client.sendRequest(notifReq)
|
|
||||||
return response
|
|
|
@ -1,385 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# __init__.py for ufpy.dataaccess package
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 12/10/12 njensen Initial Creation.
|
|
||||||
# Feb 14, 2013 1614 bsteffen refactor data access framework
|
|
||||||
# to use single request.
|
|
||||||
# Apr 09, 2013 1871 njensen Add doc strings
|
|
||||||
# Jun 03, 2013 2023 dgilling Add getAttributes to IData, add
|
|
||||||
# getLatLonGrids() to IGridData.
|
|
||||||
# Aug 01, 2016 2416 tgurney Add INotificationSubscriber
|
|
||||||
# and INotificationFilter
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
import abc
|
|
||||||
|
|
||||||
class IDataRequest(object, metaclass=abc.ABCMeta):
|
|
||||||
"""
|
|
||||||
An IDataRequest to be submitted to the DataAccessLayer to retrieve data.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def setDatatype(self, datatype):
|
|
||||||
"""
|
|
||||||
Sets the datatype of the request.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
datatype: A string of the datatype, such as "grid", "radar", "gfe", "obs"
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def addIdentifier(self, key, value):
|
|
||||||
"""
|
|
||||||
Adds an identifier to the request. Identifiers are specific to the
|
|
||||||
datatype being requested.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
key: the string key of the identifier
|
|
||||||
value: the value of the identifier
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def setParameters(self, params):
|
|
||||||
"""
|
|
||||||
Sets the parameters of data to request.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
params: a list of strings of parameters to request
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def setLevels(self, levels):
|
|
||||||
"""
|
|
||||||
Sets the levels of data to request. Not all datatypes support levels.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
levels: a list of strings of level abbreviations to request
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def setEnvelope(self, env):
|
|
||||||
"""
|
|
||||||
Sets the envelope of the request. If supported by the datatype factory,
|
|
||||||
the data returned for the request will be constrained to only the data
|
|
||||||
within the envelope.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
env: a shapely geometry
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def setLocationNames(self, locationNames):
|
|
||||||
"""
|
|
||||||
Sets the location names of the request.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
locationNames: a list of strings of location names to request
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getDatatype(self):
|
|
||||||
"""
|
|
||||||
Gets the datatype of the request
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the datatype set on the request
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getIdentifiers(self):
|
|
||||||
"""
|
|
||||||
Gets the identifiers on the request
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a dictionary of the identifiers
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getLevels(self):
|
|
||||||
"""
|
|
||||||
Gets the levels on the request
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of the levels
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getLocationNames(self):
|
|
||||||
"""
|
|
||||||
Gets the location names on the request
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of the location names
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getEnvelope(self):
|
|
||||||
"""
|
|
||||||
Gets the envelope on the request
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a rectangular shapely geometry
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IData(object, metaclass=abc.ABCMeta):
|
|
||||||
"""
|
|
||||||
An IData representing data returned from the DataAccessLayer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getAttribute(self, key):
|
|
||||||
"""
|
|
||||||
Gets an attribute of the data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
key: the key of the attribute
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the value of the attribute
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getAttributes(self):
|
|
||||||
"""
|
|
||||||
Gets the valid attributes for the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of the attribute names
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getDataTime(self):
|
|
||||||
"""
|
|
||||||
Gets the data time of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the data time of the data, or None if no time is associated
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getLevel(self):
|
|
||||||
"""
|
|
||||||
Gets the level of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the level of the data, or None if no level is associated
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getLocationName(self, param):
|
|
||||||
"""
|
|
||||||
Gets the location name of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the location name of the data, or None if no location name is
|
|
||||||
associated
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IGridData(IData):
|
|
||||||
"""
|
|
||||||
An IData representing grid data that is returned by the DataAccessLayer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getParameter(self):
|
|
||||||
"""
|
|
||||||
Gets the parameter of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the parameter of the data
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getUnit(self):
|
|
||||||
"""
|
|
||||||
Gets the unit of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the string abbreviation of the unit, or None if no unit is associated
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getRawData(self):
|
|
||||||
"""
|
|
||||||
Gets the grid data as a numpy array.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a numpy array of the data
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getLatLonCoords(self):
|
|
||||||
"""
|
|
||||||
Gets the lat/lon coordinates of the grid data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a tuple where the first element is a numpy array of lons, and the
|
|
||||||
second element is a numpy array of lats
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IGeometryData(IData):
|
|
||||||
"""
|
|
||||||
An IData representing geometry data that is returned by the DataAccessLayer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getGeometry(self):
|
|
||||||
"""
|
|
||||||
Gets the geometry of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a shapely geometry
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getParameters(self):
|
|
||||||
"""Gets the parameters of the data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a list of strings of the parameter names
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getString(self, param):
|
|
||||||
"""
|
|
||||||
Gets the string value of the specified param.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
param: the string name of the param
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the string value of the param
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getNumber(self, param):
|
|
||||||
"""
|
|
||||||
Gets the number value of the specified param.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
param: the string name of the param
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the number value of the param
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getUnit(self, param):
|
|
||||||
"""
|
|
||||||
Gets the unit of the specified param.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
param: the string name of the param
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
the string abbreviation of the unit of the param
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def getType(self, param):
|
|
||||||
"""
|
|
||||||
Gets the type of the param.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
param: the string name of the param
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
a string of the type of the parameter, such as
|
|
||||||
"STRING", "INT", "LONG", "FLOAT", or "DOUBLE"
|
|
||||||
"""
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
class INotificationSubscriber(object, metaclass=abc.ABCMeta):
|
|
||||||
"""
|
|
||||||
An INotificationSubscriber representing a notification filter returned from
|
|
||||||
the DataNotificationLayer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def subscribe(self, callback):
|
|
||||||
"""
|
|
||||||
Subscribes to the requested data. Method will not return until close is
|
|
||||||
called in a separate thread.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
callback: the method to call with the IGridData/IGeometryData
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def close(self):
|
|
||||||
"""Closes the notification subscriber"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class INotificationFilter(object, metaclass=abc.ABCMeta):
|
|
||||||
"""
|
|
||||||
Represents data required to filter a set of URIs and
|
|
||||||
return a corresponding list of IDataRequest to retrieve data for.
|
|
||||||
"""
|
|
||||||
@abc.abstractmethod
|
|
||||||
def accept(dataUri):
|
|
||||||
pass
|
|
|
@ -1,173 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
from ufpy import ThriftClient
|
|
||||||
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import ParmID
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import CommitGridsRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import GetGridInventoryRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import GetParmListRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import GetSelectTimeRangeRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.server.request import CommitGridRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.site.requests import GetActiveSitesRequest
|
|
||||||
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.server.message import ServerResponse
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Provides a Python-based interface for executing GFE requests.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 07/26/12 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
class IFPClient(object):
|
|
||||||
def __init__(self, host, port, user, site=None, progName=None):
|
|
||||||
self.__thrift = ThriftClient.ThriftClient(host, port)
|
|
||||||
self.__wsId = WsId(userName=user, progName=progName)
|
|
||||||
# retrieve default site
|
|
||||||
if site is None:
|
|
||||||
sr = self.getSiteID()
|
|
||||||
if len(sr.getPayload()) > 0:
|
|
||||||
site = sr.getPayload()[0]
|
|
||||||
self.__siteId = site
|
|
||||||
|
|
||||||
def commitGrid(self, request):
|
|
||||||
if type(request) is CommitGridRequest:
|
|
||||||
return self.__commitGrid([request])
|
|
||||||
elif self.__isHomogenousIterable(request, CommitGridRequest):
|
|
||||||
return self.__commitGrid([cgr for cgr in request])
|
|
||||||
raise TypeError("Invalid type: " + str(type(request)) + " specified to commitGrid(). Only accepts CommitGridRequest or lists of CommitGridRequest.")
|
|
||||||
|
|
||||||
def __commitGrid(self, requests):
|
|
||||||
ssr = ServerResponse()
|
|
||||||
request = CommitGridsRequest()
|
|
||||||
request.setCommits(requests)
|
|
||||||
sr = self.__makeRequest(request)
|
|
||||||
ssr.setMessages(sr.getMessages())
|
|
||||||
return ssr
|
|
||||||
|
|
||||||
def getParmList(self, id):
|
|
||||||
argType = type(id)
|
|
||||||
if argType is DatabaseID:
|
|
||||||
return self.__getParmList([id])
|
|
||||||
elif self.__isHomogenousIterable(id, DatabaseID):
|
|
||||||
return self.__getParmList([dbid for dbid in id])
|
|
||||||
raise TypeError("Invalid type: " + str(argType) + " specified to getParmList(). Only accepts DatabaseID or lists of DatabaseID.")
|
|
||||||
|
|
||||||
def __getParmList(self, ids):
|
|
||||||
ssr = ServerResponse()
|
|
||||||
request = GetParmListRequest()
|
|
||||||
request.setDbIds(ids)
|
|
||||||
sr = self.__makeRequest(request)
|
|
||||||
ssr.setMessages(sr.getMessages())
|
|
||||||
list = sr.getPayload() if sr.getPayload() is not None else []
|
|
||||||
ssr.setPayload(list)
|
|
||||||
return ssr
|
|
||||||
|
|
||||||
def __isHomogenousIterable(self, iterable, classType):
|
|
||||||
try:
|
|
||||||
iterator = iter(iterable)
|
|
||||||
for item in iterator:
|
|
||||||
if not isinstance(item, classType):
|
|
||||||
return False
|
|
||||||
except TypeError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def getGridInventory(self, parmID):
|
|
||||||
if type(parmID) is ParmID:
|
|
||||||
sr = self.__getGridInventory([parmID])
|
|
||||||
list = []
|
|
||||||
try:
|
|
||||||
list = sr.getPayload()[parmID]
|
|
||||||
except KeyError:
|
|
||||||
# no-op, we've already default the TimeRange list to empty
|
|
||||||
pass
|
|
||||||
sr.setPayload(list)
|
|
||||||
return sr
|
|
||||||
elif self.__isHomogenousIterable(parmID, ParmID):
|
|
||||||
return self.__getGridInventory([id for id in parmID])
|
|
||||||
raise TypeError("Invalid type: " + str(type(parmID)) + " specified to getGridInventory(). Only accepts ParmID or lists of ParmID.")
|
|
||||||
|
|
||||||
def __getGridInventory(self, parmIDs):
|
|
||||||
ssr = ServerResponse()
|
|
||||||
request = GetGridInventoryRequest()
|
|
||||||
request.setParmIds(parmIDs)
|
|
||||||
sr = self.__makeRequest(request)
|
|
||||||
ssr.setMessages(sr.getMessages())
|
|
||||||
trs = sr.getPayload() if sr.getPayload() is not None else {}
|
|
||||||
ssr.setPayload(trs)
|
|
||||||
return ssr
|
|
||||||
|
|
||||||
def getSelectTR(self, name):
|
|
||||||
request = GetSelectTimeRangeRequest()
|
|
||||||
request.setName(name)
|
|
||||||
sr = self.__makeRequest(request)
|
|
||||||
ssr = ServerResponse()
|
|
||||||
ssr.setMessages(sr.getMessages())
|
|
||||||
ssr.setPayload(sr.getPayload())
|
|
||||||
return ssr
|
|
||||||
|
|
||||||
def getSiteID(self):
|
|
||||||
ssr = ServerResponse()
|
|
||||||
request = GetActiveSitesRequest()
|
|
||||||
sr = self.__makeRequest(request)
|
|
||||||
ssr.setMessages(sr.getMessages())
|
|
||||||
ids = sr.getPayload() if sr.getPayload() is not None else []
|
|
||||||
sr.setPayload(ids)
|
|
||||||
return sr
|
|
||||||
|
|
||||||
def __makeRequest(self, request):
|
|
||||||
try:
|
|
||||||
request.setSiteID(self.__siteId)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
request.setWorkstationID(self.__wsId)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
sr = ServerResponse()
|
|
||||||
response = None
|
|
||||||
try:
|
|
||||||
response = self.__thrift.sendRequest(request)
|
|
||||||
except ThriftClient.ThriftRequestException as e:
|
|
||||||
sr.setMessages([str(e)])
|
|
||||||
try:
|
|
||||||
sr.setPayload(response.getPayload())
|
|
||||||
except AttributeError:
|
|
||||||
sr.setPayload(response)
|
|
||||||
try:
|
|
||||||
sr.setMessages(response.getMessages())
|
|
||||||
except AttributeError:
|
|
||||||
# not a server response, nothing else to do
|
|
||||||
pass
|
|
||||||
|
|
||||||
return sr
|
|
|
@ -1,37 +0,0 @@
|
||||||
##
|
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
#
|
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
# This software product contains export-restricted data whose
|
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
# an export license or other authorization.
|
|
||||||
#
|
|
||||||
# Contractor Name: Raytheon Company
|
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
# Mail Stop B8
|
|
||||||
# Omaha, NE 68106
|
|
||||||
# 402.291.0100
|
|
||||||
#
|
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
# further licensing information.
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# __init__.py for ufpy.gfe package
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SOFTWARE HISTORY
|
|
||||||
#
|
|
||||||
# Date Ticket# Engineer Description
|
|
||||||
# ------------ ---------- ----------- --------------------------
|
|
||||||
# 07/26/12 dgilling Initial Creation.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
]
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue