VLab Issue #4953 Added support for writing Python and/or Java objects to JSON localization files.
Change-Id: Ie25fce637e4294dd20bcfa3933d29b7bf6cc1f30 Former-commit-id: c9d45db2fe6d4693c02b8788d0c7d44b21f5359f
This commit is contained in:
parent
1ae8fe99aa
commit
04b8ffbcd2
12 changed files with 430 additions and 166 deletions
|
@ -1,7 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?>
|
||||
|
||||
<pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
</pydev_project>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import GenericHazards
|
||||
import JsonSupport
|
||||
import string, time, os, re, types, copy, LogStream, collections
|
||||
import ModuleAccessor, SampleAnalysis, EditAreaUtils
|
||||
import math
|
||||
|
@ -267,7 +268,7 @@ class TextProduct(GenericHazards.TextProduct):
|
|||
### Time related methods
|
||||
|
||||
def _initializeTimeVariables(self, argDict):
|
||||
argDict['creationTime'] = int(time.time()/60)*60.0
|
||||
argDict['creationTime'] = int(time.time()/60)*60
|
||||
self._issueTime_secs = argDict['creationTime']
|
||||
self._issueTime = self._issueTime_secs * 1000 # in milliseconds
|
||||
|
||||
|
@ -756,16 +757,13 @@ FORECASTER STEWART"""
|
|||
self._previousPreviousAdvisory = self._loadAdvisory(lastTwoAdvisories[1])
|
||||
|
||||
def _loadAdvisory(self, advisoryName):
|
||||
import json
|
||||
|
||||
self._synchronizeAdvisories()
|
||||
|
||||
try:
|
||||
jsonDict = self._getFileContents(LocalizationType.CAVE_STATIC,
|
||||
pythonDict = JsonSupport.loadFromJson(LocalizationType.CAVE_STATIC,
|
||||
self._site,
|
||||
self._getAdvisoryFilename(advisoryName))
|
||||
|
||||
pythonDict = json.loads(jsonDict)
|
||||
|
||||
print "SARAH: File contents for", self._getAdvisoryFilename(advisoryName), ":"
|
||||
print pythonDict
|
||||
|
||||
|
@ -788,15 +786,6 @@ FORECASTER STEWART"""
|
|||
|
||||
return localizationFile
|
||||
|
||||
def _getFileContents(self, loctype, siteID, filename):
|
||||
pathManager = PathManagerFactory.getPathManager()
|
||||
context = pathManager.getContextForSite(loctype, siteID)
|
||||
localizationFile = pathManager.getLocalizationFile(context, filename)
|
||||
with File(localizationFile.getFile(), filename, 'r') as pythonFile:
|
||||
fileContents = pythonFile.read()
|
||||
|
||||
return fileContents
|
||||
|
||||
def _getAdvisoryFilename(self, advisoryName):
|
||||
advisoryFilename = self._getAdvisoryPath() + \
|
||||
advisoryName + \
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
# 02/05/14 2774 dgilling Fix error logging statements in
|
||||
# __warnETNduplication() and
|
||||
# __highestETNActiveTable.
|
||||
# 11/11/14 4953 randerso Changed type of endTime from float to int
|
||||
#
|
||||
|
||||
|
||||
|
@ -957,7 +958,7 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
|
|||
# consolidate
|
||||
pTable = self.__consolidateTime(pTable)
|
||||
|
||||
# remove old - keep those ended within 30min
|
||||
# remove old - keep those ended within 30 min
|
||||
cutoff = self.__time - 30 * 60
|
||||
pTable = filter(lambda x: x['endTime'] > cutoff, pTable)
|
||||
|
||||
|
@ -965,7 +966,7 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
|
|||
for proposed in pTable:
|
||||
if (proposed['phen'], proposed['sig']) in self.__ufnKeys:
|
||||
proposed['startTime'] = self.__time #now
|
||||
proposed['endTime'] = float(2 ** 31 - 1) #forever
|
||||
proposed['endTime'] = 2 ** 31 - 1 #forever
|
||||
proposed['ufn'] = 1 #until further notice
|
||||
|
||||
self.log.info("Hazards afflicting cities:" +
|
||||
|
|
|
@ -21,7 +21,6 @@ package com.raytheon.edex.plugin.gfe.textproducts;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -32,6 +31,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.raytheon.edex.utility.ProtectedFiles;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
|
@ -64,6 +64,7 @@ import com.raytheon.uf.edex.database.cluster.ClusterTask;
|
|||
* to create textProducts and textUtilities.
|
||||
* Sep 07,2012 #1150 dgilling Fix isConfigured to check for textProducts
|
||||
* and textUtilities dirs.
|
||||
* Oct 20, 2014 #4953 randerso Cleaned up how protected file updates are returned
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -183,26 +184,23 @@ public class Configurator {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute() {
|
||||
PythonScript python = null;
|
||||
List<String> preEvals = new ArrayList<String>();
|
||||
|
||||
if (isConfigured()) {
|
||||
statusHandler.info("All text products are up to date");
|
||||
return;
|
||||
}
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext context = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.CONFIGURED);
|
||||
context.setContextName(siteID);
|
||||
|
||||
PythonScript python = null;
|
||||
|
||||
LocalizationContext edexCx = pathMgr.getContext(
|
||||
LocalizationType.EDEX_STATIC, LocalizationLevel.BASE);
|
||||
LocalizationContext commonCx = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
|
||||
String filePath = pathMgr.getFile(edexCx,
|
||||
"textproducts" + File.separator + "Generator.py").getPath();
|
||||
String textProductPath = pathMgr.getFile(edexCx,
|
||||
"textProducts.Generator").getPath();
|
||||
String jutilPath = pathMgr.getFile(commonCx, "python").getPath();
|
||||
|
||||
// Add some getters we need "in the script" that we want hidden
|
||||
preEvals.add("from JUtil import pylistToJavaStringList");
|
||||
preEvals.add("from textproducts.Generator import Generator");
|
||||
preEvals.add("generator = Generator()");
|
||||
preEvals.add("def getProtectedData():\n return pylistToJavaStringList(generator.getProtectedFiles())");
|
||||
String commonPython = GfePyIncludeUtil.getCommonPythonIncludePath();
|
||||
|
||||
Map<String, Object> argList = new HashMap<String, Object>();
|
||||
argList.put("siteId", siteID);
|
||||
|
@ -210,20 +208,18 @@ public class Configurator {
|
|||
|
||||
try {
|
||||
python = new PythonScript(filePath, PyUtil.buildJepIncludePath(
|
||||
pythonDirectory, textProductPath, jutilPath), this
|
||||
.getClass().getClassLoader(), preEvals);
|
||||
pythonDirectory, commonPython), this.getClass()
|
||||
.getClassLoader());
|
||||
|
||||
// Open the Python interpreter using the designated script.
|
||||
python.execute("generator.create", argList);
|
||||
protectedFilesList = (List<String>) python.execute(
|
||||
"getProtectedData", null);
|
||||
protectedFilesList = (List<String>) python.execute("runFromJava",
|
||||
argList);
|
||||
|
||||
updateProtectedFile();
|
||||
updateLastRuntime();
|
||||
} catch (JepException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error Configuring Text Products", e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (python != null) {
|
||||
python.dispose();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.edex.plugin.gfe.watch;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -27,8 +28,21 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import jep.JepException;
|
||||
|
||||
import com.raytheon.uf.common.activetable.VTECPartners;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
|
||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
|
||||
import com.raytheon.uf.common.python.PyUtil;
|
||||
import com.raytheon.uf.common.python.PythonScript;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
|
||||
/**
|
||||
* Watches ingested warnings for WOU products from the SPC (Storm Prediction
|
||||
|
@ -45,6 +59,7 @@ import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
|||
* Oct 08, 2014 #4953 randerso Refactored AbstractWatchNotifierSrv to allow
|
||||
* subclasses to handle all watches if desired.
|
||||
* Added hooks for TCVAdvisory creation
|
||||
* Changed to use Python to store TCVAdvisory files
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -85,6 +100,37 @@ public final class TPCWatchSrv extends AbstractWatchNotifierSrv {
|
|||
actMap = Collections.unmodifiableMap(actMapTemp);
|
||||
}
|
||||
|
||||
private ThreadLocal<PythonScript> pythonScript = new ThreadLocal<PythonScript>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.ThreadLocal#initialValue()
|
||||
*/
|
||||
@Override
|
||||
protected PythonScript initialValue() {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext context = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
LocalizationFile lf = pathMgr.getLocalizationFile(context, FileUtil
|
||||
.join(GfePyIncludeUtil.COMMON_GFE, "JsonSupport.py"));
|
||||
|
||||
String filePath = lf.getFile().getAbsolutePath();
|
||||
|
||||
String includePath = PyUtil.buildJepIncludePath(true,
|
||||
GfePyIncludeUtil.getCommonGfeIncludePath());
|
||||
|
||||
try {
|
||||
return new PythonScript(filePath, includePath, this.getClass()
|
||||
.getClassLoader());
|
||||
} catch (JepException e) {
|
||||
statusHandler.error(e.getLocalizedMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -103,11 +149,148 @@ public final class TPCWatchSrv extends AbstractWatchNotifierSrv {
|
|||
public void handleWatch(List<AbstractWarningRecord> warningRecs) {
|
||||
super.handleWatch(warningRecs);
|
||||
|
||||
// FIXME: This marks the pending.json file as Transmitted when ANY TCV
|
||||
// is decoded not the one just sent by this office. You need to look and
|
||||
// the warningRecs for a match to the issuing site and ETN or something
|
||||
// like that.
|
||||
|
||||
// FIXME: The python created dicts are storing CreationTime and EndTime
|
||||
// (but not StartTime for some reason)
|
||||
// as python floats. These values are converted to Java floats which are
|
||||
// single precision 32-bit floats causing a possible loss of precision.
|
||||
// These should be stored a integer values or datetime objects to ensure
|
||||
// no precision loss. I have fixed a couple of places where endTime may
|
||||
// have been set to a float but we need to ensure we've got them all.
|
||||
for (String siteId : getActiveSites()) {
|
||||
for (AbstractWarningRecord record : warningRecs) {
|
||||
// TODO: Sarah, add a call to your method that
|
||||
// handles the TCV here:
|
||||
// example: processTCV(siteID, record);
|
||||
this.saveTCVAdvisories(siteId);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveTCVAdvisories(String siteId) {
|
||||
File advisoriesDirectory = this.synchronizeTCVAdvisories(siteId);
|
||||
|
||||
String pendingFilename = "pending.json";
|
||||
LocalizationFile pendingFile = this.getLocalizationFile(siteId,
|
||||
pendingFilename);
|
||||
|
||||
Map<String, Object> pendingDict = this.loadJSONDictionary(pendingFile);
|
||||
if (pendingDict == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
pendingDict.put("Transmitted", true);
|
||||
|
||||
String stormName = (String) pendingDict.get("StormName");
|
||||
String advisoryNumber = (String) pendingDict.get("AdvisoryNumber");
|
||||
String transmittedFilename = stormName + advisoryNumber + ".json";
|
||||
|
||||
LocalizationFile transmittedFile = this.getLocalizationFile(siteId,
|
||||
transmittedFilename);
|
||||
this.saveJSONDictionary(transmittedFile, pendingDict);
|
||||
|
||||
boolean transmittedFileSaved = false;
|
||||
try {
|
||||
transmittedFile.save();
|
||||
transmittedFileSaved = true;
|
||||
} catch (LocalizationOpFailedException e) {
|
||||
statusHandler.error("Failed to save advisory "
|
||||
+ transmittedFilename);
|
||||
}
|
||||
|
||||
if (transmittedFileSaved) {
|
||||
boolean allCAN = (Boolean) pendingDict.get("AllCAN");
|
||||
if (allCAN) {
|
||||
for (File advisory : advisoriesDirectory.listFiles()) {
|
||||
String advisoryName = advisory.getName();
|
||||
if (advisoryName.startsWith(stormName)) {
|
||||
LocalizationFile advisoryFile = this
|
||||
.getLocalizationFile(siteId, advisoryName);
|
||||
try {
|
||||
advisoryFile.delete();
|
||||
} catch (LocalizationOpFailedException e) {
|
||||
statusHandler.error("Unable to delete "
|
||||
+ advisoryFile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
pendingFile.delete();
|
||||
} catch (LocalizationOpFailedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
this.synchronizeTCVAdvisories(siteId);
|
||||
}
|
||||
|
||||
private File synchronizeTCVAdvisories(String siteId) {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext context = pathMgr.getContextForSite(
|
||||
LocalizationType.CAVE_STATIC, siteId);
|
||||
|
||||
// Retrieving a directory causes synching to occur
|
||||
File file = pathMgr.getLocalizationFile(context,
|
||||
this.getTCVAdvisoryPath()).getFile();
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
private LocalizationFile getLocalizationFile(String siteId, String filename) {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext context = pathMgr.getContextForSite(
|
||||
LocalizationType.CAVE_STATIC, siteId);
|
||||
LocalizationFile localizationFile = pathMgr.getLocalizationFile(
|
||||
context, this.getTCVAdvisoryPath() + filename);
|
||||
|
||||
return localizationFile;
|
||||
}
|
||||
|
||||
private String getTCVAdvisoryPath() {
|
||||
return "gfe/tcvAdvisories/";
|
||||
}
|
||||
|
||||
private Map<String, Object> loadJSONDictionary(LocalizationFile lf) {
|
||||
if (lf != null) {
|
||||
PythonScript script = this.pythonScript.get();
|
||||
if (script != null) {
|
||||
Map<String, Object> args = new HashMap<String, Object>();
|
||||
args.put("localizationType", lf.getContext()
|
||||
.getLocalizationType());
|
||||
args.put("siteID", lf.getContext().getContextName());
|
||||
args.put("fileName", lf.getName());
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> retVal = (Map<String, Object>) script
|
||||
.execute("loadJsonFromJava", args);
|
||||
return retVal;
|
||||
} catch (JepException e) {
|
||||
statusHandler.error(
|
||||
"Error loading TCV advisory from " + lf, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void saveJSONDictionary(LocalizationFile lf,
|
||||
Map<String, Object> dict) {
|
||||
if (lf != null) {
|
||||
PythonScript script = this.pythonScript.get();
|
||||
if (script != null) {
|
||||
Map<String, Object> args = new HashMap<String, Object>();
|
||||
args.put("localizationType", lf.getContext()
|
||||
.getLocalizationType());
|
||||
args.put("siteID", lf.getContext().getContextName());
|
||||
args.put("fileName", lf.getName());
|
||||
args.put("javaObject", dict);
|
||||
try {
|
||||
script.execute("saveJsonFromJava", args);
|
||||
} catch (JepException e) {
|
||||
statusHandler
|
||||
.error("Error saving TCV advisory to " + lf, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,4 +357,4 @@ public final class TPCWatchSrv extends AbstractWatchNotifierSrv {
|
|||
|
||||
return msg.toString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
##
|
||||
# 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 support for loading/saving python objects from/to localization files
|
||||
# using JSON serialization
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 11/10/14 randerso Initial Creation.
|
||||
##
|
||||
import json
|
||||
import LocalizationSupport
|
||||
|
||||
import JUtil
|
||||
|
||||
def loadFromJson(localizationType, siteID, fileName):
|
||||
jsonString = LocalizationSupport.readFile(localizationType, siteID, fileName)
|
||||
object = json.loads(jsonString)
|
||||
return object
|
||||
|
||||
def saveToJson(localizationType, siteID, fileName, object):
|
||||
jsonString = json.dumps(object, sort_keys=True,
|
||||
indent=4, separators=(',', ': '))
|
||||
LocalizationSupport.writeFile(localizationType, siteID, fileName, jsonString)
|
||||
|
||||
def loadJsonFromJava(localizationType, siteID, fileName):
|
||||
object = loadFromJson(localizationType, siteID, fileName)
|
||||
javaObject = JUtil.pyValToJavaObj(object)
|
||||
return javaObject
|
||||
|
||||
def saveJsonFromJava(localizationType, siteID, fileName, javaObject):
|
||||
object = JUtil.javaObjToPyVal(javaObject)
|
||||
saveToJson(localizationType, siteID, fileName, object)
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
##
|
||||
# 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 support for reading/writing/deleting files using localization
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 11/10/14 randerso Initial Creation.
|
||||
##
|
||||
from LockingFile import File
|
||||
from com.raytheon.uf.common.localization import PathManagerFactory
|
||||
|
||||
def __getLocalizationFile(loctype, site, filename):
|
||||
pathManager = PathManagerFactory.getPathManager()
|
||||
context = pathManager.getContextForSite(loctype, site)
|
||||
localizationFile = pathManager.getLocalizationFile(context, filename)
|
||||
return localizationFile
|
||||
|
||||
def readFile(loctype, site, filename):
|
||||
localizationFile = __getLocalizationFile(loctype, site, filename)
|
||||
|
||||
with File(localizationFile.getFile(), filename, 'r') as pythonFile:
|
||||
fileContents = pythonFile.read()
|
||||
|
||||
return fileContents
|
||||
|
||||
def writeFile(loctype, site, filename, contents):
|
||||
localizationFile = __getLocalizationFile(loctype, site, filename)
|
||||
|
||||
with File(localizationFile.getFile(), filename, 'w') as pythonFile:
|
||||
pythonFile.write(contents)
|
||||
|
||||
localizationFile.save()
|
||||
|
||||
def deleteFile(loctype, site, filename):
|
||||
localizationFile = __getLocalizationFile(loctype, site, filename)
|
||||
localizationFile.delete()
|
|
@ -18,28 +18,33 @@
|
|||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
# further licensing information.
|
||||
##
|
||||
|
||||
"""Generate site specific text products.
|
||||
|
||||
This script is run at install time to customize a set of the text products
|
||||
for a given site.
|
||||
|
||||
SOFTWARE HISTORY
|
||||
Date Ticket# Engineer Description
|
||||
------------ ---------- ----------- --------------------------
|
||||
Jun 23, 2008 1180 jelkins Initial creation
|
||||
Jul 08, 2008 1222 jelkins Modified for use within Java
|
||||
Jul 09, 2008 1222 jelkins Split command line loader from class
|
||||
Jul 24, 2012 #944 dgilling Refactored to support separate
|
||||
generation of products and utilities.
|
||||
Sep 07, 2012 #1150 dgilling Ensure all necessary dirs get created.
|
||||
|
||||
@author: jelkins
|
||||
"""
|
||||
#
|
||||
# Generate site specific text products.
|
||||
#
|
||||
# This script is run at install time to customize a set of the text products
|
||||
# for a given site.
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# Jun 23, 2008 1180 jelkins Initial creation
|
||||
# Jul 08, 2008 1222 jelkins Modified for use within Java
|
||||
# Jul 09, 2008 1222 jelkins Split command line loader from class
|
||||
# Jul 24, 2012 #944 dgilling Refactored to support separate
|
||||
# generation of products and utilities.
|
||||
# Sep 07, 2012 #1150 dgilling Ensure all necessary dirs get created.
|
||||
# Oct 20, 2014 #4953 randerso Changed how SiteInfo is loaded.
|
||||
# Fixed logging to log to a file
|
||||
# Cleaned up how protected file updates are returned
|
||||
#
|
||||
# @author: jelkins
|
||||
#
|
||||
##
|
||||
__version__ = "1.0"
|
||||
|
||||
import errno
|
||||
import os
|
||||
import JUtil
|
||||
from os.path import basename
|
||||
from os.path import join
|
||||
from os.path import dirname
|
||||
|
@ -63,7 +68,6 @@ from sys import path
|
|||
path.append(join(LIBRARY_DIR,"../"))
|
||||
path.append(join(PREFERENCE_DIR,"../"))
|
||||
|
||||
from library.SiteInfo import SiteInfo as SITE_INFO
|
||||
from preferences.configureTextProducts import NWSProducts as NWS_PRODUCTS
|
||||
|
||||
from os.path import basename
|
||||
|
@ -72,12 +76,21 @@ from os.path import abspath
|
|||
from os.path import join
|
||||
|
||||
# ---- Setup Logging ----------------------------------------------------------
|
||||
LOG_CONF = join(SCRIPT_DIR,"preferences","logging.conf")
|
||||
import logging
|
||||
from time import strftime, gmtime
|
||||
timeStamp = strftime("%Y%m%d", gmtime())
|
||||
logFile = '/awips2/edex/logs/configureTextProducts-'+timeStamp+'.log'
|
||||
|
||||
import logging.config
|
||||
logging.config.fileConfig(LOG_CONF)
|
||||
LOG = logging.getLogger("configureTextProducts")
|
||||
LOG.setLevel(logging.DEBUG)
|
||||
handler = logging.FileHandler(logFile)
|
||||
handler.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter("%(levelname)-5s %(asctime)s [%(process)d:%(thread)d] %(filename)s: %(message)s")
|
||||
handler.setFormatter(formatter)
|
||||
for h in LOG.handlers:
|
||||
LOG.removeHandler(h)
|
||||
LOG.addHandler(handler)
|
||||
|
||||
LOG = logging.getLogger("Generator")
|
||||
|
||||
# List of protected files
|
||||
fileList = []
|
||||
|
@ -95,6 +108,17 @@ ProcessDirectories = [
|
|||
},
|
||||
]
|
||||
|
||||
# This will "load" SiteInfo in a more complicated way
|
||||
# than 'from SiteCFG import SiteInfo'.
|
||||
from LockingFile import File
|
||||
|
||||
pathManager = PathManagerFactory.getPathManager()
|
||||
lf = pathManager.getStaticLocalizationFile(LocalizationType.COMMON_STATIC, "python/gfe/SiteCFG.py")
|
||||
with File(lf.getFile(), lf.getName(), 'r') as file:
|
||||
fileContents = file.read()
|
||||
|
||||
exec fileContents
|
||||
|
||||
|
||||
class Generator():
|
||||
"""Generates site specific text products from base template files.
|
||||
|
@ -117,7 +141,7 @@ class Generator():
|
|||
|
||||
@raise LookupError: when the site ID is invalid
|
||||
"""
|
||||
if siteId in SITE_INFO.keys():
|
||||
if siteId in SiteInfo.keys():
|
||||
self.__siteId = siteId
|
||||
else:
|
||||
raise LookupError, ' unknown WFO: ' + siteId
|
||||
|
@ -178,6 +202,8 @@ class Generator():
|
|||
created += self.__create(dirInfo['src'], dirInfo['dest'])
|
||||
LOG.info("%d text products created" % created)
|
||||
LOG.debug("Configuration of Text Products Finish")
|
||||
|
||||
return JUtil.pylistToJavaStringList(self.getProtectedFiles())
|
||||
|
||||
def delete(self):
|
||||
"""Delete text products"""
|
||||
|
@ -215,11 +241,11 @@ class Generator():
|
|||
|
||||
LOG.debug("PIL Information for all sites Begin.......")
|
||||
|
||||
for site in SITE_INFO.keys():
|
||||
for site in SiteInfo.keys():
|
||||
LOG.info("--------------------------------------------")
|
||||
LOG.info("%s %s %s" % (site,
|
||||
SITE_INFO[site]['fullStationID'],
|
||||
SITE_INFO[site]['wfoCityState']))
|
||||
SiteInfo[site]['fullStationID'],
|
||||
SiteInfo[site]['wfoCityState']))
|
||||
pils = self.__createPilDictionary(site)
|
||||
self.__printPilDictionary(pils)
|
||||
found += len(pils)
|
||||
|
@ -302,11 +328,11 @@ class Generator():
|
|||
|
||||
subDict = {}
|
||||
subDict['<site>'] = siteid.strip()
|
||||
subDict['<region>'] = SITE_INFO[siteid]['region'].strip()
|
||||
subDict['<wfoCityState>'] = SITE_INFO[siteid]['wfoCityState'].strip()
|
||||
subDict['<wfoCity>'] = SITE_INFO[siteid]['wfoCity'].strip()
|
||||
subDict['<fullStationID>'] = SITE_INFO[siteid]['fullStationID'].strip()
|
||||
subDict['<state>'] = SITE_INFO[siteid]['state'].strip()
|
||||
subDict['<region>'] = SiteInfo[siteid]['region'].strip()
|
||||
subDict['<wfoCityState>'] = SiteInfo[siteid]['wfoCityState'].strip()
|
||||
subDict['<wfoCity>'] = SiteInfo[siteid]['wfoCity'].strip()
|
||||
subDict['<fullStationID>'] = SiteInfo[siteid]['fullStationID'].strip()
|
||||
subDict['<state>'] = SiteInfo[siteid]['state'].strip()
|
||||
if product is not None:
|
||||
subDict['<product>'] = product.strip()
|
||||
if ProductToStandardMapping.has_key(product):
|
||||
|
@ -341,7 +367,7 @@ class Generator():
|
|||
|
||||
subDict = {}
|
||||
subDict['Site'] = siteid.strip()
|
||||
subDict['Region'] = SITE_INFO[siteid]['region'].strip()
|
||||
subDict['Region'] = SiteInfo[siteid]['region'].strip()
|
||||
if product is not None:
|
||||
subDict['Product'] = product.strip()
|
||||
if pilInfo is not None and pilInfo.has_key("pil") and multiPilFlag:
|
||||
|
@ -377,10 +403,10 @@ class Generator():
|
|||
LOG.info("%s %s" % (p,pillist[p]))
|
||||
|
||||
def __createPilDictionary(self, siteid):
|
||||
"""Update the SITE_INFO with a PIL dictionary
|
||||
"""Update the SiteInfo with a PIL dictionary
|
||||
|
||||
Read the a2a data from the database, create PIL information, and add the information
|
||||
to the SITE_INFO dictionary.
|
||||
to the SiteInfo dictionary.
|
||||
|
||||
@param site: the site for which PIL information is created
|
||||
@type site: string
|
||||
|
@ -389,7 +415,7 @@ class Generator():
|
|||
@rtype: dictionary
|
||||
"""
|
||||
|
||||
siteD = SITE_INFO[siteid]
|
||||
siteD = SiteInfo[siteid]
|
||||
stationID4 = siteD['fullStationID']
|
||||
|
||||
from com.raytheon.edex.plugin.text.dao import AfosToAwipsDao
|
||||
|
@ -434,7 +460,7 @@ class Generator():
|
|||
e['textdbPil'] = pil
|
||||
e['awipsWANPil'] = site4 + pil[3:]
|
||||
d.append(e)
|
||||
siteD[nnn] = d #store the pil dictionary back into the SITE_INFO
|
||||
siteD[nnn] = d #store the pil dictionary back into the SiteInfo
|
||||
|
||||
return pillist
|
||||
|
||||
|
@ -571,8 +597,8 @@ class Generator():
|
|||
continue
|
||||
|
||||
# extract out the pil information from the dictionary
|
||||
if SITE_INFO[siteid].has_key(pilNames[0]):
|
||||
pils = SITE_INFO[siteid][pilNames[0]]
|
||||
if SiteInfo[siteid].has_key(pilNames[0]):
|
||||
pils = SiteInfo[siteid][pilNames[0]]
|
||||
else:
|
||||
#set pils to empty list if none defined
|
||||
pils = [{'awipsWANPil': 'kssscccnnn',
|
||||
|
@ -727,4 +753,7 @@ class Generator():
|
|||
LOG.debug(" Deleting Existing Baseline Templates Finished........")
|
||||
|
||||
return productsRemoved
|
||||
|
||||
|
||||
def runFromJava(siteId, destinationDir):
|
||||
generator = Generator()
|
||||
return generator.create(siteId, destinationDir)
|
|
@ -18,6 +18,13 @@
|
|||
# further licensing information.
|
||||
##
|
||||
# configureTextProducts.py preferences
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 11/10/14 #4953 randerso Added Hazard_TCV to templateProds
|
||||
##
|
||||
|
||||
# ---- NWS Products --------------------------------------------------------
|
||||
# contains a list of pil category values to automatically
|
||||
|
@ -72,7 +79,7 @@ NWSProducts = ['ADR', 'AFD', 'AFM', 'AQA', 'AVA', 'AVW', 'CAE', 'CCF', 'CDW', 'C
|
|||
#contains the products to be generated (e.g., AFM). These products
|
||||
#follow the Baseline, Region, Site technique.
|
||||
templateProds= ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF', 'HLS',
|
||||
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD']
|
||||
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD', 'Hazard_TCV']
|
||||
templateProdsWsaf= ['AFM', 'ZFP', 'CCF', 'CWF', 'CWF_Pacific', 'FWF', 'HLS',
|
||||
'FWFTable', 'FWM', 'GLF', 'MVF', 'NSH', 'PFM', 'SFT', 'SRF', 'OFF', 'AFD', 'SAF',
|
||||
'FWS', 'Hazard_TCV', 'Hazard_HLS']
|
||||
|
|
|
@ -20,20 +20,20 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
|||
Definition["outputFile"] = "{prddir}/TEXT/HLS.txt"
|
||||
Definition["database"] = "Official" # Source database
|
||||
Definition["debug"] = 1
|
||||
Definition["mapNameForCombinations"] = "Zones_MFL"
|
||||
Definition["defaultEditAreas"] = "Combinations_HLS_MFL"
|
||||
Definition["mapNameForCombinations"] = "Zones_<site>"
|
||||
Definition["defaultEditAreas"] = "Combinations_HLS_<site>"
|
||||
Definition["showZoneCombiner"] = 0 # 1 to cause zone combiner to display
|
||||
|
||||
Definition["productName"] = "LOCAL STATEMENT"
|
||||
|
||||
Definition["fullStationID" ] = "KMFL"
|
||||
Definition["wmoID" ] = "WTUS82"
|
||||
Definition["wfoCityState" ] = "MIAMI FL"
|
||||
Definition["pil" ] = "HLSMIA"
|
||||
Definition["textdbPil" ] = "MIAHLSMIA"
|
||||
Definition["awipsWANPil" ] = "KMFLHLSMIA"
|
||||
Definition["site"] = "MFL"
|
||||
Definition["wfoCity"] = "MIAMI"
|
||||
Definition["fullStationID" ] = "<fullStationID>"
|
||||
Definition["wmoID" ] = "<wmoID>"
|
||||
Definition["wfoCityState" ] = "<wfoCityState>"
|
||||
Definition["pil" ] = "<pil>"
|
||||
Definition["textdbPil" ] = "<textdbPil>"
|
||||
Definition["awipsWANPil" ] = "<awipsWANPil>"
|
||||
Definition["site"] = "<site>"
|
||||
Definition["wfoCity"] = "<wfoCity>"
|
||||
|
||||
Definition["areaName"] = "" #optional area name for product
|
||||
Definition["areaDictionary"] = "AreaDictionary"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import GenericHazards
|
||||
import JsonSupport
|
||||
import LocalizationSupport
|
||||
import string, time, os, types, copy, LogStream, collections
|
||||
import ModuleAccessor, SampleAnalysis, EditAreaUtils
|
||||
import math
|
||||
|
@ -6,8 +8,6 @@ import math
|
|||
|
||||
from AbsTime import *
|
||||
from StartupDialog import IFPDialog as Dialog
|
||||
from LockingFile import File
|
||||
from com.raytheon.uf.common.localization import PathManagerFactory
|
||||
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationType as LocalizationType
|
||||
AWIPS_ENVIRON = "AWIPS2"
|
||||
|
||||
|
@ -20,20 +20,20 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
|||
Definition["outputFile"] = "{prddir}/TEXT/TCV.txt"
|
||||
Definition["database"] = "Official" # Source database
|
||||
Definition["debug"] = 1
|
||||
Definition["mapNameForCombinations"] = "Zones_MFL"
|
||||
Definition["defaultEditAreas"] = "EditAreas_PublicZones_MFL"
|
||||
Definition["mapNameForCombinations"] = "Zones_<site>"
|
||||
Definition["defaultEditAreas"] = "EditAreas_PublicZones_<site>"
|
||||
Definition["showZoneCombiner"] = 1 # 1 to cause zone combiner to display
|
||||
|
||||
Definition["productName"] = "LOCAL WATCH/WARNING STATEMENT"
|
||||
|
||||
Definition["fullStationID" ] = "KMFL"
|
||||
Definition["wmoID" ] = "WTUS82"
|
||||
Definition["wfoCityState" ] = "MIAMI FL"
|
||||
Definition["pil" ] = "TCVMFL"
|
||||
Definition["textdbPil" ] = "MIATCVMFL"
|
||||
Definition["awipsWANPil" ] = "KMFLTCVMFL"
|
||||
Definition["site"] = "MFL"
|
||||
Definition["wfoCity"] = "MIAMI"
|
||||
Definition["fullStationID" ] = "<fullStationID>"
|
||||
Definition["wmoID" ] = "<wmoID>"
|
||||
Definition["wfoCityState" ] = "<wfoCityState>"
|
||||
Definition["pil" ] = "<pil>"
|
||||
Definition["textdbPil" ] = "<textdbPil>"
|
||||
Definition["awipsWANPil" ] = "<awipsWANPil>"
|
||||
Definition["site"] = "<site>"
|
||||
Definition["wfoCity"] = "<wfoCity>"
|
||||
|
||||
Definition["areaName"] = "" #optional area name for product
|
||||
Definition["areaDictionary"] = "AreaDictionary"
|
||||
|
@ -240,9 +240,6 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
|||
if error is not None:
|
||||
return error
|
||||
|
||||
# self._archiveTransmittedAdvisory()
|
||||
# return "Archived"
|
||||
|
||||
self._segmentList = self._determineSegments()
|
||||
print "Segment Information: ", self._segmentList, "\n\n"
|
||||
if len(self._segmentList) == 0:
|
||||
|
@ -844,67 +841,21 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
|||
|
||||
self._saveAdvisory("pending", self._currentAdvisory)
|
||||
|
||||
def _archiveTransmittedAdvisory(self):
|
||||
import unicodedata
|
||||
|
||||
pendingDict = self._loadAdvisory("pending")
|
||||
if pendingDict is None:
|
||||
return
|
||||
|
||||
stormName = pendingDict["StormName"]
|
||||
advisoryNumber = pendingDict["AdvisoryNumber"]
|
||||
|
||||
pendingDict["Transmitted"] = True
|
||||
|
||||
transmittedName = stormName + advisoryNumber
|
||||
transmittedName = unicodedata.normalize('NFKD', transmittedName).encode('ascii','ignore')
|
||||
|
||||
self._saveAdvisory(transmittedName, pendingDict)
|
||||
|
||||
if pendingDict["AllCAN"]:
|
||||
advisoryDirectoryPath = self._getLocalAdvisoryDirectoryPath()
|
||||
filenames = os.listdir(advisoryDirectoryPath)
|
||||
print "all filenames =", filenames
|
||||
stormAdvisories = filter(lambda filename: (stormName in filename) or \
|
||||
("pending" in filename),
|
||||
filenames)
|
||||
print "storm advisories =", stormAdvisories
|
||||
|
||||
for advisory in stormAdvisories:
|
||||
self._deleteAdvisory(self._getAdvisoryPath() + advisory)
|
||||
print "deleted advisory", advisory
|
||||
|
||||
def _deleteAdvisory(self, fullAdvisoryName):
|
||||
localizationFile = self._getLocalizationFile(LocalizationType.CAVE_STATIC,
|
||||
self._site,
|
||||
fullAdvisoryName)
|
||||
localizationFile.delete()
|
||||
|
||||
def _saveAdvisory(self, advisoryName, advisoryDict):
|
||||
import json
|
||||
|
||||
self._synchronizeAdvisories()
|
||||
|
||||
try:
|
||||
self._writeFileContents(LocalizationType.CAVE_STATIC,
|
||||
self._site,
|
||||
self._getAdvisoryFilename(advisoryName),
|
||||
json.dumps(advisoryDict))
|
||||
JsonSupport.saveToJson(LocalizationType.CAVE_STATIC,
|
||||
self._site,
|
||||
self._getAdvisoryFilename(advisoryName),
|
||||
advisoryDict)
|
||||
|
||||
print "SARAH: Wrote file contents for", self._getAdvisoryFilename(advisoryName)
|
||||
|
||||
self._synchronizeAdvisories()
|
||||
except Exception, e:
|
||||
print "SARAH Save Exception for", self._getAdvisoryFilename(advisoryName), ":", e
|
||||
|
||||
def _writeFileContents(self, loctype, siteID, filename, contents):
|
||||
pathManager = PathManagerFactory.getPathManager()
|
||||
context = pathManager.getContextForSite(loctype, siteID)
|
||||
localizationFile = pathManager.getLocalizationFile(context, filename)
|
||||
with File(localizationFile.getFile(), filename, 'w') as pythonFile:
|
||||
pythonFile.write(contents)
|
||||
|
||||
localizationFile.save()
|
||||
|
||||
def _getHazardsForHLS(self):
|
||||
hazardTable = self._argDict["hazards"]
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ import com.raytheon.uf.common.util.FileUtil;
|
|||
* Feb 27, 2013 #1447 dgilling Re-factor based on PythonPathIncludeUtil.
|
||||
* Mar 11, 2013 #1759 dgilling Add method getGfeConfigLF().
|
||||
* Sep 16, 2013 #1759 dgilling Move tests and autotests to GfeCavePyIncludeUtil.
|
||||
* Aug 22, 2014 3500 bclement added python path in getConfigIncludePath()
|
||||
* Aug 22, 2014 #3500 bclement added python path in getConfigIncludePath()
|
||||
* Nov 11, 2014 #4953 randerso Changed COMMON_GFE to public
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
|
@ -50,7 +51,7 @@ public class GfePyIncludeUtil extends PythonIncludePathUtil {
|
|||
|
||||
public static final String GFE = "gfe";
|
||||
|
||||
private static final String COMMON_GFE = FileUtil.join(PYTHON, GFE);
|
||||
public static final String COMMON_GFE = FileUtil.join(PYTHON, GFE);
|
||||
|
||||
public static final String ITOOL = FileUtil.join(GFE, "itool");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue