Merge "Omaha #4027 More GFE changes for Mixed Case WA" into omaha_15.1.1

Former-commit-id: 8c02aa8eba027eedb9ec8994f520c315c57ed150
This commit is contained in:
Ron Anderson 2015-04-21 08:30:03 -05:00 committed by Gerrit Code Review
commit b34c50594f
68 changed files with 817 additions and 707 deletions

View file

@ -299,7 +299,7 @@ class TextProduct(GenericHazards.TextProduct):
'''
if self._areaName != '':
self._areaName = ' FOR ' + self._areaName + '\n'
self._areaName = ' for ' + self._areaName + '\n'
# Fill in product dictionary information
productDict = collections.OrderedDict()

View file

@ -38,7 +38,7 @@ from java.io import File
# ------------ ---------- ----------- --------------------------
# 05/29/08 njensen Initial Creation.
# 12/10/14 #14946 ryu Add getTimeZones() function.
#
# 04/20/2015 #4027 randerso Fixes for formatter autotests
#
#
@ -223,10 +223,9 @@ def runFormatter(databaseID, site, forecastList, cmdLineVarDict, vtecMode,
argDict['creationTime'] = int(time.time()/60)*60.0
# Set the Site Time Zone
#tz = ifpClient.getSiteTimeZone(site)
#os.environ['TZ'] = tz
tz = str(ifpClient.getSiteTimeZone())
os.environ['TZ'] = tz
time.tzset()
# Create the formatter
formatter = TextFormatter.TextFormatter(dataMgr)
@ -239,6 +238,7 @@ def runFormatter(databaseID, site, forecastList, cmdLineVarDict, vtecMode,
forecasts = forecasts + forecast
logger.info("Text:\n" + str(forecasts))
try:
outputFile = argDict["outputFile"]
success = writeToFile(forecasts, outputFile, "w")
@ -426,6 +426,7 @@ def ppDef(definition):
def getVarDict(dspName, dataMgr, issuedBy, dataSource):
tz = str(dataMgr.getClient().getSiteTimeZone())
os.environ['TZ'] = tz
time.tzset()
productDef = displayNameDict[dspName][1]
productDef['database'] = dataSource
vdg = VarDictGroker.VarDictGroker(displayNameDict[dspName][0], productDef, dspName, issuedBy, dataMgr)

View file

@ -192,9 +192,8 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
# make a copy and change the key if we need to
newH = copy.deepcopy(h)
newH['id'] = eaList # preserve the old list of areas
# strip segments
if (newH['phen'], newH['sig']) not in self.__ncKeys or \
self.__siteID4 == 'PGUM':
# strip segments - updated to make sure GUM TRW/A hazards keep local ETN
if ((newH['phen'], newH['sig']) not in self.__ncKeys):
if string.find(newH['phensig'], ":") >= 0:
newH['phensig'] = newH['phen'] + '.' + newH['sig']

View file

@ -706,15 +706,15 @@ A Winter Weather Advisory for snow means that periods of snow will cause primari
]
def ctaPilCFW(self):
return [("***RIP CURRENTS CTA", """RIP CURRENTS ARE POWERFUL CHANNELS OF WATER FLOWING QUICKLY AWAY FROM SHORE...WHICH OCCUR MOST OFTEN AT LOW SPOTS OR BREAKS IN THE SANDBAR AND IN THE VICINITY OF STRUCTURES SUCH AS GROINS...JETTIES AND PIERS. HEED THE ADVICE OF LIFEGUARDS...BEACH PATROL FLAGS AND SIGNS.
return [("***RIP CURRENTS CTA", """Rip currents are powerful channels of water flowing quickly away from shore...which occur most often at low spots or breaks in the sandbar and in the vicinity of structures such as groins...jetties and piers. Heed the advice of lifeguards...beach patrol flags and signs.
IF YOU BECOME CAUGHT IN A RIP CURRENT...YELL FOR HELP. REMAIN CALM...do not exhaust yourself and stay afloat while waiting for help. If you have to swim out of a rip current...SWIM PARALLEL TO SHORE and back toward the beach when possible. DO NOT ATTEMPT TO SWIM DIRECTLY AGAINST A RIP CURRENT as you will tire quickly."""),
If you become caught in a rip current...yell for help. Remain calm...do not exhaust yourself and stay afloat while waiting for help. If you have to swim out of a rip current...SWIM PARALLEL TO SHORE and back toward the beach when possible. Do not attempt to swim directly against a rip current as you will tire quickly."""),
("***LONGSHORE CURRENTS CTA", """Longshore currents commonly occur when waves approach the shoreline at an angle. They can be particularly dangerous near a jetty or pier."""),
("***SNEAKER WAVES CTA", """Add cta here."""),
("***RED TIDE CTA", """Add cta here"""),
("***SEA NETTLES CTA", """Add cta here"""),
("***TSUNAMI DEBRIS CTA", """Add cta here"""),
("***OTHER BEACH HAZARDS CTA", """Add cta here"""),
("***SNEAKER WAVES CTA", """Add CTA here."""),
("***RED TIDE CTA", """Add CTA here"""),
("***SEA NETTLES CTA", """Add CTA here"""),
("***TSUNAMI DEBRIS CTA", """Add CTA here"""),
("***OTHER BEACH HAZARDS CTA", """Add CTA here"""),
]
def ctaPilCWF(self):

View file

@ -145,12 +145,12 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
def useSkyPopWx_consolidation(self, tree, node):
# If set to 1, the skyPopWx phrase will consolidate weather keys that
# span all time ranges to produce:
# PARTLY CLOUDY WITH A CHANCE OF RAIN.
# SNOW IN THE MORNING...THEN SLEET IN THE AFTERNOON.
# Partly cloudy with a chance of rain.
# Snow in the morning...then sleet in the afternoon.
#
# instead of:
# PARTLY CLOUDY. CHANCE OF RAIN AND SNOW IN THE MORNING
# ...THEN A CHANCE OF RAIN AND SLEET IN THE AFTERNOON.
# Partly cloudy. Chance of rain and snow in the morning
# ...then a chance of rain and sleet in the afternoon.
return 0
def skyPopWx_excludePoP_flag(self, tree, node):
@ -256,6 +256,9 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
subkeyDict[subkey] = 1
else:
subkeyDict[subkey] += 1
if self.__dict__.get("_leDebug", 0):
print "subkeyDict", subkeyDict
# Find subkeys to disable in first phrase and second phrase,
# respectively
list1 = []
@ -266,7 +269,10 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
list2.append(subkey)
else:
list1.append(subkey)
if self.__dict__.get("_leDebug", 0): print "list1, list2", list1, list2
if self.__dict__.get("_leDebug", 0):
print "list1", list1
print "list2", list2
if len(list1) > 0 and len(list2) > 0:
newPhrase = self.splitWxPhrase(
tree, node, list1, list2,
@ -516,20 +522,20 @@ class CombinedPhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRe
# Number of sub-phrases (length) Wx Sky includeSky
#
# 1 similar similar 1
# MOSTLY SUNNY WITH A 50 PERCENT CHANCE OF RAIN.
# Mostly sunny with a 50 percent chance of rain.
#
# 2 different similar 0
# MOSTLY SUNNY. A CHANCE OF RAIN THEN A SLIGHT CHANCE OF SNOW
# IN THE AFTERNOON.
# Mostly sunny. A chance of rain then a slight chance of snow
# in the afternoon.
#
# 1 similar different 0
# MOSTLY SUNNY IN THE MORNING THEN BECOMING PARTLY CLOUDY. A
# 50 PERCENT CHANCE OF RAIN.
# Mostly sunny in the morning then becoming partly cloudy. A
# 50 percent chance of rain.
#
# 2 different different 1
# MOSTLY SUNNY WITH A CHANCE OF RAIN THEN PARTLY CLOUDY WITH
# A SLIGHT CHANCE OF SNOW IN THE AFTERNOON. A 50 PERCENT CHANCE
# OF RAIN AND SNOW.
# Mostly sunny with a chance of rain then partly cloudy with
# a slight chance of snow in the afternoon. A 50 percent chance
# of rain and snow.
#
# Compare sky for similarity in the 1st and 2nd half of the period.
# Note: We can't count on Sky having a temporal resolution of [6],

View file

@ -123,7 +123,7 @@ class ConfigVariables(TextUtils.TextUtils):
"SKY/WEATHER.........":"SKY/WEATHER.........",
" 24 HR TREND......":" 24 HR TREND......",
"unchanged":"unchanged",
"missing":"missing",
"missing":"MISSING",
"MinT":"lows",
"MaxT":"highs",
"MinT_FireWx": "MIN TEMPERATURE.....",
@ -145,23 +145,23 @@ class ConfigVariables(TextUtils.TextUtils):
"CWR.................":"CHC OF WETTING RAIN.",
"MARINE LAYER........":"MARINE LAYER........",
# Used for Headlines
"EXPECTED" : "EXPECTED",
"IN EFFECT" : "IN EFFECT",
"EXPECTED" : "expected",
"IN EFFECT" : "in effect",
# Used for single values
"around": "around",
"through the day": "through the day",
"through the night": "through the night",
# Used for Tropical
"iminHR":"HURRICANE CONDITIONS",
"iminTS":"TROPICAL STORM CONDITIONS",
"iminTSposHR":"TROPICAL STORM CONDITIONS WITH HURRICANE CONDITIONS POSSIBLE",
"posTS":"TROPICAL STORM CONDITIONS POSSIBLE",
"posTSbcmgposHR":"TROPICAL STORM CONDITIONS POSSIBLE WITH HURRICANE CONDITIONS ALSO POSSIBLE",
"expTS":"TROPICAL STORM CONDITIONS EXPECTED",
"posHR":"HURRICANE CONDITIONS POSSIBLE",
"expHR":"HURRICANE CONDITIONS EXPECTED",
"expTSposHR":"TROPICAL STORM CONDITIONS EXPECTED WITH HURRICANE CONDITIONS POSSIBLE",
"posTSorHR":"TROPICAL STORM OR HURRICANE CONDITIONS POSSIBLE" ,
"iminHR":"Hurricane conditions",
"iminTS":"Tropical storm conditions",
"iminTSposHR":"Tropical storm conditions with hurricane conditions possible",
"posTS":"Tropical storm conditions possible",
"posTSbcmgposHR":"Tropical storm conditions possible with hurricane conditions also possible",
"expTS":"Tropical storm conditions expected",
"posHR":"Hurricane conditions possible",
"expHR":"Hurricane conditions expected",
"expTSposHR":"Tropical storm conditions expected with hurricane conditions possible",
"posTSorHR":"Tropical storm or hurricane conditions possible" ,
}
def phrase_descriptor(self, tree, node, key, value):
@ -523,12 +523,12 @@ class ConfigVariables(TextUtils.TextUtils):
def highValue_threshold_dict(self, tree, node):
# If high wind conditions report both "becoming" and
# "increasing/decreasing"
# SOUTHEAST WINDS AROUND 70 MPH BECOMING SOUTH
# AND INCREASING TO AROUND 105 MPH
# Southeast winds around 70 mph becoming south
# and increasing to around 105 mph
# Otherwise, it will just be reported with "increasing"
# or "becoming":
# SOUTHEAST WINDS AROUND 20 MPH BECOMING SOUTH
# AROUND 15 MPH
# Southeast winds around 20 mph becoming south
# around 15 mph
return {
"Wind": 45, # knots or mph depending on product
"Wind20ft": 45, # knots or mph depending on product
@ -818,8 +818,8 @@ class ConfigVariables(TextUtils.TextUtils):
def embedded_vector_descriptor_flag_dict(self, tree, node):
# If set to 1, the descriptor will be embedded in the phrase:
# such as "NORTH WINDS 20 to 25 KNOTS BECOMING LIGHT AND VARIABLE"
# instead of "WINDS NORTH 20 to 25 KNOTS BECOMING LIGHT AND VARIABLE"
# such as "North winds 20 to 25 knots becoming light and variable"
# instead of "Winds north 20 to 25 knots becoming light and variable"
return {
"Wind": 1,
"Wind20ft": 1,
@ -960,9 +960,9 @@ class ConfigVariables(TextUtils.TextUtils):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -168,7 +168,6 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
if headlineWords == "": # Don't process the "<None>" key
continue
hookWords = self.hazard_hook(tree, node, key, "", "",tr.startTime(), tr.endTime())
headlineWords = self.convertToLower(headlineWords)
headlinePhrase = "..." + headlineWords + timeDescriptor +hookWords + "...\n"
words = words + headlinePhrase
@ -682,7 +681,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = etext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
return endPrefix + ' ' + hourStr + ' ' + hourTZstr + ' ' + \
description
@ -691,13 +690,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = etext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = endPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(etext)):
hourStr, hourTZstr, othDescription = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description
return s
@ -722,11 +721,11 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
#special cases NOON
if shourStr == "12 PM":
shourStr = "Noon"
shourStr = "noon"
#special cases NOON
if ehourStr == "12 PM":
ehourStr = "Noon"
ehourStr = "noon"
# special case EARLY THIS MORNING and THIS MORNING, replace with
# just THIS MORNING
@ -755,14 +754,14 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + endPrefix + ' ' + ehourStr + ' ' + ehourTZstr + ' '
for x in xrange(1, len(etext)):
hourStr, hourTZstr, description = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + edescription
return s
@ -774,7 +773,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + sdescription + ' ' + endPrefix + ' ' + ehourStr + \
' ' + ehourTZstr + ' '
@ -782,7 +781,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + edescription
return s
@ -797,13 +796,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description0 = stext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = startPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(stext)):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description0 + ' '
@ -849,13 +848,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description0 = stext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = startPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(stext)):
hourStr, hourTZstr, description = stext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description0 + ' '
@ -910,13 +909,13 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
hourStr, hourTZstr, description0 = etext[0]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + endPrefix + ' ' + hourStr + ' ' + hourTZstr + ' '
for x in xrange(1, len(etext)):
hourStr, hourTZstr, description = etext[x]
#special cases NOON
if hourStr == "12 PM":
hourStr = "Noon"
hourStr = "noon"
s = s + "/" + hourStr + ' ' + hourTZstr + "/ "
s = s + description0 + ' '
@ -1244,7 +1243,7 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
(0*HR, 24*HR, "<dayOfWeek>"),] #midnght-1159pm
subsequentDay = [
(0*HR, 0*HR+1, "<dayOfWeek-1> Night"), #midnght
(0*HR, 0*HR+1, "<dayOfWeek-1> night"), #midnght
(0*HR, 24*HR, "<dayOfWeek>"),] #midnght-1159pm
@ -1303,11 +1302,11 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
#special cases NOON
if hourStr == "12 PM" and description == "today":
hourStr = "Noon"
hourStr = "noon"
#special cases MIDNIGHT
if hourStr == "12 AM":
hourStr = "Midnight"
hourStr = "midnight"
os.environ["TZ"] = myTimeZone # reset the defined time zone
@ -1602,7 +1601,6 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
#assemble the hazard type
hazStr = hazard['hdln']
hazStr = self.convertToLower(hazStr)
# if the hazard is a convective watch, tack on the etn
phenSig = hazard['phen'] + "." + hazard['sig']
@ -2068,9 +2066,9 @@ class DiscretePhrases(PhraseBuilder.PhraseBuilder):
# want A or AN?
if addA:
if phrase[0] in ['A','E','I','O','U','a','e','i','o','u']:
phrase = "AN " + phrase
phrase = "an " + phrase
else:
phrase = "A " + phrase
phrase = "a " + phrase
return phrase

View file

@ -150,8 +150,8 @@ Definition["outputFile"] = "{prddir}/TEXT/FWS.txt"
# Definitions to insert unrepresentativeness of the forecast
# instructions for the user.
Definition["insertUnrepresentStatement"] = 1 # Use 1 for yes, 0 for no
Definition["unrepresentStatement"] = "IF CONDITIONS BECOME UNREPRESENTATIVE..." + \
"CONTACT THE NATIONAL WEATHER\nSERVICE."
Definition["unrepresentStatement"] = "If conditions become unrepresentative..." + \
"contact the National Weather\nService."
# Definitions to insert the FWF discussion from a separate file.
# Discussion is edited separately in XNOW for the FWF forecast.
# Advantage of this is to have a first guess for the discussion in
@ -188,8 +188,8 @@ Definition["stqPil"] = "STQ<site>" # STQ pil
# Definitions to insert unrepresentativeness of the forecast
# instructions for the user.
#Definition["insertUnrepresentStatement"] = 0 # Use 1 for yes, 0 for no
#Definition["unrepresentStatement"] = "IF CONDITIONS BECOME UNREPRESENTATIVE..." + \
# "CONTACT THE NATIONAL WEATHER\nSERVICE."
#Definition["unrepresentStatement"] = "If conditions become unrepresentative..." + \
# "contact the National Weather\nService."
# wind20ftHeader: This definition set to "1" allows offices to
# format winds in this format...
@ -1848,7 +1848,7 @@ class FWS_Overrides:
# Code to ensure the wildfireElementList parameters are included in
# the FWS product (if this is a wildfire incident) was added to this
# method.
if self._fireType == "WILDFIRE":
if self._fireType.upper() == "WILDFIRE":
for element in self._wildfireElementList:
for elementList in elementLists:
if element not in elementList and len(elementList) != 0:
@ -2008,7 +2008,7 @@ class FWS_Overrides:
self._fireTime + ' ' + self._fireDate + ' ' + rtz,
'%H%M %m/%d/%y %Z')
fcst = fcst + time.strftime(
'FORECAST IS BASED ON ' + requestWords + ' TIME OF %H%M %Z ON %B %d. ',
'Forecast is based on ' + requestWords + ' time of %H%M %Z on %B %d. ',
self._fireDateTime)
else:
offset = 0
@ -2063,7 +2063,7 @@ class FWS_Overrides:
fireDateTime = time.strptime(
self._fireTime + ' ' + self._fireDate, '%H%M %m/%d/%y')
fcst = fcst + time.strftime(
'FORECAST IS BASED ON ' + requestWords + ' TIME OF %H%M ' + rtz + ' ON %B %d. ',
'Forecast is based on ' + requestWords + ' time of %H%M ' + rtz + ' on %B %d. ',
fireDateTime)
fcst = fcst + "\n"
self._makeFireTimeRange()
@ -2085,18 +2085,18 @@ class FWS_Overrides:
# This is a new method that Matt Davis wrote. Figures out whether or not
# we are using a ignition time, request time, or incident time.
def _getRequestWords(self):
if self._fireType == "WILDFIRE":
return "REQUEST"
elif self._fireType == "PRESCRIBED":
return "IGNITION"
if self._fireType.upper() == "WILDFIRE":
return "request"
elif self._fireType.upper() == "PRESCRIBED":
return "ignition"
else:
return "INCIDENT"
return "incident"
# Import the discussion from a previously edited discussion file.
def _makeDiscussion(self, fcst, argDict):
discussionHeader = ""
discussionHeader = ".DISCUSSION...\n"
discussionHeader = ".Discussion...\n"
if self._insertDiscussionFromFile == 1:
discussion = ""
@ -2109,7 +2109,7 @@ class FWS_Overrides:
discussion = string.join(string.split(discussion,"\n\n"),"\n")
return fcst + discussionHeader + discussion + "\n"
else:
discussion = "...PUT DISCUSSION TEXT HERE..."
discussion = "...Put discussion text here..."
return fcst + discussionHeader + discussion + "\n\n"
elif self._insertDiscussionFromFile == 2:
version = 0
@ -2121,7 +2121,7 @@ class FWS_Overrides:
disFlag = 0
foundDiscussion = 0
for line in product:
if string.find(line,"DISCUSSION...") != -1:
if string.find(line,"Discussion...") != -1:
disFlag = 1
foundDiscussion = 1
try:
@ -2138,7 +2138,7 @@ class FWS_Overrides:
if foundDiscussion:
return fcst + discussion + "\n\n"
else:
discussion = "...PUT DISCUSSION TEXT HERE..."
discussion = "...Put discussion text here..."
return fcst + discussionHeader + discussion + "\n\n"
else:
return fcst + discussionHeader + "\n\n\n"
@ -2290,7 +2290,7 @@ class FWS_Overrides:
if "Include Day 8-14 Outlook?" not in self._extendedQuestions:
return fcst
outlookHeader = ".OUTLOOK FOR " + self._outlookDay8Label + " THROUGH " \
outlookHeader = ".Outlook for " + self._outlookDay8Label + " through " \
+ self._outlookDay14Label + "...\n"
outlookHeader = string.upper(outlookHeader)
@ -2305,7 +2305,7 @@ class FWS_Overrides:
outlook = string.join(string.split(outlook,"\n\n"),"\n")
return fcst + outlookHeader + outlook + "\n"
else:
outlook = "...PUT 8 TO 14 DAY OUTLOOK TEXT HERE..."
outlook = "...Put 8 to 14 day outlook text here..."
return fcst + outlookHeader + outlook + "\n\n"
elif self._insertDiscussionFromFile == 2:
version = 0
@ -2327,7 +2327,7 @@ class FWS_Overrides:
if foundOutlook:
return fcst + outlookHeader + outlook + "\n\n"
else:
outlook = "...PUT 8 TO 14 DAY OUTLOOK TEXT HERE..."
outlook = "...Put 8 to 14 day outlook text here..."
return fcst + outlookHeader + outlook + "\n\n"
else:
return fcst + outlookHeader + "\n\n\n"
@ -2341,17 +2341,18 @@ class FWS_Overrides:
newFireName = self._fireName + "..." + self._otherAgencyName
else:
newFireName = self._fireName + "..." + self._requestingAgency
productLabel = self._productName + " FOR " + newFireName
productLabel = self._productName + " for " + newFireName
productLabel = self.checkTestMode(argDict, productLabel)
issuedByString = self.getIssuedByString()
# Product header
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" + productLabel + \
"\nNATIONAL WEATHER SERVICE " + self._wfoCityState + \
"\nNational Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Add time disclaimer
self._fireTR = None
@ -2378,9 +2379,9 @@ in the future. *|''' % self._timeLabel
tagLineString = ""
else:
tagLineString = ".TAG " + self._webSiteTag + "/" + self._wfoID + "\n"
fcst = fcst + "$$\nFORECASTER..." + forecasterString + "\n" + \
"REQUESTED BY..." + self._agencyContact + "\n" + \
"TYPE OF REQUEST..." + self._fireType + "\n" + tagLineString
fcst = fcst + "$$\nForecaster..." + forecasterString + "\n" + \
"Requested by..." + self._agencyContact + "\n" + \
"Type of request..." + self._fireType + "\n" + tagLineString
#self.storeAWIPS(fcst, self._awipsProductID)
self.setProgressPercentage(100)
self.progressMessage(0, 100, self._displayName + " Complete")
@ -2516,39 +2517,39 @@ in the future. *|''' % self._timeLabel
pass
return [
("Next Day", 24 + self.DAY(), 24 + self.NIGHT(), 24 + self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
".Today...", "early in the morning", "late in the afternoon",
1, narrativeDef),
("Morning", self.DAY(), self.NIGHT(), self.NIGHT(),
".TODAY...", "early in the morning", "late in the afternoon",
".Today...", "early in the morning", "late in the afternoon",
1, narrativeDef),
("Morning Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning", "late in the afternoon",
".Rest of Today...", "early in the morning", "late in the afternoon",
1, narrativeDef),
("Afternoon Update", "issuanceHour", self.NIGHT(), self.NIGHT(),
".REST OF TODAY...", "early in the morning","late in the afternoon",
".Rest of Today...", "early in the morning","late in the afternoon",
1, narrativeDef),
# End times are tomorrow:
("Afternoon", self.NIGHT(), 24 + self.DAY(), 24 + self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
".Tonight...", "late in the night", "early in the evening",
1, narrativeDef),
("Afternoon with 4 periods", self.NIGHT(), 24 + self.DAY(), 24 + self.DAY(),
".TONIGHT...", "late in the night", "early in the evening",
".Tonight...", "late in the night", "early in the evening",
1, narrativeDef),
("Evening Update", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
".REST OF TONIGHT...", "late in the night","early in the evening",
".Rest of Tonight...", "late in the night","early in the evening",
1, narrativeDef),
("Evening Update with 4 periods", "issuanceHour", 24 + self.DAY(), 24 + self.DAY(),
".REST OF TONIGHT...", "late in the night","early in the evening",
".Rest of Tonight...", "late in the night","early in the evening",
1, narrativeDef),
# For the early morning update, this produces:
# REST OF TONIGHT:
# MONDAY
# MONDAY NIGHT
# Rest of Tonight:
# Monday
# Monday Night
("Early Morning Update", "issuanceHour", self.DAY(), self.DAY(),
".REST OF TONIGHT...", "early in the morning","late in the afternoon",
".Rest of Tonight...", "early in the morning","late in the afternoon",
0, narrativeDef),
("Early Morning Update with 4 periods", "issuanceHour", self.DAY(), self.DAY(),
".REST OF TONIGHT...", "early in the morning","late in the afternoon",
".Rest of Tonight...", "early in the morning","late in the afternoon",
0, narrativeDef),
]
@ -2961,11 +2962,11 @@ in the future. *|''' % self._timeLabel
if self._withIgnitionTimes == "yes":
dayNight = self.getPeriod(node.getTimeRange(), 1)
if dayNight == self.DAYTIME():
tempElement = "MAX"
rhElement = "MIN"
tempElement = "Max"
rhElement = "Min"
else:
tempElement = "MIN"
rhElement = "MAX"
tempElement = "Min"
rhElement = "Max"
if elementName == "MaxT" or elementName == "MinT":
ignitionElement = "T"
elementType = tempElement
@ -2978,7 +2979,7 @@ in the future. *|''' % self._timeLabel
if ignitionStats is not None:
ignitionPhrase = `int(self.getValue(ignitionStats))`
reqType = self._getRequestWords()
words = ignitionPhrase + units + " AT " + reqType + "..." + elementType + " " + igWords
words = ignitionPhrase + units + " at " + reqType + "..." + elementType + " " + igWords
else:
words = elementType + " " + igWords
else:
@ -3019,7 +3020,7 @@ in the future. *|''' % self._timeLabel
igMagStr = `int(ignitionWindStats[0])`
igDirStr = self.vector_dir(int(ignitionWindStats[1]))
reqType = self._getRequestWords()
igWords = "WINDS " + igDirStr + " AT " + igMagStr + " MPH AT " + reqType + "...OTHERWISE "
igWords = "Winds " + igDirStr + " at " + igMagStr + " mph at " + reqType + "...otherwise "
words = igWords + words
node.set("descriptor", "")
@ -3127,11 +3128,11 @@ in the future. *|''' % self._timeLabel
dayNight = self.getPeriod(node.getTimeRange(), 1)
if dayNight == self.DAYTIME():
vr = int(maxVal)
ventType = "MAX"
ventType = "Max"
mergeMethod = "Max"
else:
vr = int(minVal)
ventType = "MIN"
ventType = "Min"
mergeMethod = "Min"
vrCat = self.smokeDispersal_valueStr(vr)
words = ventType + "..." + vrCat + " " + " /" + `vr` + " knot-ft/"
@ -3139,7 +3140,7 @@ in the future. *|''' % self._timeLabel
ignitionDispersal = tree.stats.get(
"VentRate", self._fireTR, node.getAreaLabel(), mergeMethod=mergeMethod)
vrCat = self.smokeDispersal_valueStr(ignitionDispersal)
igWords = vrCat + " /" + `int(ignitionDispersal)` + " KNOT-FT/ AT " + reqType + ". \n"
igWords = vrCat + " /" + `int(ignitionDispersal)` + " knot-ft/ at " + reqType + ". \n"
words = igWords + " " + words
else:
# Handle phrase with range if not including ignition time
@ -3193,17 +3194,17 @@ in the future. *|''' % self._timeLabel
# Single Value input
if mix1 == mix2:
words = `mix1` + " " + outUnits + " agl"
words = `mix1` + " " + outUnits + " AGL"
# Range
else:
words = `mix1`+ "-" + `mix2` + " " + outUnits + " agl"
words = `mix1`+ "-" + `mix2` + " " + outUnits + " AGL"
# Handle ignition time
if self._checkFireTR(node.getTimeRange()):
reqType = self._getRequestWords()
ignitionMixStats = tree.stats.get(
"MixHgt", self._fireTR, node.getAreaLabel(), mergeMethod="Max")
igWords = `int(ignitionMixStats)` + " " + outUnits + " agl at " + reqType +"...otherwise "
igWords = `int(ignitionMixStats)` + " " + outUnits + " AGL at " + reqType +"...otherwise "
words = igWords + words
return self.setWords(node, words)
@ -3250,7 +3251,7 @@ in the future. *|''' % self._timeLabel
reqType = self._getRequestWords()
hainesDict = self.hainesDict()
words = ignitionPhrase + " " + hainesDict[int(ignitionPhrase)] + \
" AT " + reqType + "...MAX " + `haines1`
" at " + reqType + "...max " + `haines1`
ignitionFlag = 1
if not ignitionFlag:
haines1, haines2 = self.getValue(stats, "MinMax")
@ -3409,23 +3410,23 @@ in the future. *|''' % self._timeLabel
if height is None:
return self.setWords(node.parent, "MISSING")
if dir >= 22.5 and dir < 67.5:
dirWords = "NORTHEAST"
dirWords = "northeast"
elif dir >= 67.5 and dir < 112.5:
dirWords = "EAST"
dirWords = "east"
elif dir >= 112.5 and dir < 157.5:
dirWords = "SOUTHEAST"
dirWords = "southeast"
elif dir >= 157.5 and dir < 202.5:
dirWords = "SOUTH"
dirWords = "south"
elif dir >= 202.5 and dir < 247.5:
dirWords = "SOUTHWEST"
dirWords = "southwest"
elif dir >= 247.5 and dir < 292.5:
dirWords = "WEST"
dirWords = "west"
elif dir >= 292.5 and dir < 337.5:
dirWords = "NORTHWEST"
dirWords = "northwest"
else:
dirWords = "NORTH"
dirWords = "north"
heightWords = `int(height + 0.5)`
words = dirWords + " SWELL " + heightWords + " FEET"
words = dirWords + " swell " + heightWords + " feet"
return self.setWords(node, words)
def ceiling_phrase(self):

View file

@ -597,7 +597,7 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
### Humidity
def humidityRecovery_percentage(self, tree, node):
# If the maximum humidity is greater than this percentage,
# humidity recovery will be EXCELLENT.
# humidity recovery will be Excellent.
return 50
def humidityRecovery_phrase(self):
@ -634,7 +634,7 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
return self.setWords(node.parent, "MISSING")
maxRH = self.getValue(curStats, "Max")
if maxRH > self.humidityRecovery_percentage(tree, node):
return self.setWords(node, "EXCELLENT")
return self.setWords(node, "Excellent")
timeRange = node.getTimeRange()
prevTimeRange = self.adjustTimeRange(timeRange, -24)
prevStats = tree.stats.get(elementName, prevTimeRange, node.getAreaLabel(),
@ -660,15 +660,15 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
# editAreaNames = ["area1", "area2"]
# if self.currentAreaContains(tree, editAreaNames):
# return [
# (15, "POOR"),
# (20, "FAIR"),
# (30, "GOOD"),
# (15, "Poor"),
# (20, "Fair"),
# (30, "Good"),
# ]
return [
(25, "POOR"),
(55, "MODERATE"),
(70, "GOOD"),
(100,"EXCELLENT"),
(25, "Poor"),
(55, "Moderate"),
(70, "Good"),
(100,"Excellent"),
]
### LAL
@ -865,10 +865,10 @@ class FirePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRelate
# Single Value input
if mix1 == mix2:
words = `mix1` + " " + outUnits + " agl"
words = `mix1` + " " + outUnits + " AGL"
# Range
else:
words = `mix1`+ "-" + `mix2` + " " + outUnits + " agl"
words = `mix1`+ "-" + `mix2` + " " + outUnits + " AGL"
return self.setWords(node, words)
###---------------------------------------------------------

View file

@ -536,7 +536,7 @@ class Header(EditAreaUtils.EditAreaUtils, StringUtils.StringUtils):
lineLength=66, areaDictName="AreaDictionary", addPeriod = False,
forceAlphaSort=False):
# Returns a list of cities (from the AreaDictionary)
# Appends an " AND " instead of "..." for the last city mentioned.
# Appends an " and " instead of "..." for the last city mentioned.
# Access the UGC information for the area(s) if available
areaDict = ModuleAccessor.ModuleAccessor().variable(areaDictName, "AreaDictionary")
@ -557,7 +557,7 @@ class Header(EditAreaUtils.EditAreaUtils, StringUtils.StringUtils):
for c in cities:
cityString = cityString + "..." + c
cityString = self.replaceLast(cityString, "...", " AND ")
cityString = self.replaceLast(cityString, "...", " and ")
if len(cityString) == 0:
return ""
else:
@ -687,7 +687,7 @@ class Header(EditAreaUtils.EditAreaUtils, StringUtils.StringUtils):
first = 0
else:
result = result + "..." + county
result = self.replaceLast(result, "...", " AND ")
result = self.replaceLast(result, "...", " and ")
return result
def replaceLast(self, str, str1, str2):

View file

@ -403,6 +403,7 @@ class MarinePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRela
#print "\n in swell words"
periodFlag = node.getAncestor("periodFlag")
statDict = node.getStatDict()
#Check for Swell alone
swell2 = self.getStats(statDict, "Swell2")
if swell2 is None:
@ -526,28 +527,28 @@ class MarinePhrases(ScalarPhrases.ScalarPhrases, VectorRelatedPhrases.VectorRela
fcst = re.sub(r'(?i)(\W)SOUTHEAST(\W)', r'\1SE\2',fcst)
fcst = re.sub(r'(?i)(\W)SOUTHWEST(\W)', r'\1SW\2',fcst)
fcst = re.sub(r'(?i)(\W)NORTHWEST(\W)', r'\1NW\2',fcst)
fcst = re.sub(r'(?i)(\W)KNOTS?(\W)', r'\1KT\2',fcst)
fcst = re.sub(r'(?i)(\W)KNOTS?(\W)', r'\1kt\2',fcst)
## fcst = re.sub(r'(?i)(\W)FOOT(\W)', r'\1FT\2',fcst)
fcst = re.sub(r'(?i)(\W)FEET(\W)', r'\1FT\2',fcst)
fcst = re.sub(r'(?i)(\W)FEET(\W)', r'\1ft\2',fcst)
fcst = re.sub(r'(?i)(\W)POSITION(\W)', r'\1PSN\2',fcst)
fcst = re.sub(r'(?i)(\W)VISIBILITY(\W)', r'\1VSBY\2',fcst)
fcst = re.sub(r'(?i)(\W)THUNDERSTORM', r'\1TSTM',fcst)
fcst = re.sub(r'(?i)(\W)AVERAGE(\W)', r'\1AVG\2',fcst)
fcst = re.sub(r'(?i)(\W)NAUTICAL MILES?(\W)', r'\1NM\2',fcst)
fcst = re.sub(r'(?i)(\W)NAUTICAL MILES?(\W)', r'\1nm\2',fcst)
fcst = re.sub(r'(?i)(\W)ATLANTIC(\W)', r'\1ATLC\2',fcst)
fcst = re.sub(r'(?i)(\W)FATHOMS?(\W)', r'\1FM\2',fcst)
fcst = re.sub(r'(?i)(\W)FATHOMS?(\W)', r'\1fm\2',fcst)
fcst = re.sub(r'(?i)(\W)LONGITUDE(\W)', r'\1LONG\2',fcst)
fcst = re.sub(r'(?i)(\W)PACIFIC(\W)', r'\1PAC\2',fcst)
fcst = re.sub(r'(?i)(\W)DEGREES?(\W)', r'\1DEG\2',fcst)
fcst = re.sub(r'(?i)(\W)MILLIBARS?(\W)', r'\1MB\2',fcst)
fcst = re.sub(r'(?i)(\W)DEGREES?(\W)', r'\1deg\2',fcst)
fcst = re.sub(r'(?i)(\W)MILLIBARS?(\W)', r'\1mb\2',fcst)
fcst = re.sub(r'(?i)(\W)PRESSURE(\W)', r'\1PRES\2',fcst)
fcst = re.sub(r'(?i)(\W)SUNDAY(\W)', r'\1SUN\2',fcst)
fcst = re.sub(r'(?i)(\W)MONDAY(\W)', r'\1MON\2',fcst)
fcst = re.sub(r'(?i)(\W)TUESDAY(\W)', r'\1TUE\2',fcst)
fcst = re.sub(r'(?i)(\W)WEDNESDAY(\W)', r'\1WED\2',fcst)
fcst = re.sub(r'(?i)(\W)THURSDAY(\W)', r'\1THU\2',fcst)
fcst = re.sub(r'(?i)(\W)FRIDAY(\W)', r'\1FRI\2',fcst)
fcst = re.sub(r'(?i)(\W)SATURDAY(\W)', r'\1SAT\2',fcst)
fcst = re.sub(r'(?i)(\W)SUNDAY(\W)', r'\1Sun\2',fcst)
fcst = re.sub(r'(?i)(\W)MONDAY(\W)', r'\1Mon\2',fcst)
fcst = re.sub(r'(?i)(\W)TUESDAY(\W)', r'\1Tue\2',fcst)
fcst = re.sub(r'(?i)(\W)WEDNESDAY(\W)', r'\1Wed\2',fcst)
fcst = re.sub(r'(?i)(\W)THURSDAY(\W)', r'\1Thu\2',fcst)
fcst = re.sub(r'(?i)(\W)FRIDAY(\W)', r'\1Fri\2',fcst)
fcst = re.sub(r'(?i)(\W)SATURDAY(\W)', r'\1Sat\2',fcst)
fcst = re.sub(r'^ ', r'',fcst)
return fcst

View file

@ -32,6 +32,7 @@
# 12/28/2012 DR 15596 J.Zeng Added checkWeatherSimilarity
# for two lists based on Virgil's
# suggestion
# 04/20/2015 4027 randerso Changes for mixed case product generation.
# ----------------------------------------------------------------------------
import types
@ -1882,7 +1883,7 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
if stats1 == stats2:
#print 'checkWx return 1'
return 1
# Check for equal length of statistics
if len(stats1) == len(stats2):
# If there is only one subkey to worry about
@ -3571,6 +3572,7 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
# Initialize so that we are ready to use the thenConnector
# if appropriate
phrase.set("useThenConnector", 1)
useThenConnector = phrase.get("useThenConnector")
prevEnd = prev.getTimeRange().endTime()
# If the start time of this subPhrase is the same
@ -3585,6 +3587,8 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
# Can re-set connector so we are ready to use the
# then connector on the next subPhrase
phrase.set("useThenConnector", 1)
subPhrase.set("words", subPhrase.get("words").capitalize())
return connector
def visConnector(self, tree, subPhrase):
@ -3677,8 +3681,8 @@ class PhraseBuilder(ConfigVariables.ConfigVariables,
else:
# If high wind conditions report both "becoming" and
# "increasing/decreasing"
# SOUTHEAST WINDS AROUND 70 MPH BECOMING SOUTH
# AND INCREASING TO AROUND 105 MPH
# Southeast winds around 70 mph becoming south
# and increasing to around 105 mph
increasing = mag1 < mag2
if max(mag1, mag2) > self.highValue_threshold(
tree, subPhrase, elementName, elementName):

View file

@ -697,12 +697,12 @@ class TextProduct(AreaFcst.TextProduct):
def useSkyPopWx_consolidation(self, tree, node):
# If set to 1, the skyPopWx phrase will consolidate weather keys that
# span all time ranges to produce:
# PARTLY CLOUDY WITH A CHANCE OF RAIN.
# SNOW IN THE MORNING...THEN SLEET IN THE AFTERNOON.
# Partly cloudy with a chance of rain.
# Snow in the morning...then sleet in the afternoon.
#
# instead of:
# PARTLY CLOUDY. CHANCE OF RAIN AND SNOW IN THE MORNING
# ...THEN A CHANCE OF RAIN AND SLEET IN THE AFTERNOON.
# Partly cloudy. Chance of rain and snow in the morning
# ...then a chance of rain and sleet in the afternoon.
#return 1
return 0

View file

@ -338,7 +338,7 @@ class SAF_Overrides:
# Clean up the area label to avoid possibly
# repeat "forecast for"
e=re.compile('.*forecast for',re.IGNORECASE)
intro = "again, the forecast for " + \
intro = "Again, the forecast for " + \
e.sub("",areaLabel).strip()
# Now strip off any punctuation on the area label
# and add the period label, ie, today, tonight
@ -391,7 +391,7 @@ class SAF_Overrides:
return finalFcst
def setLabel(self, tree, component):
exLabel= "\n\nand now the extended forecast for the radio listening area.\n"
exLabel= "\n\nAnd now the extended forecast for the radio listening area.\n"
component.set("words", exLabel)
return self.DONE()
@ -745,7 +745,7 @@ class SAF_Overrides:
# dz 031010 - from Brian Walawender
# Code below sets the start time for the afternoon update
# Local Noon or the current hour (whichever is greater)
# Local noon or the current hour (whichever is greater)
currentTime = time.time()
updateHour = self.DAY() + 6

View file

@ -312,7 +312,7 @@ class ScalarPhrases(PhraseBuilder.PhraseBuilder):
# Used IF the areal_sky_flag is 1.
# Weather types that are related to sky cover and will be included in the
# sky phrase if their areal coverage matches the sky areal coverage.
# For example: AREAS OF LOW CLOUDS AND FOG IN THE MORNING...THEN MOSTLY SUNNY.
# For example: areas of low clouds and fog in the morning...then mostly sunny.
return ["F", "L"]
def disableSkyRelatedWx(self, tree, node):
@ -955,7 +955,7 @@ class ScalarPhrases(PhraseBuilder.PhraseBuilder):
elif digitMin >= upperMin and digitMax <= lowerMax and maxVal - minVal <= 10:
roundedMax = int(self.round(maxVal, "Nearest", 10))
return self.constructTempException("near %max", minVal, roundedMax)
# return 50s AND 60s (not LOWER 50s TO UPPER 60s)
# return 50s and 60s (not lower 50s to upper 60s)
elif digitMin <= lowerMax and digitMax >= upperMin:
return "in the " + decadeMinStr + " to " + decadeMaxStr
digitMinPhrase = digitMinStr + " " + decadeMinStr

View file

@ -43,46 +43,46 @@
AreaDictionary = {
'FLZ039': {'fullStateName': 'Florida',
'FLZ139': {'fullStateName': 'Florida',
'partOfState': 'northern',
'stateAbbr': 'FL',
'ugcCityString': '...Cedar Key...Hudson Beach...McKethan Pine Island Park',
'ugcCode': 'FLZ039',
'ugcCode': 'FLZ139',
'ugcName': 'Levy',
'ugcTimeZone': 'EST5EDT',
'landSeaArea': 'SRF_850',
'marineArea': 'GMZ850',
'surfAreas': [
('NorthCoast1', 'Surf along north facing reefs.............'),
('SouthCoast', 'Surf along south facing reefs.............')
('NorthCoast1', 'SURF ALONG NORTH FACING REEFS.............'),
('SouthCoast', 'SURF ALONG SOUTH FACING REEFS.............')
],
'uviCity': "Tampa", # City for which UVI should be listed
'tideTables': ["Cedar Key", "Venice Inlet"],
},
'FLZ042': {'fullStateName': 'Florida',
'FLZ142': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ042',
'ugcCode': 'FLZ142',
'ugcName': 'Citrus',
'ugcTimeZone': 'EST5EDT',
'surfAreas': [
('NorthCoast2', 'Surf along north facing reefs.............'),
('SouthCoast', 'Surf along south facing reefs.............')
('NorthCoast2', 'SURF ALONG NORTH FACING REEFS.............'),
('SouthCoast', 'SURF ALONG SOUTH FACING REEFS.............')
],
},
'FLZ048': {'fullStateName': 'Florida',
'FLZ148': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ048',
'ugcCode': 'FLZ148',
'ugcName': 'Hernando',
'ugcTimeZone': 'EST5EDT'},
'FLZ049': {'fullStateName': 'Florida',
'FLZ149': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': "",
'ugcCode': 'FLZ049',
'ugcCode': 'FLZ149',
'ugcName': 'Pasco',
'ugcTimeZone': 'EST5EDT'},
@ -101,35 +101,35 @@ AreaDictionary = {
'uviCity': "Tampa",
'tideTables': ["Saint Petersburg", "Fort Myers"],
},
'FLZ051': {'fullStateName': 'Florida',
'FLZ151': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ051',
'ugcCode': 'FLZ151',
'ugcName': 'Hillsborough',
'ugcTimeZone': 'EST5EDT'},
'FLZ055': {'fullStateName': 'Florida',
'FLZ155': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ055',
'ugcCode': 'FLZ155',
'ugcName': 'Manatee',
'ugcTimeZone': 'EST5EDT'},
'FLZ060': {'fullStateName': 'Florida',
'FLZ160': {'fullStateName': 'Florida',
'partOfState': 'west central',
'stateAbbr': 'FL',
'ugcCityString': '',
'ugcCode': 'FLZ060',
'ugcCode': 'FLZ160',
'ugcName': 'Sarasota',
'ugcTimeZone': 'EST5EDT'},
###################
'FLZ062': {'fullStateName': 'Florida',
'FLZ162': {'fullStateName': 'Florida',
'partOfState': 'Southwest',
'stateAbbr': 'FL',
'ugcCityString': '...Boca Grande...Englewood',
'ugcCode': 'FLZ062',
'ugcCode': 'FLZ162',
'ugcName': 'Charlotte',
'ugcTimeZone': 'EST5EDT',
'landSeaArea': 'SRF_856',
@ -138,11 +138,11 @@ AreaDictionary = {
'uviCity': "Tampa",
'tideTables': ["Venice Inlet"],
},
'FLZ065': {'fullStateName': 'Florida',
'FLZ165': {'fullStateName': 'Florida',
'partOfState': 'Southwest',
'stateAbbr': 'FL',
'ugcCityString': '...Fort Myers Beach...Sanibel Island',
'ugcCode': 'FLZ065',
'ugcCode': 'FLZ165',
'ugcName': 'Lee',
'ugcTimeZone': 'EST5EDT',
},

View file

@ -702,8 +702,10 @@ class TextUtils:
if newTimeZone is None:
newTimeZone = myTimeZone
os.environ["TZ"] = newTimeZone # set the new time zone
time.tzset()
timeZoneStr = time.strftime(format, time.localtime(gmTime))
os.environ["TZ"] = myTimeZone # set the time zone back
time.tzset()
return timeZoneStr # return the time as a string
# Adopted from ER 8/04

View file

@ -92,7 +92,7 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
# timeRanges 24 hours long so that getWeekday_descriptor
# will honor the splitDay24HourLabel setting and leave
# weekdays as simply the weekday name e.g.
# SATURDAY instead of SATURDAY AND SATURDAY NIGHT
# Saturday instead of Saturday and Saturday night
if splitDay24HourLabel:
# Make 12-hour start and end timeRanges
durHours1 = 12
@ -132,12 +132,12 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
# holidayModule: file containing holiday dates
# nextDay24HourLabel: if 1, a 24-hour time period starting
# after 1600, will be labeled as the next day.
# This is to accomodate 24 extended periods that go from
# This is to accommdate 24 extended periods that go from
# 6pm-6pm.
# splitDay24HourLabel: if 0, a 24-hour period will be labeled with
# simply the weekday name (e.g. SATURDAY)
# simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
#
# If the time range is for today AND is less than 12 hours,
# we must accurately describe the period.
@ -296,14 +296,14 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
4 : "Friday",
5 : "Saturday"
},
"Now": "Now",
"Today":"Today",
"Tonight": "Tonight",
"Rest of Today":"Rest of Today",
"Rest of Tonight": "Rest of Tonight",
"Night": "Night",
"Evening": "Evening",
"Afternoon": "This Afternoon",
"Now": "now",
"Today":"today",
"Tonight": "tonight",
"Rest of Today":"rest of today",
"Rest of Tonight": "rest of tonight",
"Night": "night",
"Evening": "evening",
"Afternoon": "this afternoon",
},
"Worded": {
"PrePunctuation": "",
@ -380,14 +380,14 @@ class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
4 : "Fri",
5 : "Sat"
},
"Now": "Now",
"Today":"Today",
"Tonight": "Tonight",
"Rest of Today":"Rest of Today",
"Rest of Tonight": "Rest of Tonight",
"Night": "Night",
"Evening": "Evening",
"Afternoon": "This Afternoon",
"Now": "now",
"Today":"today",
"Tonight": "tonight",
"Rest of Today":"rest of today",
"Rest of Tonight": "rest of tonight",
"Night": "night",
"Evening": "evening",
"Afternoon": "this afternoon",
},
"CapsAbbreviated": {
"PrePunctuation": "",

View file

@ -443,7 +443,7 @@ Expression = [
('Saturday',"Samedi","Sabado"),
('Sunday',"Dimanche","Domingo"),
("Tonight", "Ce soir", "Esta noche"),
('Today', "Aujourd'Hui", "HOY"),
('Today', "Aujourd'Hui", "Hoy"),
('Night', "Soir", "Noche"),
('Monday',"Lundi","Lunes"),
('Tuesday',"Mardi", "Martes"),
@ -479,7 +479,7 @@ Expression = [
('FreeWind(mph)','VentLibre(mph)','VientoLibre(mph)'),
('Haines','Haines','Haines'),
('TransWind(mph)','VentTrans(mph)','VientoTrans(mph)'),
('MixHgt(ft agl)','ElevMelang(ft agl)','AltuMezcl(ft agl)'),
('MixHgt(ft AGL)','ElevMelang(ft AGL)','AltuMezcl(ft AGL)'),
('City','Ville', 'Ciudad'),
('County','Comte', 'Condado'),
('Nowcast','Previsions Courantes','Pronostico Sobre Tiempo'),
@ -669,7 +669,7 @@ if __name__ == '__main__':
"High winds in the afternoon. Partly cloudy. Very heavy rain showers likely. Snow accumulation of 1 inch. Lows in the mid 30s. East winds at 75 mph. Probability of precipitation 65 percent.",
"Mostly sunny. Widespread heavy volcanic ash. Snow accumulation of 1 to 20 inches. Highs around 120. Probability of precipitation 99 percent.",
"High winds. Partly cloudy. Slight chance of very heavy rain showers. Snow accumulation of 1 inch. Lows in the mid 30s. East winds at 75 mph. Probability of precipitation 1 percent. Southwest winds up to 15 mph.",
"SKY/WEATHER...Mostly cloudy with scattered rain showers and thunderstorms\nLAL...........3-4\nTEMPERATURE...Lows in the mid 30s\nHUMIDITY......70 pct\nWIND - 20 FT..Northwest to Southeast in the evening\n VALLEYS...\n RIDGES....\nHAINES INDEX..4 low\nSMOKE DISPERSAL:\n MIXING HEIGHT...Decreasing to 500-1,000 ft agl\n TRANSPORT WIND..Northeast to southeast 3-8 mph",
"SKY/WEATHER...Mostly cloudy with scattered rain showers and thunderstorms\nLAL...........3-4\nTEMPERATURE...Lows in the mid 30s\nHUMIDITY......70 pct\nWIND - 20 FT..Northwest to Southeast in the evening\n VALLEYS...\n RIDGES....\nHAINES INDEX..4 low\nSMOKE DISPERSAL:\n MIXING HEIGHT...Decreasing to 500-1,000 ft AGL\n TRANSPORT WIND..Northeast to southeast 3-8 mph",
"High winds. Decreasing cloudiness. Widely scattered light sleet. Snow accumulation of 1 to 50 inches. Low 0. Northwest winds at 90 to 100 mph becoming southwest at 80 to 90 mph. Probability of precipitation 110 percent." ]
for forecast in forecastList:

View file

@ -31,17 +31,33 @@ from com.raytheon.uf.common.dataplugin.gfe.weather import WeatherSubKey as JavaW
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 09/09/08 njensen Initial Creation.
#
#
# 04/20/2015 4027 randerso Added __eq__ and __hash__ so WeatherSubKey works
# correctly when used as key in a dict.
# Changed several methods which were static methods in Java
#
class WeatherSubKey:
def __init__(self, javaSubKey):
self.__key = javaSubKey
def __repr__(self):
return str(self.__key.toString())
def __str__(self):
return str(self.__key.toString())
def __eq__(self, other):
try:
return self.__key.equals(other.__key)
except:
return False
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return self.__key.hashCode()
def wxType(self):
return self.__key.getType()
@ -60,26 +76,26 @@ class WeatherSubKey:
def wxDef(self):
return WxDefinition.WxDefinition(self.__key.wxDef())
def availableCoverages(self, dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableCoverages(siteId, wxType))
def availableAttributes(self, dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableAttributes(siteId, wxType))
def availableIntensities(self, dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableIntensities(siteId, wxType))
def availableVisibilities(self, dataMgr):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableVisibilities(siteId))
def availableWxTypes(self, dataMgr):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableWxTypes(siteId))
def availableCoverages(dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableCoverages(siteId, wxType))
def availableAttributes(dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableAttributes(siteId, wxType))
def availableIntensities(dataMgr, wxType):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableIntensities(siteId, wxType))
def availableVisibilities(dataMgr):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableVisibilities(siteId))
def availableWxTypes(dataMgr):
siteId = dataMgr.getSiteID()
return JUtil.javaStringListToPylist(JavaWeatherSubKey.availableWxTypes(siteId))
def weatherSubKey(dataMgr, coverage, wxType, intensity, vis, attrList):
siteId = dataMgr.getSiteID()
javaSubKey = JavaWeatherSubKey(siteId, coverage, wxType,

View file

@ -1045,15 +1045,15 @@ class WxPhrases(PhraseBuilder.PhraseBuilder):
# If the number of sub-phrases is greater than this limit, the weather
# phrase will use 6-hour instead of the higher resolution to produce:
#
# OCCASIONAL SNOW POSSIBLY MIXED WITH SLEET AND FREEZING
# DRIZZLE IN THE MORNING...THEN A CHANCE OF RAIN POSSIBLY MIXED WITH SNOW
# AND SLEET AND FREEZING DRIZZLE IN THE AFTERNOON.
# Occasional snow possibly mixed with sleet and freezing
# drizzle in the morning...then a chance of rain possibly mixed wiht snow
# and sleet and freezing drizzle in the afternoon.
#
# instead of:
# OCCASIONAL SNOW IN THE MORNING. CHANCE OF LIGHT SLEET AND
# SLIGHT CHANCE OF LIGHT FREEZING DRIZZLE IN THE LATE MORNING AND
# EARLY AFTERNOON. CHANCE OF SNOW EARLY IN THE AFTERNOON. CHANCE OF
# RAIN IN THE AFTERNOON.
# Occasional snow in the morning. Chance of light sleet and
# slight chance of light freezing drizzle in the late morning and
# early afternoon. Chance of snow early in the afternoon. Chance of
# rain in the afternoon.
return 3

View file

@ -98,8 +98,8 @@ public class GfeClient extends AbstractAWIPSComponent {
}
}
if (gfeClientArgStartIndex == -1
|| gfeClientArgStartIndex == args.length) {
if ((gfeClientArgStartIndex == -1)
|| (gfeClientArgStartIndex == args.length)) {
System.err.println("No python script specified to run - exiting");
return;
}
@ -130,7 +130,6 @@ public class GfeClient extends AbstractAWIPSComponent {
GfeCavePyIncludeUtil.getAutotestIncludePath(),
GfeCavePyIncludeUtil.getTextUtilitiesIncludePath(includeUser),
GfeCavePyIncludeUtil.getTextProductsIncludePath(includeUser),
GfeCavePyIncludeUtil.getTextProductsTemplatesIncludePath(),
GfeCavePyIncludeUtil.getCombinationsIncludePath(includeUser),
GfeCavePyIncludeUtil.getTestsIncludePath(),
GfeCavePyIncludeUtil.getProceduresIncludePath(includeUser));

View file

@ -103,6 +103,7 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager;
* 05/22/2014 3110 randerso Attach router to edex.alerts.gfe earlier
* 09/09/2014 3592 randerso Added call to SampleSetManager.dispose()
* 10/30/2014 3775 randerso Added parmCacheInit to initStatus
* 04/20/2015 4027 randerso Let TextProductManager know we are not running in a GUI
*
* </pre>
*
@ -213,6 +214,8 @@ public class DataManager {
*
* @param factory
* @param discriminator
* used as key for this instance of DataManager in the factory's
* instance map. Normally this is the window GFE is running in.
* @throws GFEServerException
*/
DataManager(DataManagerFactory factory, Object discriminator)
@ -236,7 +239,7 @@ public class DataManager {
strInitJob.setSystem(true);
strInitJob.schedule();
initializeScriptControllers();
initializeScriptControllers(discriminator);
procJobPool = new ProcedureJobPool(4, 4, this);
toolJobPool = new SmartToolJobPool(3, 3, this);
@ -510,7 +513,7 @@ public class DataManager {
this.gridManager = gridManager;
}
private void initializeScriptControllers() {
private void initializeScriptControllers(final Object discriminator) {
// it would be really nice to be able to spawn the construction of these
// two heavy objects into another thread. Unfortunately, Jep requires
// creation and all subsequent access to happen on the same thread. So
@ -539,7 +542,8 @@ public class DataManager {
"Error initializing smart tool interface", e);
}
DataManager.this.textProductMgr = new TextProductManager();
DataManager.this.textProductMgr = new TextProductManager(
discriminator != null);
}
});
}

View file

@ -690,7 +690,7 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements
TabItem newTab = new TabItem(tabFolder, SWT.NONE);
newTab.setText(tabName);
setTabImage(newTab, ConfigData.productStateEnum.New);
setTabImage(newTab, ConfigData.ProductStateEnum.New);
newTab.setImage(newTabImg);
ProductAreaComp comp = new ProductAreaComp(tabFolder, this,
@ -874,7 +874,7 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements
* Name of the tab.
*/
@Override
public void setTabState(ConfigData.productStateEnum state, String tabName) {
public void setTabState(ConfigData.ProductStateEnum state, String tabName) {
TabItem[] items = tabFolder.getItems();
for (int i = 0; i < items.length; i++) {
@ -893,18 +893,18 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements
* @param state
* Product state.
*/
private void setTabImage(TabItem ti, ConfigData.productStateEnum state) {
if (state == ConfigData.productStateEnum.New) {
private void setTabImage(TabItem ti, ConfigData.ProductStateEnum state) {
if (state == ConfigData.ProductStateEnum.New) {
ti.setImage(newTabImg);
} else if (state == ConfigData.productStateEnum.Queued) {
} else if (state == ConfigData.ProductStateEnum.Queued) {
ti.setImage(queuedImg);
} else if (state == ConfigData.productStateEnum.Running) {
} else if (state == ConfigData.ProductStateEnum.Running) {
ti.setImage(runningImg);
} else if (state == ConfigData.productStateEnum.Finished) {
} else if (state == ConfigData.ProductStateEnum.Finished) {
ti.setImage(finishedImg);
} else if (state == ConfigData.productStateEnum.Transmitted) {
} else if (state == ConfigData.ProductStateEnum.Transmitted) {
ti.setImage(transmittedImg);
} else if (state == ConfigData.productStateEnum.Failed) {
} else if (state == ConfigData.ProductStateEnum.Failed) {
ti.setImage(failedImg);
}
}

View file

@ -27,6 +27,7 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 18 APR 2008 ### lvenable Initial creation
* 20 APR 2015 4027 randerso Added a flag to the enum's to indicate which are final states
*
* </pre>
*
@ -46,8 +47,19 @@ public final class ConfigData {
* @author lvenable
*
*/
public enum productStateEnum {
New, Queued, Running, Finished, Transmitted, Failed;
public enum ProductStateEnum {
New(false), Queued(false), Running(false), Finished(true), Transmitted(
true), Failed(true);
private boolean complete;
private ProductStateEnum(boolean complete) {
this.complete = complete;
}
public boolean isComplete() {
return complete;
}
}
/**

View file

@ -27,6 +27,7 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 18 APR 2008 ### lvenable Initial creation
* 20 APR 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -50,7 +51,7 @@ public interface IProductTab {
* Product state.
* @param productName
*/
void setTabState(ConfigData.productStateEnum state, String productName);
void setTabState(ConfigData.ProductStateEnum state, String productName);
/**
* Update the status from the component.

View file

@ -28,7 +28,8 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 22, 2010 #2861 lvenable Initial creation
* Feb 22, 2010 #2861 lvenable Initial creation
* Apr 20, 2015 #4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -36,5 +37,5 @@ package com.raytheon.viz.gfe.dialogs.formatterlauncher;
* @version 1.0
*/
public interface ITransmissionState {
void setTransmissionState(ConfigData.productStateEnum state);
void setTransmissionState(ConfigData.ProductStateEnum state);
}

View file

@ -38,7 +38,7 @@ import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.dialogs.FormatterLauncherDialog;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.productStateEnum;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
import com.raytheon.viz.gfe.tasks.AbstractGfeTask;
import com.raytheon.viz.gfe.tasks.TaskManager;
import com.raytheon.viz.gfe.textformatter.FormatterUtil;
@ -67,6 +67,7 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager;
* 05 FEB 2014 2591 randerso Added dataManager to ZoneCombinerComp constructor
* Passed dataMgr instance to FormatterUtil.runFormatterScript
* 12 FEB 2014 2801 randerso Added prompting if formatter is run against non-normal database
* 20 APR 2015 4027 randerso Fixes for GFE formatter auto tests to support mixed case WA
*
* </pre>
*
@ -380,6 +381,15 @@ public class ProductAreaComp extends Composite implements
if (formattingCbo.isVisible()) {
vtecMode = formattingCbo.getText();
} else {
// TODO: part of fix for SS RM DR #14813
// String pil = (String) textProductMgr
// .getDefinitionValue(productName, "pil");
// if (pil != null) {
// pil = pil.substring(0, 3);
// vtecMode = textProductMgr
// .getVtecMessageType(pil);
// }
int hazIndex = productName.indexOf("Hazard_");
if (hazIndex > -1) {
String category = productName.substring(
@ -640,14 +650,13 @@ public class ProductAreaComp extends Composite implements
}
@Override
public void textProductQueued() {
productTabCB.setTabState(ConfigData.productStateEnum.Queued,
productName);
public void textProductQueued(ConfigData.ProductStateEnum state) {
productTabCB.setTabState(state, productName);
}
@Override
public void textProductFinished(String productText,
ConfigData.productStateEnum state) {
ConfigData.ProductStateEnum state) {
if (isTabClosed == true) {
return;
@ -657,7 +666,7 @@ public class ProductAreaComp extends Composite implements
runFormatterBtn.setEnabled(true);
// closeTabBtn.setEnabled(true);
outputLogBtn.setEnabled(true);
if (state == ConfigData.productStateEnum.Finished) {
if (state == ConfigData.ProductStateEnum.Finished) {
if (productText != null) {
productEditorComp.retrieveActiveVTEC();
productEditorComp.setProductText(productText);
@ -668,14 +677,14 @@ public class ProductAreaComp extends Composite implements
productEditorBtn.setSelection(true);
productEditorBtnSelected();
} else if (state == ConfigData.productStateEnum.Failed) {
} else if (state == ConfigData.ProductStateEnum.Failed) {
outputLogBtn.setSelection(true);
outputLogBtnSelected();
}
}
@Override
public void startProgressBar(ConfigData.productStateEnum state) {
public void startProgressBar(ConfigData.ProductStateEnum state) {
if (isTabClosed == true) {
return;
}
@ -685,7 +694,7 @@ public class ProductAreaComp extends Composite implements
}
@Override
public void stopProgressBar(ConfigData.productStateEnum state) {
public void stopProgressBar(ConfigData.ProductStateEnum state) {
if (isTabClosed == true) {
return;
}
@ -695,7 +704,7 @@ public class ProductAreaComp extends Composite implements
}
@Override
public void setTransmissionState(productStateEnum state) {
public void setTransmissionState(ProductStateEnum state) {
productTabCB.setTabState(state, productName);
}

View file

@ -115,7 +115,7 @@ import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.GFEPreference;
import com.raytheon.viz.gfe.constants.StatusConstants;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.productStateEnum;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
import com.raytheon.viz.gfe.product.ProductFileUtil;
import com.raytheon.viz.gfe.product.TextDBUtil;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
@ -165,6 +165,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* for the local time zones for each segment.
* 01/28/2015 #4018 randerso Code cleanup.
* 02/04/2014 17039 ryu Removed menu item related to the HighlighFramingCodes feature.
* 04/20/2015 4027 randerso Renamed ProductStateEnum with an initial capital
* </pre>
*
* @author lvenable
@ -1499,7 +1500,7 @@ public class ProductEditorComp extends Composite implements
// Check start and ending time for end later than start
if ((vtecStart != null) && (vtecEnd != null)
&& (vtecStart.getTime() >= vtecEnd.getTime())) {
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
String msg = "VTEC ending time is before "
+ "starting time. Product is invalid and must"
+ " be regenerated.";
@ -1516,7 +1517,7 @@ public class ProductEditorComp extends Composite implements
if ((vtecEnd != null)
&& (vtecEnd.getTime() <= transmissionTime.getTime())) {
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
String msg = "VTEC ends before current time."
+ " Product is invalid and must be regenerated.";
throw new VizException(msg);
@ -2426,7 +2427,7 @@ public class ProductEditorComp extends Composite implements
clearProductText();
setProductText(draft.getProductText());
setTabColorFunc(productStateEnum.Finished);
setTabColorFunc(ProductStateEnum.Finished);
setStatusText('R', productId + " draft loaded.");
if (productDefinition.get("brain") != null) {
@ -2437,7 +2438,7 @@ public class ProductEditorComp extends Composite implements
+ "after the draft was originally saved.\nThis causes VTEC to "
+ "be suspect. You must re-run the formatter.";
setStatusText('U', msg);
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
} else {
revive();
retrieveActiveVTEC();
@ -2827,13 +2828,13 @@ public class ProductEditorComp extends Composite implements
setStatusText('U', msg1);
// set tab back to gray
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
// special *ALL* case
} else if (allFound) {
brain();
// set tab back to gray
setTabColorFunc(productStateEnum.New);
setTabColorFunc(ProductStateEnum.New);
}
}
@ -2900,7 +2901,7 @@ public class ProductEditorComp extends Composite implements
/**
* @param string
*/
private void setTabColorFunc(productStateEnum state) {
private void setTabColorFunc(ProductStateEnum state) {
transmissionCB.setTransmissionState(state);
}

View file

@ -88,6 +88,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* Nov 14, 2014 4953 randerso Cleaned up practice product requests
* Feb 26, 2015 4126 randerso Ensure transmit/store is properly cancelled if dialog is closed
* Code cleanup
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -441,7 +442,7 @@ public class StoreTransmitDlg extends CaveSWTDialog {
} catch (VizException e) {
statusHandler.handle(Priority.CRITICAL,
"Error preparing product for transmission.", e);
sendTransmissionStatus(ConfigData.productStateEnum.Failed);
sendTransmissionStatus(ConfigData.ProductStateEnum.Failed);
StoreTransmitDlg.this.parentEditor.revive();
}
}
@ -578,14 +579,14 @@ public class StoreTransmitDlg extends CaveSWTDialog {
Priority p = null;
if (!resp.hasFailure()) {
p = Priority.EVENTA;
sendTransmissionStatus(ConfigData.productStateEnum.Transmitted);
sendTransmissionStatus(ConfigData.ProductStateEnum.Transmitted);
} else {
// determine the failure type and priority
ConfigData.productStateEnum state = null;
ConfigData.ProductStateEnum state = null;
if (resp.isSendLocalSuccess()) {
state = ConfigData.productStateEnum.Transmitted;
state = ConfigData.ProductStateEnum.Transmitted;
} else {
state = ConfigData.productStateEnum.Failed;
state = ConfigData.ProductStateEnum.Failed;
}
p = Priority.EVENTA;
if (!resp.isAttempted()) {
@ -619,14 +620,14 @@ public class StoreTransmitDlg extends CaveSWTDialog {
this.parentEditor.brain();
} catch (VizException e) {
statusHandler.handle(Priority.CRITICAL, "Error sending product", e);
sendTransmissionStatus(ConfigData.productStateEnum.Failed);
sendTransmissionStatus(ConfigData.ProductStateEnum.Failed);
this.parentEditor.revive();
}
SEQ_NUMBER++;
}
private void sendTransmissionStatus(ConfigData.productStateEnum status) {
private void sendTransmissionStatus(ConfigData.ProductStateEnum status) {
if (!isStoreDialog) {
transmissionCB.setTransmissionState(status);
}

View file

@ -20,11 +20,11 @@
package com.raytheon.viz.gfe.smarttool;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
import com.raytheon.uf.common.localization.IPathManager;
@ -33,6 +33,7 @@ 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.LocalizationException;
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
import com.raytheon.uf.common.python.PythonFileFilter;
import com.raytheon.viz.gfe.GFEOperationFailedException;
@ -46,6 +47,7 @@ import com.raytheon.viz.gfe.GFEOperationFailedException;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 28, 2009 njensen Initial creation
* Apr 20, 2015 4027 randerso Changes to support GFE formatter auto tests
*
* </pre>
*
@ -87,6 +89,14 @@ public class TextFileUtil {
return file;
}
public static LocalizationFile getUserTextFile(LocalizationFile source) {
LocalizationContext ctx = PATH_MGR.getContext(source.getContext()
.getLocalizationType(), LocalizationLevel.USER);
LocalizationFile destLf = getTextFile(ctx, source.getName());
return destLf;
}
private static String getPathFromType(String filename, String fileType) {
String name = null;
if (fileType.equalsIgnoreCase("TextUtility")) {
@ -102,7 +112,8 @@ public class TextFileUtil {
name = "gfe" + File.separator + "editAreaGroups" + File.separator
+ filename + ".txt";
} else if (fileType.equalsIgnoreCase("Reference")) {
name = "editAreas" + File.separator + filename + ".xml";
name = "gfe" + File.separator + "editAreas" + File.separator
+ filename + ".xml";
}
return name;
}
@ -115,63 +126,75 @@ public class TextFileUtil {
public static void makeWritableCopy(String source, String fileType,
String dest, boolean deleteFlag) throws IOException,
GFEOperationFailedException {
LocalizationFile lf = getTextFile(source, fileType);
if (lf.getContext().getLocalizationLevel() == LocalizationLevel.BASE
|| lf.getContext().getLocalizationLevel() == LocalizationLevel.SITE) {
File srcFile = lf.getFile();
LocalizationFile srcLf = getTextFile(source, fileType);
if ((srcLf.getContext().getLocalizationLevel() == LocalizationLevel.BASE)
|| (srcLf.getContext().getLocalizationLevel() == LocalizationLevel.CONFIGURED)
|| (srcLf.getContext().getLocalizationLevel() == LocalizationLevel.SITE)) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext ctx = pathMgr.getContext(lf.getContext()
LocalizationContext ctx = pathMgr.getContext(srcLf.getContext()
.getLocalizationType(), LocalizationLevel.USER);
LocalizationFile destLf = getTextFile(ctx,
getPathFromType(dest, fileType));
File destFile = destLf.getFile();
copy(srcFile, destFile);
try {
copy(srcLf, destLf);
destLf.save();
} catch (Exception e) {
throw new GFEOperationFailedException(
"Unable to save localization file", e);
}
} else if (lf.getContext().getLocalizationLevel() == LocalizationLevel.USER) {
} else if (srcLf.getContext().getLocalizationLevel() == LocalizationLevel.USER) {
if (deleteFlag) {
try {
lf.delete();
srcLf.delete();
} catch (Exception e) {
throw new GFEOperationFailedException(
"Unable to delete localization file "
+ lf.toString(), e);
+ srcLf.toString(), e);
}
} else {
System.out.println("USER version already exists " + source);
}
} else {
throw new GFEOperationFailedException(
"No file found at base or site level for " + source + " "
+ fileType);
"No file found at base, configured or site level for "
+ source + " " + fileType);
}
}
private static void copy(File src, File dest) throws IOException {
File dir = new File(dest.getParent());
dir.mkdir();
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
private static void copy(LocalizationFile srcLf, LocalizationFile destLf)
throws IOException, LocalizationException {
File dir = destLf.getFile(false).getParentFile();
Files.createDirectories(dir.toPath());
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
try (InputStream in = srcLf.openInputStream();
OutputStream out = destLf.openOutputStream()) {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
in.close();
out.close();
}
public static void deleteTextFile(LocalizationFile lf)
throws LocalizationOpFailedException {
lf.delete();
throws LocalizationOpFailedException, IOException {
if (lf.getContext().getLocalizationLevel()
.equals(LocalizationLevel.USER)
&& lf.getContext().getContextName().equals("GFETEST")) {
lf.delete();
String path = lf.getFile().getAbsolutePath();
if (path.endsWith(".py")) {
path = path + "o";
Files.deleteIfExists(Paths.get(path));
}
} else {
throw new IllegalArgumentException(
"Can only delete USER level files owned by GFETEST: " + lf);
}
}
}

View file

@ -30,15 +30,18 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.gfe.python.GfeCavePyIncludeUtil;
/**
* Builds text formatter script objects
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 2, 2008 njensen Initial creation
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 02, 2008 njensen Initial creation
* Apr 20, 2015 4027 randerso Remove unused TextProductsTemplates path and added
* Tests path for GFE formatter auto tests
*
* </pre>
*
@ -67,9 +70,9 @@ public class FormatterScriptFactory {
GfePyIncludeUtil.getHeadlineIncludePath(),
GfePyIncludeUtil.getTextUtilitiesIncludePath(),
GfePyIncludeUtil.getTextProductsIncludePath(),
GfePyIncludeUtil.getTextProductsTemplatesIncludePath(),
GfePyIncludeUtil.getUtilitiesIncludePath(),
GfePyIncludeUtil.getCombinationsIncludePath());
GfePyIncludeUtil.getCombinationsIncludePath(),
GfeCavePyIncludeUtil.getTestsIncludePath());
return new FormatterScript(runnerPath, include,
FormatterScript.class.getClassLoader());

View file

@ -36,13 +36,14 @@ import com.raytheon.viz.gfe.tasks.TaskManager;
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 8, 2008 njensen Initial creation
* Jan 15, 2010 3395 ryu Fix &quot;issued by&quot; functionality
* Sep 05, 2013 2329 randerso Removed save of combinations file
* Feb 12, 2014 2591 randerso Passed dataMgr instance to FormatterUtil.runFormatterScript
* Removed call to TextProductManager.reloadModule
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 8, 2008 njensen Initial creation
* Jan 15, 2010 3395 ryu Fix &quot;issued by&quot; functionality
* Sep 05, 2013 2329 randerso Removed save of combinations file
* Feb 12, 2014 2591 randerso Passed dataMgr instance to FormatterUtil.runFormatterScript
* Removed call to TextProductManager.reloadModule
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -117,7 +118,7 @@ public class FormatterUtil {
time, testMode, finish);
} else {
finish.textProductFinished("Formatter canceled",
ConfigData.productStateEnum.Finished);
ConfigData.ProductStateEnum.Finished);
}
}
@ -128,7 +129,7 @@ public class FormatterUtil {
varDict, vtecActiveTable, drtTime, testMode, finish);
// Thread thread = new Thread(formatter);
// thread.start();
finish.textProductQueued();
finish.textProductQueued(ConfigData.ProductStateEnum.Queued);
TaskManager.getInstance().queueFormatter(formatter);
}

View file

@ -35,7 +35,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.productStateEnum;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
import com.raytheon.viz.gfe.sampler.SamplerGridSliceCache;
import com.raytheon.viz.gfe.tasks.AbstractGfeTask;
@ -46,13 +46,14 @@ import com.raytheon.viz.gfe.tasks.AbstractGfeTask;
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 29, 2008 njensen Initial creation
* Oct 15, 2008 njensen Split python running to
* non-UI thread
* Dec 1, 2010 6130 ryu Set proper state and invoke callback
* May 29, 2014 2841 randerso Handle failure to queue due to pending limit
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 29, 2008 njensen Initial creation
* Oct 15, 2008 njensen Split python running to
* non-UI thread
* Dec 1, 2010 6130 ryu Set proper state and invoke callback
* May 29, 2014 2841 randerso Handle failure to queue due to pending limit
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -73,7 +74,7 @@ public class TextFormatter extends AbstractGfeTask {
private HashMap<String, Object> argMap;
private ConfigData.productStateEnum state;
private ConfigData.ProductStateEnum state;
/**
* Constructor
@ -103,7 +104,7 @@ public class TextFormatter extends AbstractGfeTask {
argMap.put(ArgDictConstants.VTEC_ACTIVE_TABLE, vtecActiveTable);
argMap.put("drtTime", drtTime);
listener = finish;
this.state = ConfigData.productStateEnum.Queued;
this.state = ConfigData.ProductStateEnum.Queued;
}
@Override
@ -114,7 +115,7 @@ public class TextFormatter extends AbstractGfeTask {
VizApp.runSyncIfWorkbench(new Runnable() {
@Override
public void run() {
state = ConfigData.productStateEnum.Running;
state = ConfigData.ProductStateEnum.Running;
listener.startProgressBar(state);
}
});
@ -130,11 +131,11 @@ public class TextFormatter extends AbstractGfeTask {
perfLog.logDuration("Text Formatter " + productName,
timer.getElapsedTime());
state = ConfigData.productStateEnum.Finished;
state = ConfigData.ProductStateEnum.Finished;
} catch (Throwable t) {
statusHandler.handle(Priority.PROBLEM,
"Error generating text product", t);
state = ConfigData.productStateEnum.Failed;
state = ConfigData.ProductStateEnum.Failed;
} finally {
SamplerGridSliceCache.remove(this.getId());
SamplerGridSliceCache.remove(UI_THREAD_ID);
@ -149,8 +150,8 @@ public class TextFormatter extends AbstractGfeTask {
VizApp.runSyncIfWorkbench(new Runnable() {
@Override
public void run() {
listener.textProductFinished(text, state);
listener.stopProgressBar(state);
listener.textProductFinished(text, state);
}
});
}
@ -167,9 +168,9 @@ public class TextFormatter extends AbstractGfeTask {
// TODO: this is deprecated and probably not a good thing to do.
// we really need to get formatters running in their own process
// so we can kill them safely
if (this.state.equals(productStateEnum.Queued)
|| this.state.equals(productStateEnum.New)) {
state = ConfigData.productStateEnum.Failed;
if (this.state.equals(ProductStateEnum.Queued)
|| this.state.equals(ProductStateEnum.New)) {
state = ConfigData.ProductStateEnum.Failed;
cleanUp(null);
this.finishedTime = SimulatedTime.getSystemTime().getTime();

View file

@ -29,6 +29,8 @@ import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 15, 2008 njensen Initial creation
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
* @author njensen
@ -38,12 +40,12 @@ import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
public interface TextProductFinishListener {
public void textProductFinished(String productText,
ConfigData.productStateEnum state);
ConfigData.ProductStateEnum state);
public void startProgressBar(ConfigData.productStateEnum state);
public void startProgressBar(ConfigData.ProductStateEnum state);
public void stopProgressBar(ConfigData.productStateEnum state);
public void stopProgressBar(ConfigData.ProductStateEnum state);
public void textProductQueued();
public void textProductQueued(ConfigData.ProductStateEnum state);
}

View file

@ -20,6 +20,7 @@
package com.raytheon.viz.gfe.textformatter;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
/**
* Listens for a text product to finish and then returns the product with
@ -32,6 +33,7 @@ import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 30, 2009 njensen Initial creation
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
*
* </pre>
*
@ -43,7 +45,7 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
private String product;
private boolean wait = true;
private ProductStateEnum state;
/*
* (non-Javadoc)
@ -53,8 +55,8 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
* ()
*/
@Override
public void startProgressBar(ConfigData.productStateEnum state) {
wait = true;
public void startProgressBar(ConfigData.ProductStateEnum state) {
this.state = state;
}
/*
@ -65,8 +67,8 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
* ()
*/
@Override
public void stopProgressBar(ConfigData.productStateEnum state) {
wait = false;
public void stopProgressBar(ConfigData.ProductStateEnum state) {
this.state = state;
}
/*
@ -76,8 +78,8 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
* textProductQueued()
*/
@Override
public void textProductQueued() {
wait = true;
public void textProductQueued(ConfigData.ProductStateEnum state) {
this.state = state;
}
/*
@ -88,16 +90,22 @@ public class TextProductFinishWaiter implements TextProductFinishListener {
*/
@Override
public void textProductFinished(String productText,
ConfigData.productStateEnum state) {
ConfigData.ProductStateEnum state) {
this.product = productText;
wait = false;
this.state = state;
}
public String waitAndGetProduct() throws InterruptedException {
while (wait) {
Thread.sleep(50);
while (!state.isComplete()) {
Thread.sleep(100);
}
if (state == ConfigData.ProductStateEnum.Failed) {
product = "";
}
return product;
}
public ConfigData.ProductStateEnum getState() {
return this.state;
}
}

View file

@ -62,6 +62,8 @@ import com.raytheon.viz.gfe.core.DataManager;
* Apr 24, 2013 1936 dgilling Remove unused imports.
* Feb 12, 2014 2591 randerso Removed reloadModule method
* Dec 15, 2014 #14946 ryu Add getTimeZones() method.
* Apr 20, 2015 4027 randerso Made fileObservers conditional as they are not needed
* in a non-GUI environment like GFE formatter auto-tests
*
* </pre>
*
@ -89,9 +91,9 @@ public class TextProductManager {
private TextProductListener listener;
public TextProductManager() {
public TextProductManager(boolean startListener) {
try {
init();
init(startListener);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Exception initializing TextProductManager", e);
@ -101,7 +103,7 @@ public class TextProductManager {
}
}
private void init() throws VizException, JepException {
private void init(boolean startListener) throws VizException, JepException {
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext configContext = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.CONFIGURED);
@ -116,10 +118,12 @@ public class TextProductManager {
GfePyIncludeUtil.TEXT_PRODUCTS);
lfUserDir = pm.getLocalizationFile(userContext,
GfePyIncludeUtil.TEXT_PRODUCTS);
listener = new TextProductListener();
lfConfigDir.addFileUpdatedObserver(listener);
lfSiteDir.addFileUpdatedObserver(listener);
lfUserDir.addFileUpdatedObserver(listener);
if (startListener) {
listener = new TextProductListener();
lfConfigDir.addFileUpdatedObserver(listener);
lfSiteDir.addFileUpdatedObserver(listener);
lfUserDir.addFileUpdatedObserver(listener);
}
script = FormatterScriptFactory.buildFormatterScript();
@ -136,10 +140,10 @@ public class TextProductManager {
HashMap<String, Object> map = new HashMap<String, Object>();
String paths = configDir.getPath();
if (siteDir != null && siteDir.exists()) {
if ((siteDir != null) && siteDir.exists()) {
paths = siteDir + ":" + paths;
}
if (userDir != null && userDir.exists()) {
if ((userDir != null) && userDir.exists()) {
paths = userDir + ":" + paths;
}
map.put("paths", paths);
@ -170,7 +174,7 @@ public class TextProductManager {
public String getCombinationsFileName(String productName) {
String filename = null;
Object obj = getDefinitionValue(productName, "defaultEditAreas");
if (obj != null && obj instanceof String) {
if ((obj != null) && (obj instanceof String)) {
filename = (String) obj;
} else {
filename = "NONE";
@ -181,7 +185,7 @@ public class TextProductManager {
public boolean isSingleZoneSelect(String productName) {
boolean isSingle = false;
Object obj = getDefinitionValue(productName, "singleComboOnly");
if (obj != null && obj instanceof Integer) {
if ((obj != null) && (obj instanceof Integer)) {
if ((Integer) obj == 1) {
isSingle = true;
}
@ -245,12 +249,13 @@ public class TextProductManager {
statusHandler.handle(Priority.PROBLEM,
"Exception getting VTECMessageType", e);
}
if (vtec == null) {
vtec = "";
}
return vtec;
}
public List<String> getTimeZones(List<String> zones,
String officeTimeZone) {
public List<String> getTimeZones(List<String> zones, String officeTimeZone) {
List<String> timeZones = Collections.emptyList();
HashMap<String, Object> map = new HashMap<String, Object>(2);
map.put("zones", zones);
@ -259,7 +264,7 @@ public class TextProductManager {
timeZones = (List<String>) script.execute("getTimeZones", map);
} catch (JepException e) {
statusHandler.handle(Priority.PROBLEM,
"Exception getting time zones", e);
"Exception getting time zones", e);
}
return timeZones;
}

View file

@ -996,8 +996,8 @@ def localTC(start,repeat,duration,dst):
timezone = SITES[GFESUITE_SITEID][3]
import dateutil.tz, datetime
tz = dateutil.tz.gettz(timezone)
dt = datetime.datetime.utcnow()
delta = tz.utcoffset(dt) + tz.dst(dt)
local = datetime.datetime.now(tz)
delta = tz.utcoffset(local) - tz.dst(local)
offset = delta.days*86400 + delta.seconds
start = start - offset
if dst == 1:

View file

@ -390,17 +390,17 @@ def createTCVAreaDictionary(outputDir, mapDict, siteID):
# # "We ended the other list and are back at tab level 0 now",
# # ]
# 'infoSection': [
# "LOCAL EVACUATION AND SHELTERING: MIAMI-DADE COUNTY EMERGENCY MANAGEMENT",
# "Local evacuation and sheltering: Miami-Dade County Emergency Management",
# [
# "HTTP://WWW.MIAMIDADE.GOV/EMERGENCY/",
# "http://www.miamidade.gov/emergency/",
# ],
# "FAMILY EMERGENCY PLANS: FEDERAL EMERGENCY MANAGEMENT AGENCY",
# "Family emergency plans: Federal Emergency Management Agency",
# [
# "HTTP://READY.GOV/",
# "http://ready.gov/",
# ],
# "LOCAL WEATHER CONDITIONS AND FORECASTS: NWS MIAMI FLORIDA",
# "Local weather conditions and forecasts: NWS Miami Florida",
# [
# "HTTP://WWW.SRH.NOAA.GOV/MFL/",
# "http://www.srh.noaa.gov/mfl/",
# ],
# ],
# },

View file

@ -355,9 +355,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# set this variable to zero for proper labeling.
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
return 1
def gust_wind_difference_nlValue(self, tree, node):
@ -1162,7 +1162,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -1171,11 +1171,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# The following lines insert a statement
# at the top of the forecast that describes the time periods
@ -1404,7 +1405,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
for myTimeRange, label in myTimeRanges:
# Add it on to the header
if periodNum == numPeriods:
header = header + "AND "
header = header + "and "
header = header + label
periodNum = periodNum + 1

View file

@ -303,8 +303,10 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Add product heading to fcst string
return fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
fcst = fcst + s.upper()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):
return fcst + areaLabel + " "

View file

@ -802,7 +802,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -811,11 +811,13 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._Text1()
try:
text2 = self._Text2(argDict)
@ -1125,14 +1127,14 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.
# Periods longer than that will always be split into day and night labels
# (e.g. SUNDAY THROUGH MONDAY NIGHT)
# (e.g. Sunday through Monday night)
compName = node.getComponentName()
if compName == "CWFExtended":
return 0

View file

@ -417,7 +417,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def combinedSeas_threshold(self, tree, node):
# See wave_phrase
# If waves and swells are above this threshold,
# combined seas will be reported AND no Swell phrase will be reported.
# combined seas will be reported and no Swell phrase will be reported.
# Units: feet
return 7
@ -1105,7 +1105,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -1113,11 +1113,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._Text1()
try:
text2 = self._Text2(argDict)
@ -1270,7 +1271,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
## # expirationHour -- hour when the product expires (in local time)
## # This is relitive to midnight local time of the
## # current day.
## # period1 Label -- the label for the first period. e.g. ".Today...", ".REST OF Today..."
## # period1 Label -- the label for the first period. e.g. ".Today...", ".Rest of Today..."
## # period1 lateNight phrase -- phrase to use if the hours of 3am to 6am must be qualified
## # e.g. "Partly cloudy in the early morning."
## # period1 lateDay phrase -- phrase to use if the hours of 3pm to 6pm must be qualified
@ -1314,9 +1315,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -90,8 +90,8 @@ class TextProduct(CivilEmerg.TextProduct):
label, variable = key
exec "self._" + variable + "= varDict[key]"
fcst = fcst + "An earthquake has been felt " + self._felt + " BY " +\
self._extent + " " + "IN THE |*enter area*| AREA. " + \
fcst = fcst + "An earthquake has been felt " + self._felt + " by " +\
self._extent + " " + "in the |*enter area*| area. " + \
self._damage + " damage has been reported. "
if self._damage != "No":

View file

@ -851,7 +851,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -859,11 +859,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Put in a place holder for the headlines to be substituted in
# "postProcessProduct"

View file

@ -627,7 +627,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Add product heading to fcst string
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -635,11 +635,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weahter Service " + self._wfoCityState + \
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Put in a place holder for the headlines to be substituted in
# "postProcessProduct"

View file

@ -267,8 +267,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# This is the header for the overall product
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
fcst = fcst + s.upper()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):

View file

@ -431,46 +431,43 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
return 1
def marine_abbreviateText(self, fcst):
fcst = " " + fcst
fcst = re.sub(r'\n', r' ',fcst)
fcst = re.sub(r'(?i)(\W)NORTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(\W)', r'\1N\2', fcst)
fcst = re.sub(r'(?i)(\W)SOUTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(\W)', r'\1S\2', fcst)
fcst = re.sub(r'(?i)(\W)EAST(?!WARD|ERN)(\W)', r'\1E\2', fcst)
fcst = re.sub(r'(?i)(\W)WEST(?!WARD|ERN)(\W)', r'\1W\2', fcst)
fcst = re.sub(r'(?i)(\W)KNOTS?(\W)', r'\1KT\2', fcst)
fcst = re.sub(r'(?i)(\W)MILLIBARS?(\W)', r'\1MB\2', fcst)
fcst = re.sub(r'(?i)(\W)FATHOMS?(\W)', r'\1FM\2', fcst)
fcst = re.sub(r'(?i)(\W)NAUTICAL MILES?(\W)', r'\1NM\2', fcst)
fcst = re.sub(r'(?i)(\W)FOOT|FEET(\W)', r'\1FT\2', fcst)
fcst = re.sub(r'(?i)(\W)POSITION(\W)', r'\1PSN\2', fcst)
fcst = re.sub(r'(?i)(\W)VISIBILITY(\W)', r'\1VSBY\2', fcst)
fcst = re.sub(r'(?i)(\W)THUNDERSTORM(\W)', r'\1TSTM\2', fcst)
fcst = re.sub(r'(?i)(\W)AVERAGE(\W)', r'\1AVG\2', fcst)
fcst = re.sub(r'(?i)(\W)ATLANTIC(\W)', r'\1ATLC\2', fcst)
fcst = re.sub(r'(?i)(\W)LONGITUDE(\W)', r'\1LONG\2', fcst)
fcst = re.sub(r'(?i)(\W)PACIFIC(\W)', r'\1PAC\2', fcst)
fcst = re.sub(r'(?i)(\W)DEGREE(\W)', r'\1DEG\2', fcst)
fcst = re.sub(r'(?i)(\W)PRESSURE(\W)', r'\1PRES\2', fcst)
fcst = re.sub(r'(?i)(\W)SUNDAY(\W)', r'\1SUN\2', fcst)
fcst = re.sub(r'(?i)(\W)MONDAY(\W)', r'\1MON\2', fcst)
fcst = re.sub(r'(?i)(\W)TUESDAY(\W)', r'\1TUE\2', fcst)
fcst = re.sub(r'(?i)(\W)WEDNESDAY(\W)', r'\1WED\2', fcst)
fcst = re.sub(r'(?i)(\W)THURSDAY(\W)', r'\1THU\2', fcst)
fcst = re.sub(r'(?i)(\W)FRIDAY(\W)', r'\1FRI\2', fcst)
fcst = re.sub(r'(?i)(\W)SATURDAY(\W)', r'\1SAT\2', fcst)
fcst = re.sub(r'(?i)(\W)W HALF(\W)', r'\1WEST HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)E HALF(\W)', r'\1EAST HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)N HALF(\W)', r'\1NORTH HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)S HALF(\W)', r'\1SOUTH HALF\2', fcst)
fcst = re.sub(r'(?i)(\W)W THIRD(\W)', r'\1WEST THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)E THIRD(\W)', r'\1EAST THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)N THIRD(\W)', r'\1NORTH THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)S THIRD(\W)', r'\1SOUTH THIRD\2', fcst)
fcst = re.sub(r'(?i)(\W)W TWO(\W)', r'\1WEST TWO\2', fcst)
fcst = re.sub(r'(?i)(\W)E TWO(\W)', r'\1EAST TWO\2', fcst)
fcst = re.sub(r'(?i)(\W)N TWO(\W)', r'\1NORTH TWO\2', fcst)
fcst = re.sub(r'(?i)(\W)S TWO(\W)', r'\1SOUTH TWO\2', fcst)
fcst = re.sub(r'^ ', r'',fcst)
fcst = re.sub(r'(?i)(\W|^)NORTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(?=\W|$)', r'\1N', fcst)
fcst = re.sub(r'(?i)(\W|^)SOUTH(?!WARD|ERN|WESTWARD|EASTWARD|WESTERN|EASTERN)(?=\W|$)', r'\1S', fcst)
fcst = re.sub(r'(?i)(\W|^)EAST(?!WARD|ERN)(?=\W|$)', r'\1E', fcst)
fcst = re.sub(r'(?i)(\W|^)WEST(?!WARD|ERN)(?=\W|$)', r'\1W', fcst)
fcst = re.sub(r'(?i)(\W|^)KNOTS?(?=\W|$)', r'\1kt', fcst)
fcst = re.sub(r'(?i)(\W|^)MILLIBARS?(?=\W|$)', r'\1mb', fcst)
fcst = re.sub(r'(?i)(\W|^)FATHOMS?(?=\W|$)', r'\1fm', fcst)
fcst = re.sub(r'(?i)(\W|^)NAUTICAL MILES?(?=\W|$)', r'\1nm', fcst)
fcst = re.sub(r'(?i)(\W|^)(?:FOOT|FEET)(?=\W|$)', r'\1ft', fcst)
fcst = re.sub(r'(?i)(\W|^)POSITION(?=\W|$)', r'\1PSN', fcst)
fcst = re.sub(r'(?i)(\W|^)VISIBILITY(?=\W|$)', r'\1VSBY', fcst)
fcst = re.sub(r'(?i)(\W|^)THUNDERSTORM(?=\W|$)', r'\1TSTM', fcst)
fcst = re.sub(r'(?i)(\W|^)AVERAGE(?=\W|$)', r'\1AVG', fcst)
fcst = re.sub(r'(?i)(\W|^)ATLANTIC(?=\W|$)', r'\1ATLC', fcst)
fcst = re.sub(r'(?i)(\W|^)LONGITUDE(?=\W|$)', r'\1LONG', fcst)
fcst = re.sub(r'(?i)(\W|^)PACIFIC(?=\W|$)', r'\1PAC', fcst)
fcst = re.sub(r'(?i)(\W|^)DEGREE(?=\W|$)', r'\1deg', fcst)
fcst = re.sub(r'(?i)(\W|^)PRESSURE(?=\W|$)', r'\1PRES', fcst)
fcst = re.sub(r'(?i)(\W|^)SUNDAY(?=\W|$)', r'\1Sun', fcst)
fcst = re.sub(r'(?i)(\W|^)MONDAY(?=\W|$)', r'\1Mon', fcst)
fcst = re.sub(r'(?i)(\W|^)TUESDAY(?=\W|$)', r'\1Tue', fcst)
fcst = re.sub(r'(?i)(\W|^)WEDNESDAY(?=\W|$)', r'\1Wed', fcst)
fcst = re.sub(r'(?i)(\W|^)THURSDAY(?=\W|$)', r'\1Thu', fcst)
fcst = re.sub(r'(?i)(\W|^)FRIDAY(?=\W|$)', r'\1Fri', fcst)
fcst = re.sub(r'(?i)(\W|^)SATURDAY(?=\W|$)', r'\1Sat', fcst)
fcst = re.sub(r'(?i)(\W|^)W HALF(?=\W|$)', r'\1West half', fcst)
fcst = re.sub(r'(?i)(\W|^)E HALF(?=\W|$)', r'\1east half', fcst)
fcst = re.sub(r'(?i)(\W|^)N HALF(?=\W|$)', r'\1north half', fcst)
fcst = re.sub(r'(?i)(\W|^)S HALF(?=\W|$)', r'\1soutH half', fcst)
fcst = re.sub(r'(?i)(\W|^)W THIRD(?=\W|$)', r'\1west third', fcst)
fcst = re.sub(r'(?i)(\W|^)E THIRD(?=\W|$)', r'\1east third', fcst)
fcst = re.sub(r'(?i)(\W|^)N THIRD(?=\W|$)', r'\1north third', fcst)
fcst = re.sub(r'(?i)(\W|^)S THIRD(?=\W|$)', r'\1south third', fcst)
fcst = re.sub(r'(?i)(\W|^)W TWO(?=\W|$)', r'\1west two', fcst)
fcst = re.sub(r'(?i)(\W|^)E TWO(?=\W|$)', r'\1east two', fcst)
fcst = re.sub(r'(?i)(\W|^)N TWO(?=\W|$)', r'\1north two', fcst)
fcst = re.sub(r'(?i)(\W|^)S TWO(?=\W|$)', r'\1south two', fcst)
return fcst
def rounding_method_dict(self, tree, node):
@ -608,7 +605,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Get the edit areas
try:
if self._groupings == "West 1/3:East 2/3":
if self._groupings == "West 1/3:east 2/3":
self._areaList = [("west_one_third", "WEST THIRD"),
("east_two_thirds", "EAST TWO THIRDS")]
elif self._groupings == "West 2/3:East 1/3":
@ -782,7 +779,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -790,13 +787,15 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + '\n' + \
self._lakezone + "-" + self._expireTimeDDHHMM + "-\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n" + \
self._headerphrase + "\n\n" + ".SYNOPSIS..." + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._headerphrase + "\n\n" + ".SYNOPSIS..." + "\n\n"
# Set up hazards
self.getHazards(argDict, self._areaList)
@ -855,12 +854,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Adjust some phrases to local requirements
# ========================================
fcst = string.replace(fcst,"WIDESPREAD RAIN", "OCCASIONAL RAIN")
fcst = string.replace(fcst,"WIDESPREAD SHOWERS", "SHOWERS")
fcst = string.replace(fcst,"WIDESPREAD THUNDERSTORMS", "THUNDERSTORMS")
fcst = string.replace(fcst,"widespread rain", "occasional rain")
fcst = string.replace(fcst,"widespread showers", "showers")
fcst = string.replace(fcst,"widespread thunderstorms", "thunderstorms")
fcst = string.replace(fcst, "RAIN SHOWERS", "SHOWERS")
fcst = string.replace(fcst, "THUNDERSTORMS AND SHOWERS", "SHOWERS AND THUNDERSTORMS")
fcst = string.replace(fcst, "rain showers", "showers")
fcst = string.replace(fcst, "thunderstorms and showers", "showers and thunderstorms")
#phrase = string.replace(phrase, "widespread", "")
# This is the footer for an edit area combination
@ -870,9 +869,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
fcst = fcst + "$$\n\n"
if string.find(fcst, "STORM FORCE") > 0 or\
string.find(fcst, "STORM WARNING") > 0 or\
string.find(fcst, "HURRICANE") > 0:
if string.find(fcst, "storm force") > 0 or\
string.find(fcst, "storm warning") > 0 or\
string.find(fcst, "hurricane") > 0:
fcst = fcst + "&&STORM\n\n"
if self._processmafor == 1:
@ -965,9 +964,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -273,7 +273,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict,
self._productName + self._areaName)
@ -283,11 +283,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
else:
eas = ''
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
eas + productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + "Default overview section\n"
return fcst
@ -505,7 +506,6 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
hazNameA = self.hazardName(eachHazard['hdln'], argDict, True)
hazName = self.hazardName(eachHazard['hdln'], argDict, False)
# if hazName == "Winter Weather Advisory" or hazName == "Winter Storm Warning":
if hazName in ["Winter Weather Advisory", "Winter Storm Warning", "Beach Hazards Statement"]:
forPhrase = " for |* Enter hazard type *|"
else:
@ -670,6 +670,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
startPara = 1
else:
startPara = 2
segmentText, foundCTAs = self.cleanCapturedText(prevText,
startPara, addFramingCodes = False,
skipCTAs = skipCTAs)

View file

@ -251,7 +251,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()

View file

@ -2120,10 +2120,10 @@ class TextProduct(HLSTCV_Common.TextProduct):
return direction
def _dirInEnglish(self, direction):
dirList = ["North", "North-Northeast", "Northeast", "East-Northeast",
"East", "East-Southeast", "Southeast", "South-Southeast",
"South", "South-Southwest", "Southwest", "West-Southwest",
"West", "West-Northwest", "Northwest", "North-NorthWest"]
dirList = ["north", "north-northeast", "northeast", "east-northeast",
"east", "east-southeast", "southeast", "south-southeast",
"south", "south-southwest", "southwest", "west-southwest",
"west", "west-northwest", "northwest", "north-northwest"]
dirIndex = int((direction + 11.25) / 22.5)
if dirIndex > 15:
dirIndex = dirIndex - 16

View file

@ -150,19 +150,19 @@ class TextProduct(GenericHazards.TextProduct):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " +\
s = self._wmoID + " " + self._fullStationID + " " +\
self._ddhhmmTime + "\n" + self._pil + "\n\n" + productName + "\n"
# Placeholder for Agency Names to be filled in in _postProcessProduct
#fcst = fcst + "@AGENCYNAMES" + "\n"
s = "Relayed by National Weather Service " + self._wfoCityState + "\n" +\
#s = s + "@AGENCYNAMES" + "\n"
s = s + "Relayed by National Weather Service " + self._wfoCityState + "\n" +\
issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()

View file

@ -203,7 +203,7 @@ class TextProduct(GenericHazards.TextProduct):
for each in fullKeyList:
if each in ['LS.W', 'LS.A', 'LS.Y', 'LS.S']:
productName = "Lakeshore Hazard Message"
fcst = fcst.replace(self._productName, productName, 1)
fcst = fcst.replace(self._productName.upper(), productName.upper(), 1)
break
# Added to place line feeds in the CAP tags to keep separate from CTAs

View file

@ -133,7 +133,7 @@ class TextProduct(GenericHazards.TextProduct):
#
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
if useEAS == 1:
easPhrase = "URGENT - IMMEDIATE BROADCAST REQUESTED\n"
else:
@ -142,12 +142,14 @@ class TextProduct(GenericHazards.TextProduct):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, self._productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" + easPhrase +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n" + \
self._easPhrase + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + "Default overview section\n"
return fcst
@ -304,7 +306,7 @@ class TextProduct(GenericHazards.TextProduct):
if areaGroupCount == 1:
conn = ""
elif areaGroupCount == areaGroupLen:
conn = " AND "
conn = " and "
else:
conn = "..."
@ -350,7 +352,7 @@ class TextProduct(GenericHazards.TextProduct):
incPhrases.append("Parish")
elif parishCnt > 1:
incPhrases.append("Parishes")
incPhrase = " AND ".join(incPhrases)
incPhrase = " and ".join(incPhrases)
if generalOnly:
return areaPhrase
@ -375,7 +377,7 @@ class TextProduct(GenericHazards.TextProduct):
phrase = "...".join(snames[0:-1])
# complex phrasing (state, partOfState, and names)
else:
phrase = "IN "
phrase = "In "
if partOfState != '' and partOfState != ' ':
phrase = phrase + partOfState + ' '
phrase = phrase + state + "..." + "...".join(snames[0:-1])
@ -383,7 +385,7 @@ class TextProduct(GenericHazards.TextProduct):
if len(snames) == 1:
phrase = phrase + snames[-1]
else:
phrase = phrase + " AND " + snames[-1]
phrase = phrase + " and " + snames[-1]
areaPhrase = areaPhrase + phrase
if i != len(areaGroups) - 1:
areaPhrase = areaPhrase + '. ' #another one coming, add period
@ -413,7 +415,7 @@ class TextProduct(GenericHazards.TextProduct):
if hazard['act'] == 'NEW' and len(hazard['hdln']):
attribution = nwsPhrase + "issued a"
headPhrase = "* " + hazName + " FOR " + areaPhrase + "."
headPhrase = "* " + hazName + " for " + areaPhrase + "."
elif hazard['act'] == 'CON' and len(hazard['hdln']):
attribution = "The " + hazName + " continues for"

View file

@ -1040,7 +1040,7 @@ class TextProduct(GenericHazards.TextProduct):
# Product header
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, actualProductName + self._areaName)
@ -1049,11 +1049,12 @@ class TextProduct(GenericHazards.TextProduct):
else:
eas = ''
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
eas + productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Main Headline
mh = self._MainHeadline
@ -2833,10 +2834,10 @@ class TextProduct(GenericHazards.TextProduct):
def _dirInEnglish(self, direction):
dirList = ["North", "North-Northeast", "Northeast", "East-Northeast",
"East", "East-Southeast", "Southeast", "South-Southeast",
"South", "South-Southwest", "Southwest", "West-Southwest",
"West", "West-Northwest", "Northwest", "North-NorthWest"]
dirList = ["north", "north-northeast", "northeast", "east-northeast",
"east", "east-southeast", "southeast", "south-southeast",
"south", "south-southwest", "southwest", "west-southwest",
"west", "west-northwest", "northwest", "north-northwest"]
dirIndex = int((direction + 11.25) / 22.5)
if dirIndex > 15:
dirIndex = dirIndex - 16
@ -2873,7 +2874,7 @@ class TextProduct(GenericHazards.TextProduct):
if act in self._ignoreActions():
continue
if hdlns.index(hazardHdln) > 0:
t+= " AND "
t+= " and "
t+= "A " + hdln
reported += 1
if reported > 0:
@ -2936,7 +2937,7 @@ class TextProduct(GenericHazards.TextProduct):
if areaCount == 1:
conn = ""
elif areaCount == areaLen:
conn = " AND "
conn = " and "
else:
conn = "..."
if generalArea[1] != "":
@ -3384,9 +3385,9 @@ class TextProduct(GenericHazards.TextProduct):
# Skip HU.S headines
if (phen =='HU' and sig =='S'):
continue
if hdln[0] in ["A","I"]:a='AN '
elif hdln.find("FOR") == 0: a = ' '
else: a ='A '
if hdln[0] in ["A","I"]:a='an '
elif hdln.find("for") == 0: a = ' '
else: a ='a '
#print "\n Headline", hdln, phen
if areaWordMethod is not None:
@ -3504,7 +3505,7 @@ class TextProduct(GenericHazards.TextProduct):
if act in self._ignoreActions():
continue
if hdlns.index(hazardHdln) > 0:
t+= " AND "
t+= " and "
t+= "A " + hdln
reported += 1
if reported > 0:
@ -4052,7 +4053,7 @@ remain in port until this storm passes.
if act in self._ignoreActions():
continue
if hdlns.index(hazardHdln) > 0:
t+= " AND "
t+= " and "
t+= "A " + hdln
reported += 1
if reported > 0:
@ -4710,7 +4711,7 @@ remain in port until this storm passes.
"marine":self._frame("Small craft should remain in port or safe harbor until winds and seas subside. For any small craft who are in distress...or if you see someone else in distress...radio your situation according to maritime protocol. If appropriate...deploy your emergency distress beacon.")+"\n",
},
"NoImpact": {
"general": self._frame("THIS EVENT IS NO LONGER EXPECTED TO HAVE AN IMPACT ACROSS THE AREA AT THIS TIME. USE THE OPPORTUNITY TO REVISE PREPAREDNESS PLANS AND REMAIN PREPARED FOR FUTURE EVENTS.\n\nAdd other wrap-up wording here.")+"\n",
"general": self._frame("This event is no longer expected to have an impact across the area at this time. Use the opportunity to revise preparedness plans and remain prepared for future events.\n\nAdd other wrap-up wording here.")+"\n",
},
"LongTerm": {
"land": self._frame("Continue to listen to NOAA weather radio and other local news media for the latest information on storm impacts.\n\nIf you are using a portable generator...observe all safety precautions to avoid carbon monoxide poisoning...electrocution...or fires. Portable generators should be operated outdoors...in a dry and well ventilated place. Do not store fuel inside your home or garage.\n\nChain saws can be very helpful when removing fallen trees and large branches. Yet...operating a chain saw is dangerous work. Be sure to review operating procedures for safe cutting. To reduce the chance of mishap or injury...work with another person who has experience.\n\nDo not go sight seeing into areas which have been hardest hit as you may hinder ongoing rescue and recovery operations.\n\nStay out of flooded areas as the water may be contaminated or the road might have been washed away. Test drinking water before using...particularly from wells. Stay away from downed power lines too.")+"\n\n",
@ -4723,13 +4724,13 @@ remain in port until this storm passes.
return {
"InProgress": self._frame(
"""
although the system is losing its tropical characteristics...the
Although the system is losing its tropical characteristics...the
potential impacts are similar to those previously indicated
regardless of its nature. Continue with readiness actions as
recommended."""),
"Completed": self._frame(
"""
although the system has become non-tropical...the potential
Although the system has become non-tropical...the potential
impacts are similar to those previously indicated. Continue with
readiness actions as recommended."""),
}

View file

@ -144,7 +144,7 @@ class TextProduct(GenericReport.TextProduct):
if areaCount == 1:
conn = ""
elif areaCount == areaLen:
conn = " AND "
conn = " and "
else:
conn = "..."
if eachGeneralArea[1] != "":

View file

@ -480,7 +480,7 @@ class TextProduct(GenericHazards.TextProduct):
if self._elevationSource == "Grids":
### initialize the phrase
le = " FOR "
le = " for "
### Set the phrase from the forecaster selections
if len(self._rfwType) > 0:
### add the event type
@ -489,7 +489,7 @@ class TextProduct(GenericHazards.TextProduct):
le = le + phraseDict.get(t)[0]
### add zone numbers or generic location description to headline
if self._numInHeadline == 0:
le = le + "For |* location description *|"
le = le + "for |* location description *|"
else:
le = le + self._headlineNumbers(hazard['id'])
else:
@ -577,9 +577,9 @@ class TextProduct(GenericHazards.TextProduct):
numList.sort()
### initialize the zone number list
if len(numList) > 1:
numStr = "For fire weather zones "
numStr = "for fire weather zones "
else:
numStr = "For fire weather zone "
numStr = "for fire weather zone "
i = 0
for i in range (len(numList)):
@ -588,7 +588,7 @@ class TextProduct(GenericHazards.TextProduct):
elif (len(numList) - i) > 2: ### more than three zones, and/or last zone in list
numStr = numStr + numList[i] + "..."
elif (len(numList) - i) > 1: ### next to last zone in list
numStr = numStr + numList[i] + " AND "
numStr = numStr + numList[i] + " and "
return numStr
@ -657,7 +657,7 @@ class TextProduct(GenericHazards.TextProduct):
### include state name
if self._includeStateName == 1:
nameString = nameString + "IN " + stateList[0] + "..."
nameString = nameString + "In " + stateList[0] + "..."
### sort based on zone number
ugcList = sorted(ugcList, key=lambda ugc: ugc[2])
@ -680,14 +680,14 @@ class TextProduct(GenericHazards.TextProduct):
elif (len(ugcList) - i) > 2: ### more than three zones, and/or last zone in list
nameString = nameString + ugcList[i][2] + " " + "..."
elif (len(ugcList) - i) == 2: ### next to last zone in list
nameString = nameString + ugcList[i][2] + " " + " AND "
nameString = nameString + ugcList[i][2] + " " + " and "
else: ### more than one state
for state in stateList:
### include state name
if self._includeStateName == 1:
nameString = nameString + "IN " + state + "..."
nameString = nameString + "In " + state + "..."
newList = [] ### split up ugcList for each state.
for st, name, num in ugcList:
@ -715,7 +715,7 @@ class TextProduct(GenericHazards.TextProduct):
elif (len(newList) - i) > 2: ### more than three zones, and/or last zone in list
nameString = nameString+ newList[i][0] + " " + "..."
elif (len(newList) - i) == 2: ### next to last zone in list
nameString = nameString + newList[i][0] + " " + " AND "
nameString = nameString + newList[i][0] + " " + " and "
### get rid of any spaces in the ellipses
nameString = nameString.replace("... ","...")
@ -810,7 +810,7 @@ class TextProduct(GenericHazards.TextProduct):
else:
hazardTypeForWeather = ""
forPhrase = " FOR " + hazardTypeForWeather
forPhrase = " for " + hazardTypeForWeather
return forPhrase

View file

@ -641,21 +641,21 @@ class TextProduct(HLSTCV_Common.TextProduct):
phen, sig = phenSig.split('.')
headline = VTECTable.VTECTable[phenSig]["hdln"]
definition = "A " + headline + " MEANS "
definition = "A " + headline + " means "
if phen == "HU":
definition += "HURRICANE WIND CONDITIONS"
definition += "Hurricane wind conditions"
elif phen == "TR":
definition += "TROPICAL STORM WIND CONDITIONS"
definition += "Tropical storm wind conditions"
elif phen == "SS":
definition += "LIFE THREATENING INUNDATION LEVELS"
definition += "Life threatening inundation levels"
else:
return ""
if sig == "W": # Warning
definition += " ARE EXPECTED SOMEWHERE WITHIN THIS AREA AND WITHIN THE NEXT 36 HOURS"
definition += " are expected somewhere within this area and within the next 36 hours"
elif sig == "A": # Watch
definition += " ARE POSSIBLE SOMEWHERE WITHIN THIS AREA AND WITHIN THE NEXT 48 HOURS"
definition += " are possible somewhere within this area and within the next 48 hours"
return definition
@ -1940,7 +1940,7 @@ class FloodingRainSection(SectionCommon):
self._setProductPartValue(segmentDict, 'forecastSubsection', subsectionDict)
def _latestForecastSummary(self, segmentDict, productSegmentGroup, productSegment):
summary = "" # was "No flood watch is in effect"
summary = "" # was "No Flood Watch is in effect"
segment, vtecRecords = productSegment
headlines, _ = self._textProduct._getAdditionalHazards()

View file

@ -112,7 +112,7 @@ class TextProduct(GenericHazards.TextProduct):
#
if self._areaName != "":
self._areaName = " FOR " + self._areaName
self._areaName = " for " + self._areaName
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict,
self._productName + watchPhrase)
@ -375,16 +375,16 @@ class TextProduct(GenericHazards.TextProduct):
county2 = "In {area} this allows to expire {number} {placeTypes}"
indepCity1 = "In {area} this allows to expire {number} " +\
"independent city"
indepCity2 = "IN {area} THIS ALLOWS TO EXPIRE {number} " +\
indepCity2 = "In {area} this allows to expire {number} " +\
"independent cities"
marine = "This allows to expire the following adjacent coastal waters"
elif phraseType == "REPLACE":
county1 = "IN {area} THE NEW WATCH INCLUDES {number} {placeType}"
county2 = "IN {area} THE NEW WATCH INCLUDES {number} {placeTypes}"
indepCity1 = "IN {area} THE NEW WATCH INCLUDES {number} " + \
county1 = "In {area} the new watch includes {number} {placeType}"
county2 = "In {area} the new watch includes {number} {placeTypes}"
indepCity1 = "In {area} the new watch includes {number} " + \
"independent city"
indepCity2 = "IN {area} THE NEW WATCH INCLUDES {number} " + \
indepCity2 = "In {area} the new watch includes {number} " + \
"independent cities"
marine = "The new watch includes the following adjacent coastal waters"
@ -559,7 +559,7 @@ class TextProduct(GenericHazards.TextProduct):
def _makeTextFromCountyTuple(self, countyTuple, lineLength=66, colWidth=22,
mainFormatSingular="In {area} this watch includes {number} {placeType}",
mainFormatPlural="In {area} this watch includes {number} {placeTypes}",
subFormat="IN {area}", mode="byState"):
subFormat="In {area}", mode="byState"):
#countyTuple: (state, partOfStateAndState, name)
#The type of text depends upon the mode: "byState" or "byPart"

View file

@ -259,8 +259,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
(self._getAnalysisList(), self._timeRangeList, self._areaList))
def _preProcessProduct(self, fcst, argDict):
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n"
fcst = fcst + s.upper()
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):

View file

@ -69,7 +69,7 @@
# in the AWIPS text database.
# This value is also used for the default GUI entry for
# storage.
# awipsWANPil Defines the awips product identifier
# awipsWANPil Defines the AWIPS product identifier
# (e.g., KBOUCCFDEN) that is used to transmit the
# product to the AWIPS WAN.
# This value is also used for the default GUI
@ -78,7 +78,7 @@
# grid points in a zone that must contain the hazard
# in order for it to be considered. Tuple (percent, points)
#
# periodCombining If 1, compnents an attempt will be made to combine components
# periodCombining If 1, components an attempt will be made to combine components
# or time periods into one. Otherwise no period combining will
# will be done.
# useAbbreviations
@ -329,7 +329,6 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def postProcessPhrases(self, tree, node):
words = node.get("words")
if words is not None:
words = string.lower(words)
words = string.replace(words, "thunderstorms and rain showers",
"showers and thunderstorms")
words = string.replace(words, "snow showers and rain showers", "rain and snow showers")
@ -574,7 +573,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -582,12 +581,14 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n" + \
self._lakeStmt(argDict) + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._lakeStmt(argDict) + "\n\n"
fcst = fcst + self._Text1()
return fcst
@ -694,9 +695,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.

View file

@ -514,9 +514,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def splitDay24HourLabel_flag(self, tree, node):
# Return 0 to have the TimeDescriptor module label 24 hour periods
# with simply the weekday name (e.g. SATURDAY)
# with simply the weekday name (e.g. Saturday)
# instead of including the day and night periods
# (e.g. SATURDAY AND SATURDAY NIGHT)
# (e.g. Saturday and Saturday night)
# NOTE: If you set this flag to 1, make sure the "nextDay24HourLabel_flag"
# is set to zero.
# NOTE: This applied only to periods that are exactly 24-hours in length.
@ -920,18 +920,20 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict):
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
issuedByString = self.getIssuedByString()
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
fcst = fcst + self._Text1()
try:
text2 = self._Text2(argDict["host"])

View file

@ -419,7 +419,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
zoneTZ = localTZ
tzid = localTZid
LogStream.logProblem("WARNING: Entry " + area +
" missing from AreaDictionary. Using default time zone.")
" missing from AreaDictionary. Using default time zone.", LogStream.exc())
if (zoneTZ, tzid) not in tzs:
tzs.append((zoneTZ, tzid))
@ -674,14 +674,15 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
productName = self.checkTestMode(argDict,
productDescription)
fcst = fcst + self._pil + "\n\n"
fcst = fcst + productName + "\n"
fcst = fcst + "National Weather Service "
fcst = fcst + self._wfoCityState +"\n"
fcst = fcst + issuedByString
fcst = fcst + self._mndTimeLabel + "\n\n"
s = self._pil + "\n\n" + \
productName + "\n" + \
"National Weather Service " + \
self._wfoCityState +"\n" + \
issuedByString + \
self._mndTimeLabel + "\n\n"
fcst = fcst + s.upper()
return fcst
return fcst
def _preProcessArea(self, fcst, editArea, areaLabel, argDict, timeLabel):
# extract out the ugc codes and the area descriptors

View file

@ -41,8 +41,8 @@
# names in one of two formats, depending upon whether
# you are supporting regional headers. Choose one and
# use it throughout the product.
# (editAreaName, "REGIONLABEL\nCITYLABEL")
# (editAreaName, "CITYLABEL")
# (editAreaName, "Regionlabel\nCitylabel")
# (editAreaName, "Citylabel")
#
# productName defines name of product e.g. "Tabular State Forecast"
#
@ -158,9 +158,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"outputFile": "{prddir}/TEXT/SFT_<MultiPil>.txt",
"debug": 0,
"defaultEditAreas": [("area1", "REGION1\nCITY1"),
("area2", "REGION1\nCITY2"),
("area3", "REGION2\nCITY3"),
"defaultEditAreas": [("area1", "Region1\nCity1"),
("area2", "Region1\nCity2"),
("area3", "Region2\nCity3"),
],
# product identifiers
@ -354,15 +354,18 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# Add product heading to fcst string
issuedByString = self.getIssuedByString()
productName = self._productName + " FOR " + self._stateName
productName = self._productName + " for " + self._stateName
productName = self.checkTestMode(argDict, productName)
return fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n" +\
self._zoneCode + "-" + self._ddhhmmTimeExpire + "-\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n" + \
self._rowDescription() + "\n\n" + self._tableHeader() + "\n\n"
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
return fcst + self._rowDescription() + "\n\n" + self._tableHeader() + "\n\n"
def _preProcessArea(self, fcst, editArea, areaLabel, argDict):
# determine the region and area names, separated by a new line
@ -582,7 +585,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _popTimeLabel(self):
# Returns the valid time for the daily POP field
return " NIGHTTIME 6PM-6AM/DAYTIME 6AM-6PM"
return " nighttime 6PM-6AM/daytime 6AM-6PM"
def _qpfTimeLabel(self):
# Returns the valid time for the daily qpf field
@ -595,30 +598,30 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
ident = " "
# s is the built-up string containing the description
s = "ROWS INCLUDE...\n"
s = "Rows include...\n"
# Weather
s = s + ident + "DAILY PREDOMINANT DAYTIME WEATHER 6AM-6PM"
s = s + ident + "Daily predominant daytime weather 6AM-6PM"
# Temps
s = s + "\n" + ident + \
"FORECAST TEMPERATURES...EARLY MORNING LOW/DAYTIME HIGH"
"Forecast temperatures...early morning low/daytime high"
# PoP
if self._alwaysIncludePoP:
s = s + "\n" + ident + ident + ident + \
"PROBABILITY OF PRECIPITATION" + self._popTimeLabel()
"Probability of precipitation" + self._popTimeLabel()
# other stuff
s = s + "\n" + \
ident + ident + ident + " - INDICATES TEMPERATURES BELOW ZERO\n" + \
ident + ident + ident + "MM INDICATES MISSING DATA"
ident + ident + ident + " - indicates temperatures below zero\n" + \
ident + ident + ident + "MM indicates missing data"
#QPF
if self._alwaysIncludeQPF:
s = s + "\n" + ident + \
"QUANTITATIVE PRECIPITATION - INCHES -" + \
"Quantitative precipitation - inches -" + \
self._qpfTimeLabel()

View file

@ -59,7 +59,7 @@
# You can copy the information from the AreaDictionary as a starting point.
# Then add the following information for each zone:
#
# "landSeaArea": An edit area you need to create which contians grid
# "landSeaArea": An edit area you need to create which contains grid
# points along the coast, including both land and sea.
# "marineArea": Typically, the coastal waters area.
# "surfAreas": The surfAreas entry is an optional list of edit areas and labels
@ -67,18 +67,18 @@
# For example, If you have:
#
# surfAreas: [
# ("WestCoast", "Surf along west facing reefs.............."),
# ("NorthCoast", "Surf along north facing reefs............."),
# ("EastCoast", "Surf along east facing reefs.............."),
# ("SouthCoast", "Surf along south facing reefs............."),
# ("WestCoast", "SURF ALONG WEST FACING REEFS.............."),
# ("NorthCoast", "SURF ALONG NORTH FACING REEFS............."),
# ("EastCoast", "SURF ALONG EAST FACING REEFS.............."),
# ("SouthCoast", "SURF ALONG SOUTH FACING REEFS............."),
# ]
#
# You would get a surfHeight report for each surfArea listed:
#
# Surf along west facing reefs................10 TO 12 feet.
# Surf along north facing reefs...............4 TO 6 feet.
# Surf along east facing reefs................2 TO 3 feet.
# Surf along south facing reefs...............4 TO 6 feet.
# SURF ALONG WEST FACING REEFS................10 TO 12 feet.
# SURF ALONG NORTH FACING REEFS...............4 TO 6 feet.
# SURF ALONG EAST FACING REEFS................2 TO 3 feet.
# SURF ALONG SOUTH FACING REEFS...............4 TO 6 feet.
#
# If the list is empty, you will simply get surfHeight reported
# for the current value of the WaveHeight Grid sampled from the
@ -281,7 +281,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"ripGrid": "", # Use grid for rip_phrase
"waterSpoutGrid": "", # Use grid for waterSpout_phrase
"includeOutlook": 0, # If 1, OUTLOOK section included
"outLookText": "\n.OUTLOOK...",# Text for OUTLOOK section
"outLookText": "\n.Outlook...",# Text for OUTLOOK section
"tideFiles": { # For each tide table, list the file where it can
# be found
"Venice Inlet": "/data/local/localapps/tides/VeniceInlet.txt",
@ -313,7 +313,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"areaDictionary": "SurfAreaDictionary",
"language": "english",
"synopsisUGC": "", # UGC code for synopsis
"synopsisHeading": ".SYNOPSIS...",# Heading for synopsis
"synopsisHeading": ".Synopsis...",# Heading for synopsis
# If individualExtended == 1, an extended forecast will be
# generated for each individual area
# If extendedLabel == 1, a label will be included for each
@ -358,21 +358,21 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"WaveHeight" : "surf................",
"Swell": "swell",
"Swell2": "swell",
"LabelSwell": "swell...............",
"LabelSwell2": "secondary swell.....",
"Period": "period..............",
"Period2":"secondary period....",
"chop" : "water condition.....",
"rip" : "rip current risk....",
"HeatIndex": "heat index..........",
"20-foot winds......." : "beach winds.........",
"MaxT_FireWx":"max temperature.....",
"Sky/weather.........": "sky/weather.........",
"sst" : "water temperature...",
"uvi" : "UVI index...........",
"LAL" : "lightning threat....",
"WaterSpout" : "waterspout threat...",
"PoP" : "chance of...........",
"LabelSwell": "SWELL...............",
"LabelSwell2": "SECONDARY SWELL.....",
"Period": "PERIOD..............",
"Period2":"SECONDARY PERIOD....",
"chop" : "WATER CONDITION.....",
"rip" : "RIP CURRENT RISK....",
"HeatIndex": "HEAT INDEX..........",
"20-FOOT WINDS......." : "BEACH WINDS.........",
"MaxT_FireWx":"MAX TEMPERATURE.....",
"SKY/WEATHER.........": "SKY/WEATHER.........",
"sst" : "WATER TEMPERATURE...",
"uvi" : "UVI INDEX...........",
"LAL" : "LIGHTNING THREAT....",
"WaterSpout" : "WATERSPOUT THREAT...",
"PoP" : "CHANCE OF...........",
"MinT":"lows",
"MaxT":"highs",
"Wind": "winds",
@ -381,8 +381,8 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
"In effect" : "in effect",
# Used for single values
"around": "around ",
" valleys/lwr slopes...": " inland...............",
" ridges/upr slopes....": " coastal..............",
" VALLEYS/LWR SLOPES...": " INLAND...............",
" RIDGES/UPR SLOPES....": " COASTAL..............",
}
############################################################################
@ -857,7 +857,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
def _preProcessProduct(self, fcst, argDict,):
# Product header
if self._areaName != "":
productName = self._productName.strip() + " FOR " + \
productName = self._productName.strip() + " for " + \
self._areaName.strip()
else:
productName = self._productName.strip()
@ -865,11 +865,12 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
issuedByString = self.getIssuedByString()
productName = self.checkTestMode(argDict, productName)
fcst = fcst + self._wmoID + " " + self._fullStationID + " " + \
s = self._wmoID + " " + self._fullStationID + " " + \
self._ddhhmmTime + "\n" + self._pil + "\n\n" +\
productName + "\n" +\
"National Weather Service " + self._wfoCityState + \
"\n" + issuedByString + self._timeLabel + "\n\n"
fcst = fcst + s.upper()
# Try to get Synopsis from previous SRF
srfPil = self._statePil + self._srfPil
@ -937,8 +938,8 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
# "landSeaArea": "Extra0",
# "marineArea": "Extra1",
# "surfAreas": [
# ('NorthCoast', 'Surf along north facing reefs.............'),
# ('SouthCoast', 'Surf along south facing reefs.............')
# ('NorthCoast', 'SURF ALONG NORTH FACING REEFS.............'),
# ('SouthCoast', 'SURF ALONG SOUTH FACING REEFS.............')
# ],
# "tideTables": ["Cedar Key", "Venice Inlet"],
# },
@ -1704,7 +1705,7 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis):
if words is None:
return
if words == "":
words = "Missing"
words = "MISSING"
node.set("descriptor", "")
node.set("indentLabel", "Label"+elementName)
node.set("compound", 1)

View file

@ -118,7 +118,7 @@ Definition["autoWrite"] = 0 #set to 1 to write product to file
Definition["lacList"] = ["VAC910c", "NCC940c"]
Definition["defaultEditAreas"] = [
("area1","Southwest mountains including yourTown"),
("area1","Southwest Mountains including YourTown"),
("area2","Eastern Virginia"),
("area3","Northern North Carolina"),
]

View file

@ -136,11 +136,6 @@ public class GfePyIncludeUtil extends PythonIncludePathUtil {
return PATH_MANAGER.getLocalizationFile(ctx, HEADLINE);
}
public static LocalizationFile getTextProductsTemplatesLF(
LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, TEXT_PRODUCTS);
}
public static LocalizationFile getCombinationsLF(LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, COMBINATIONS);
}
@ -324,11 +319,6 @@ public class GfePyIncludeUtil extends PythonIncludePathUtil {
LocalizationLevel.BASE), HEADLINE);
}
public static String getTextProductsTemplatesIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.CAVE_STATIC,
LocalizationLevel.BASE), TEXT_PRODUCTS);
}
public static String getCombinationsIncludePath() {
return getCombinationsIncludePath(true);
}

View file

@ -31,298 +31,298 @@
VTECTable = {
'AF.W' : {'phen': 'AF',
'sig': 'W',
'hdln': 'ASHFALL WARNING'},
'hdln': 'Ashfall Warning'},
'AF.Y' : {'phen': 'AF',
'sig': 'Y',
'hdln': 'ASHFALL ADVISORY'},
'hdln': 'Ashfall Advisory'},
'AQ.Y' : {'phen': 'AQ',
'sig': 'Y',
'hdln': 'AIR QUALITY ALERT'},
'hdln': 'Air Quality Alert'},
'AS.O' : {'phen': 'AS',
'sig': 'O',
'hdln': 'AIR STAGNATION OUTLOOK'},
'hdln': 'Air Stagnation Outlook'},
'AS.Y' : {'phen': 'AS',
'sig': 'Y',
'hdln': 'AIR STAGNATION ADVISORY'},
'hdln': 'Air Stagnation Advisory'},
'BH.S' : {'phen': 'BH',
'sig': 'S',
'hdln': 'BEACH HAZARDS STATEMENT'},
'hdln': 'Beach Hazards Statement'},
'BW.Y' : {'phen': 'BW',
'sig': 'Y',
'hdln': 'BRISK WIND ADVISORY'},
'hdln': 'Brisk Wind Advisory'},
'BZ.A' : {'phen' : 'BZ',
'sig' : 'A',
'hdln' : 'BLIZZARD WATCH'},
'hdln' : 'Blizzard Watch'},
'BZ.W' : {'phen' : 'BZ',
'sig' : 'W',
'hdln' : 'BLIZZARD WARNING'},
'hdln' : 'Blizzard Warning'},
'CF.A' : {'phen': 'CF',
'sig': 'A',
'hdln': 'COASTAL FLOOD WATCH'},
'hdln': 'Coastal Flood Watch'},
'CF.W' : {'phen': 'CF',
'sig': 'W',
'hdln': 'COASTAL FLOOD WARNING'},
'hdln': 'Coastal Flood Warning'},
'CF.Y' : {'phen': 'CF',
'sig': 'Y',
'hdln': 'COASTAL FLOOD ADVISORY'},
'hdln': 'Coastal Flood Advisory'},
'CF.S' : {'phen': 'CF',
'sig': 'S',
'hdln': ''}, #No headline for this VTEC
'DS.W' : {'phen': 'DS',
'sig': 'W',
'hdln': 'DUST STORM WARNING'},
'hdln': 'Dust Storm Warning'},
'DU.Y' : {'phen': 'DU',
'sig': 'Y',
'hdln': 'BLOWING DUST ADVISORY'},
'hdln': 'Blowing Dust Advisory'},
'EC.A' : {'phen': 'EC',
'sig': 'A',
'hdln': 'EXTREME COLD WATCH'},
'hdln': 'Extreme Cold Watch'},
'EC.W' : {'phen': 'EC',
'sig': 'W',
'hdln': 'EXTREME COLD WARNING'},
'hdln': 'Extreme Cold Warning'},
'EH.A' : {'phen': 'EH',
'sig': 'A',
'hdln': 'EXCESSIVE HEAT WATCH'},
'hdln': 'Excessive Heat Watch'},
'EH.W' : {'phen': 'EH',
'sig': 'W',
'hdln': 'EXCESSIVE HEAT WARNING'},
'hdln': 'Excessive Heat Warning'},
'EW.W' : {'phen': 'EW',
'sig': 'W',
'hdln': 'EXCESSIVE WIND WARNING'},
'hdln': 'Excessive Wind Warning'},
'FA.A' : {'phen': 'FA',
'sig': 'A',
'hdln': 'FLOOD WATCH'},
'hdln': 'Flood Watch'},
'FA.W' : {'phen': 'FA',
'sig': 'W',
'hdln': 'AREAL FLOOD WARNING'},
'hdln': 'Areal Flood Warning'},
'FA.Y' : {'phen': 'FA',
'sig': 'Y',
'hdln': 'AREAL FLOOD ADVISORY'},
'hdln': 'Areal Flood Advisory'},
'FF.A' : {'phen': 'FF',
'sig': 'A',
'hdln': 'FLASH FLOOD WATCH'},
'hdln': 'Flash Flood Watch'},
'FF.W' : {'phen': 'FF',
'sig': 'W',
'hdln': 'FLASH FLOOD WARNING'},
'hdln': 'Flash Flood Warning'},
'FG.Y' : {'phen': 'FG',
'sig': 'Y',
'hdln': 'DENSE FOG ADVISORY'},
'hdln': 'Dense Fog Advisory'},
'FL.A' : {'phen': 'FL',
'sig': 'A',
'hdln': 'FLOOD WATCH'},
'hdln': 'Flood Watch'},
'FL.W' : {'phen': 'FL',
'sig': 'W',
'hdln': 'FLOOD WARNING'},
'hdln': 'Flood Warning'},
'FL.Y' : {'phen': 'FL',
'sig': 'Y',
'hdln': 'FLOOD ADVISORY'},
'hdln': 'Flood Advisory'},
'FR.Y' : {'phen': 'FR',
'sig': 'Y',
'hdln': 'FROST ADVISORY'},
'hdln': 'Frost Advisory'},
'FW.A' : {'phen': 'FW',
'sig': 'A',
'hdln': 'FIRE WEATHER WATCH'},
'hdln': 'Fire Weather Watch'},
'FW.W' : {'phen': 'FW',
'sig': 'W',
'hdln': 'RED FLAG WARNING'},
'hdln': 'Red Flag Warning'},
'FZ.A' : {'phen': 'FZ',
'sig': 'A',
'hdln': 'FREEZE WATCH'},
'hdln': 'Freeze Watch'},
'FZ.W' : {'phen': 'FZ',
'sig': 'W',
'hdln': 'FREEZE WARNING'},
'hdln': 'Freeze Warning'},
'GL.A' : {'phen': 'GL',
'sig': 'A',
'hdln': 'GALE WATCH'},
'hdln': 'Gale Watch'},
'GL.W' : {'phen': 'GL',
'sig': 'W',
'hdln': 'GALE WARNING'},
'hdln': 'Gale Warning'},
'HF.A' : {'phen': 'HF',
'sig': 'A',
'hdln': 'HURRICANE FORCE WIND WATCH'},
'hdln': 'Hurricane Force Wind Watch'},
'HF.W' : {'phen': 'HF',
'sig': 'W',
'hdln': 'HURRICANE FORCE WIND WARNING'},
'hdln': 'Hurricane Force Wind Warning'},
'HT.Y' : {'phen': 'HT',
'sig': 'Y',
'hdln': 'HEAT ADVISORY'},
'hdln': 'Heat Advisory'},
'HU.A' : {'phen': 'HU',
'sig': 'A',
'hdln': 'HURRICANE WATCH'},
'hdln': 'Hurricane Watch'},
'HU.S' : {'phen': 'HU',
'sig': 'S',
'hdln': ''}, #No headline for this VTEC
'HU.W' : {'phen': 'HU',
'sig': 'W',
'hdln': 'HURRICANE WARNING'},
'hdln': 'Hurricane Warning'},
'HW.A' : {'phen': 'HW',
'sig': 'A',
'hdln': 'HIGH WIND WATCH'},
'hdln': 'High Wind Watch'},
'HW.W' : {'phen': 'HW',
'sig': 'W',
'hdln': 'HIGH WIND WARNING'},
'hdln': 'High Wind Warning'},
'HZ.A' : {'phen': 'HZ',
'sig': 'A',
'hdln': 'HARD FREEZE WATCH'},
'hdln': 'Hard Freeze Watch'},
'HZ.W' : {'phen': 'HZ',
'sig': 'W',
'hdln': 'HARD FREEZE WARNING'},
'hdln': 'Hard Freeze Warning'},
'IS.W' : {'phen': 'IS',
'sig': 'W',
'hdln': 'ICE STORM WARNING'},
'hdln': 'Ice Storm Warning'},
'LE.A' : {'phen': 'LE',
'sig': 'A',
'hdln': 'LAKE EFFECT SNOW WATCH'},
'hdln': 'Lake Effect Snow Watch'},
'LE.W' : {'phen': 'LE',
'sig': 'W',
'hdln': 'LAKE EFFECT SNOW WARNING'},
'hdln': 'Lake Effect Snow Warning'},
'LE.Y' : {'phen': 'LE',
'sig': 'Y',
'hdln': 'LAKE EFFECT SNOW ADVISORY'},
'hdln': 'Lake Effect Snow Advisory'},
'LO.Y' : {'phen': 'LO',
'sig': 'Y',
'hdln': 'LOW WATER ADVISORY'},
'hdln': 'Low Water Advisory'},
'LS.A' : {'phen': 'LS',
'sig': 'A',
'hdln': 'LAKESHORE FLOOD WATCH'},
'hdln': 'Lakeshore Flood Watch'},
'LS.S' : {'phen': 'LS',
'sig': 'S',
'hdln': ''}, #No headline for this VTEC
'LS.W' : {'phen': 'LS',
'sig': 'W',
'hdln': 'LAKESHORE FLOOD WARNING'},
'hdln': 'Lakeshore Flood Warning'},
'LS.Y' : {'phen': 'LS',
'sig': 'Y',
'hdln': 'LAKESHORE FLOOD ADVISORY'},
'hdln': 'Lakeshore Flood Advisory'},
'LW.Y' : {'phen': 'LW',
'sig': 'Y',
'hdln': 'LAKE WIND ADVISORY'},
'hdln': 'Lake Wind Advisory'},
'MA.S' : {'phen': 'MA',
'sig': 'S',
'hdln': ''}, #No headline for this VTEC
'MA.W' : {'phen': 'MA',
'sig': 'W',
'hdln': 'SPECIAL MARINE WARNING'},
'hdln': 'Special Marine Warning'},
'MF.Y' : {'phen': 'MF',
'sig': 'Y',
'hdln': 'DENSE FOG ADVISORY'}, # Marine Fog
'hdln': 'Dense Fog Advisory'}, # Marine Fog
'MH.W' : {'phen': 'MH',
'sig': 'W',
'hdln': 'ASHFALL WARNING'}, # Marine Ashfall
'hdln': 'Ashfall Warning'}, # Marine Ashfall
'MH.Y' : {'phen': 'MH',
'sig': 'Y',
'hdln': 'ASHFALL ADVISORY'}, # Marine Ashfall
'hdln': 'Ashfall Advisory'}, # Marine Ashfall
'MS.Y' : {'phen': 'MS',
'sig': 'Y',
'hdln': 'DENSE SMOKE ADVISORY'}, # Marine Smoke
'hdln': 'Dense Smoke Advisory'}, # Marine Smoke
'RB.Y' : {'phen': 'RB',
'sig': 'Y',
'hdln': 'SMALL CRAFT ADVISORY FOR ROUGH BAR'},
'hdln': 'Small Craft Advisory for rough bar'},
'RP.S' : {'phen': 'RP',
'sig' : 'S',
'hdln': 'HIGH RIP CURRENT RISK'}, #DR 21037 change
'hdln': 'High Rip Current Risk'}, #DR 21037 change
'SC.Y' : {'phen': 'SC',
'sig': 'Y',
'hdln': 'SMALL CRAFT ADVISORY'},
'hdln': 'Small Craft Advisory'},
'SE.A' : {'phen': 'SE',
'sig': 'A',
'hdln': 'HAZARDOUS SEAS WATCH'},
'hdln': 'Hazardous Seas Watch'},
'SE.W' : {'phen': 'SE',
'sig': 'W',
'hdln': 'HAZARDOUS SEAS WARNING'},
'hdln': 'Hazardous Seas Warning'},
'SI.Y' : {'phen': 'SI',
'sig': 'Y',
'hdln': 'SMALL CRAFT ADVISORY FOR WINDS'},
'hdln': 'Small Craft Advisory for winds'},
'SM.Y' : {'phen': 'SM',
'sig': 'Y',
'hdln': 'DENSE SMOKE ADVISORY'},
'hdln': 'Dense Smoke Advisory'},
'SR.A' : {'phen': 'SR',
'sig': 'A',
'hdln': 'STORM WATCH'},
'hdln': 'Storm Watch'},
'SR.W' : {'phen': 'SR',
'sig': 'W',
'hdln': 'STORM WARNING'},
'hdln': 'Storm Warning'},
'SS.A' : {'phen': 'SS',
'sig': 'A',
'hdln': 'STORM SURGE WATCH'},
'hdln': 'Storm Surge Watch'},
'SS.W' : {'phen': 'SS',
'sig': 'W',
'hdln': 'STORM SURGE WARNING'},
'hdln': 'Storm Surge Warning'},
'SU.W' : {'phen': 'SU',
'sig': 'W',
'hdln': 'HIGH SURF WARNING'},
'hdln': 'High Surf Warning'},
'SU.Y' : {'phen': 'SU',
'sig': 'Y',
'hdln': 'HIGH SURF ADVISORY'},
'hdln': 'High Surf Advisory'},
'SV.A' : {'phen': 'SV',
'sig': 'A',
'hdln': 'SEVERE THUNDERSTORM WATCH'},
'hdln': 'Severe Thunderstorm Watch'},
'SV.W' : {'phen': 'SV',
'sig': 'W',
'hdln': 'SEVERE THUNDERSTORM WARNING'},
'hdln': 'Severe Thunderstorm Warning'},
'SW.Y' : {'phen': 'SW',
'sig': 'Y',
'hdln': 'SMALL CRAFT ADVISORY FOR HAZARDOUS SEAS'},
'hdln': 'Small Craft Advisory for hazardous seas'},
'TO.A' : {'phen': 'TO',
'sig': 'A',
'hdln': 'TORNADO WATCH'},
'hdln': 'Tornado Watch'},
'TO.W' : {'phen': 'TO',
'sig': 'W',
'hdln': 'TORNADO WARNING'},
'hdln': 'Tornado Warning'},
'TR.A' : {'phen': 'TR',
'sig': 'A',
'hdln': 'TROPICAL STORM WATCH'},
'hdln': 'Tropical Storm Watch'},
'TR.W' : {'phen': 'TR',
'sig': 'W',
'hdln': 'TROPICAL STORM WARNING'},
'hdln': 'Tropical Storm Warning'},
'TS.A' : {'phen': 'TS',
'sig': 'A',
'hdln': 'TSUNAMI WATCH'},
'hdln': 'Tsunami Watch'},
'TS.W' : {'phen': 'TS',
'sig': 'W',
'hdln': 'TSUNAMI WARNING'},
'hdln': 'Tsunami Warning'},
'TY.A' : {'phen': 'TY',
'sig': 'A',
'hdln': 'TYPHOON WATCH'},
'hdln': 'Typhoon Watch'},
'TY.W' : {'phen': 'TY',
'sig': 'W',
'hdln': 'TYPHOON WARNING'},
'hdln': 'Typhoon Warning'},
'UP.A' : {'phen': 'UP',
'sig': 'A',
'hdln': 'HEAVY FREEZING SPRAY WATCH'},
'hdln': 'Heavy Freezing Spray Watch'},
'UP.W' : {'phen': 'UP',
'sig': 'W',
'hdln': 'HEAVY FREEZING SPRAY WARNING'},
'hdln': 'Heavy Freezing Spray Warning'},
'UP.Y' : {'phen': 'UP',
'sig': 'Y',
'hdln': 'FREEZING SPRAY ADVISORY'},
'hdln': 'Freezing Spray Advisory'},
'WC.A' : {'phen': 'WC',
'sig': 'A',
'hdln': 'WIND CHILL WATCH'},
'hdln': 'Wind Chill Watch'},
'WC.W' : {'phen': 'WC',
'sig': 'W',
'hdln': 'WIND CHILL WARNING'},
'hdln': 'Wind Chill Warning'},
'WC.Y' : {'phen': 'WC',
'sig': 'Y',
'hdln': 'WIND CHILL ADVISORY'},
'hdln': 'Wind Chill Advisory'},
'WI.Y' : {'phen': 'WI',
'sig': 'Y',
'hdln': 'WIND ADVISORY'},
'hdln': 'Wind Advisory'},
'WS.A' : {'phen': 'WS',
'sig': 'A',
'hdln': 'WINTER STORM WATCH'},
'hdln': 'Winter Storm Watch'},
'WS.W' : {'phen': 'WS',
'sig': 'W',
'hdln': 'WINTER STORM WARNING'},
'hdln': 'Winter Storm Warning'},
'WW.Y' : {'phen': 'WW',
'sig': 'Y',
'hdln': 'WINTER WEATHER ADVISORY'},
'hdln': 'Winter Weather Advisory'},
'ZF.Y' : {'phen': 'ZF',
'sig': 'Y',
'hdln': 'FREEZING FOG ADVISORY'},
'hdln': 'Freezing Fog Advisory'},
'ZR.Y' : {'phen': 'ZR',
'sig': 'Y',
'hdln': 'FREEZING RAIN ADVISORY'},
'hdln': 'Freezing Rain Advisory'},
}
#