awips2/cave/com.raytheon.viz.avnconfig/localization/aviation/python/RouteInfoEditor.py
Max Schenkelberg 3c02342d04 Issue #2033 moved avnfps and text workstation files into respective plugins.
Change-Id: If95cb839ad81ca2a842ff7f6926847ac3928d8f2

Former-commit-id: db24201469 [formerly bbad83c21a] [formerly 6f60751ec6] [formerly db24201469 [formerly bbad83c21a] [formerly 6f60751ec6] [formerly c5575f9624 [formerly 6f60751ec6 [formerly 77e1a4d8f5237e5fae930c1e00589c752f8b3738]]]]
Former-commit-id: c5575f9624
Former-commit-id: 62f4f1bafb [formerly 8139e0dfb7] [formerly 33159773a1764cd4fb517d13a3cff0a11feaa433 [formerly 8de539020d]]
Former-commit-id: 094fceec6e1d9989f5e80a4efe1310f8a093b3ef [formerly 451eb54a36]
Former-commit-id: f553c93092
2013-08-15 12:21:43 -05:00

353 lines
12 KiB
Python

##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#
# Name:
# RouteInfoEditor.py
# GFS1-NHD:A8058.0000-SCRIPT;9
#
# Status:
# DELIVERED
#
# History:
# Revision 9 (DELIVERED)
# Created: 29-JUN-2006 07:50:31 TROJAN
# spr 7181: modified "Update" action logic
#
# Revision 8 (DELIVERED)
# Created: 27-JUL-2005 18:35:32 TROJAN
# spr 6948
#
# Revision 7 (APPROVED)
# Created: 06-JUL-2005 20:50:39 TROJAN
# spr 6910
#
# Revision 6 (DELIVERED)
# Created: 07-MAY-2005 11:37:44 OBERFIEL
# Added Item Header Block
#
# Revision 5 (DELIVERED)
# Created: 04-APR-2005 14:16:29 TROJAN
# spr 6777
#
# Revision 4 (APPROVED)
# Created: 21-MAR-2005 15:45:20 TROJAN
# spr 6732
#
# Revision 3 (APPROVED)
# Created: 21-MAR-2005 15:14:37 TROJAN
# spr 6732
#
# Revision 2 (DELIVERED)
# Created: 19-JAN-2005 14:47:13 TROJAN
# spr 6563
#
# Revision 1 (APPROVED)
# Created: 30-SEP-2004 18:19:22 TROJAN
# rewrite of avnsetup
#
# Change Document History:
# 1:
# Change Document: GFS1-NHD_SPR_7181
# Action Date: 26-FEB-2007 09:50:36
# Relationship Type: In Response to
# Status: BUILD_RELEASE
# Title: AvnFPS: Update button for TAF and TWEB site editor GUIs does not work
#
#
# RouteInfoEditor.py
# Aviation setup editor
# Author: George Trojan, SAIC/MDL, September 2004
# last update: 06/28/06
import logging, os, re
import ConfigParser
from Tkinter import *
import Pmw
from Balloon import Balloon
import Avn, AvnDialog, AvnParser, EditDialog
_Help = {
'title': 'Route Setup Help',
'content': """
This dialog is used to define TWEB route information.
To add a new site, enter site id and press "Update". Edit displayed
entries and press "Save". Create default template files.
To load current configuration, enter site id and press <Enter>
or use the "Load" button".
To create template files, press "Make" in the "Templates" area.
To edit template file, press "Edit" in the "Templates" area.
You can use "Update" button to extract information from AWIPS
configuration files. Only non-empty fields will be overwritten.
"""
}
_A2A = '%s/data/afos2awips.txt' % os.environ['FXA_HOME']
_Logger = logging.getLogger(__name__)
def _validateAFOS(text):
text = text.strip()
length = len(text)
if length < 8:
return Pmw.PARTIAL
value = text.upper()
if re.match('^[A-Z]{3,3}TWB[(0-9)|(A-Z)]{2,3}$', value):
return Pmw.OK
else:
if length == 9:
return Pmw.ERROR
else:
return Pmw.PARTIAL
def _validateWMO(text):
text = text.strip()
length = len(text)
if length < 11:
return Pmw.PARTIAL
value = text.upper()
if re.match('^[A-Z]{4}[0-9]{2} [A-Z]{4}$', value):
return Pmw.OK
else:
return Pmw.ERROR
def _validateIdent(text):
for x in text.split(','):
n = len(x)
if n == 0:
continue
elif n > 4:
return Pmw.ERROR
elif n < 4:
return Pmw.PARTIAL
if Pmw.alphanumericvalidator(x) == Pmw.ERROR:
return Pmw.ERROR
return Pmw.OK
def getHeaders(ident):
tid = 'TWB'+ident[1:]
for line in file(_A2A):
if line[3:9] == tid:
return line.rstrip().split(None, 1)
else:
return None
##############################################################################
class Editor(AvnDialog.Dialog):
Sites = ['METARS', 'TAFS']
def __init__(self, parent, **kw):
AvnDialog.Dialog.__init__(self, parent, **kw)
self.title(Avn.Name + ' TWEB Route Info')
# from AvnDialog
self.createMessageBar(self.interior(), True)
interior = self.interior()
frame = Frame(interior, relief='ridge', bd=2)
self.site = Pmw.EntryField(frame,
labelpos='w',
label_text='Route',
entry_width=4,
validate={'validator': 'alphanumeric',
'min': 3, 'max': 3, 'minstrict': 0},
command=self.__load,
)
self.site.pack(side='left', expand='no', padx=5)
bbox = Pmw.ButtonBox(frame)
btn = bbox.add('Load', command=self.__load)
Balloon().bind(btn, 'Retrieves data for selected site')
btn = bbox.add('Update', command=self.__update)
Balloon().bind(btn, 'Retrieves site info from fxa data files')
btn = bbox.add('Save', command=self.__save)
Balloon().bind(btn, 'Saves route info to a file')
btn = bbox.add('Close', command=self.close)
Balloon().bind(btn, 'Closes this dialog')
btn = bbox.add('Help', command=Avn.curry(self.showHelp, _Help))
Balloon().bind(btn, 'Shows help')
bbox.alignbuttons()
bbox.pack(side='right', expand='no')
frame.pack(side='top', expand='yes', fill='x')
group = Pmw.Group(interior, tag_text='Headers')
self.wmo = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='WMO',
entry_width=12,
validate=_validateWMO,
)
self.wmo.grid(row=0, column=0, sticky='ew', padx=20)
self.afos = Pmw.EntryField(group.interior(),
labelpos='w',
label_text='AFOS',
entry_width=9,
validate=_validateAFOS,
)
self.afos.grid(row=0, column=1, sticky='ew', padx=20)
group.pack(side='top', expand='yes', fill='x', pady=5)
group = Pmw.Group(interior, tag_text='Associated ids')
self.ident = {}
for n, tag in enumerate(self.Sites):
self.ident[tag] = Pmw.EntryField(group.interior(),
labelpos='w',
label_text=tag,
entry_width=64,
validate=_validateIdent,
)
self.ident[tag].grid(row=n, column=0, sticky='e')
group.pack(side='top', expand='yes', fill='x', pady=5)
group = Pmw.Group(interior, tag_text='Template')
bbox = Pmw.ButtonBox(group.interior())
btn = bbox.add('Edit', command=self.__editTemplate)
Balloon().bind(btn, 'Template editor')
btn = bbox.add('Make', command=self.__makeTemplate)
Balloon().bind(btn, 'Makes default template')
bbox.alignbuttons()
bbox.pack(side='top')
group.pack(side='top', expand='yes', fill='x', pady=5)
self.initialiseoptions(Editor)
self.setGeometry()
def __clear(self):
self.wmo.clear()
self.afos.clear()
for tag in self.Sites:
self.ident[tag].clear()
def __validate(self):
if not self.site.valid():
msg = 'Invalid site id'
self.messagebar().message('usererror', msg)
return
for tag in self.Sites:
if not self.ident[tag].valid():
return False
return True
def __load(self):
self.messagebar().resetmessages('systemerror')
if not self.site.valid():
msg = 'Invalid site id'
self.messagebar().message('usererror', msg)
return
ident = self.site.getvalue().upper()
cfg = AvnParser.getTwbSiteCfg(ident)
if cfg is None:
self.__clear()
msg = 'Failed to retrieve configuration for %s' % ident
self.messagebar().message('systemerror', msg)
return
self.wmo.setvalue(cfg['headers']['wmo'])
self.afos.setvalue(cfg['headers']['afos'])
for tag in self.Sites:
# FIXME: it's a list! And strip trailing 's'
ids = cfg['sites'][tag.lower()[:-1]]
self.ident[tag].setvalue(','.join(ids))
def __update(self):
self.messagebar().resetmessages('systemerror')
if not self.site.valid():
msg = 'Invalid site id'
self.messagebar().message('usererror', msg)
return
ident = self.site.getvalue().upper()
hdr = getHeaders(ident)
if hdr:
self.afos.setvalue(hdr[0])
self.wmo.setvalue(hdr[1])
else:
msg = 'Failed to find headers for %s' % ident
self.messagebar().message('systemerror', msg)
_Logger.exception(msg)
def __save(self):
self.messagebar().resetmessages('systemerror')
if not self.__validate():
msg = 'Invalid entry'
self.messagebar().message('usererror', msg)
return
ident = self.site.getvalue().upper()
path = os.path.join('etc', 'twbs', ident, 'info.cfg')
try:
cp = ConfigParser.ConfigParser()
cp.add_section('headers')
wmo = self.wmo.getvalue().strip().upper()
cp.set('headers', 'wmo', wmo)
afos = self.afos.getvalue().strip().upper()
cp.set('headers', 'afos', afos)
cp.add_section('sites')
for tag in self.Sites:
s = self.ident[tag].getvalue().strip().upper()
cp.set('sites', tag, s)
try:
if not os.path.exists(os.path.dirname(path)):
os.mkdir(os.path.dirname(path))
fp = file(path, 'w')
fp.write('# %s\n\n' % path)
cp.write(fp)
finally:
fp.close()
msg = 'Updated %s' % path
self.messagebar().message('systemevent', msg)
except Exception, e:
msg = 'Failed to update %s' % path
_Logger.exception(msg)
self.messagebar().message('systemerror', msg)
def __makeTemplate(self):
self.messagebar().resetmessages('systemerror')
if not self.site.valid():
msg = 'Invalid site id'
self.messagebar().message('usererror', msg)
return
ident = self.site.getvalue().upper()
path = os.path.join('etc', 'twbs', ident, 'template')
if os.path.exists(path):
return
try:
if not os.path.exists(os.path.dirname(path)):
os.mkdir(os.path.dirname(path))
file(path, 'w').write('%s TWEB DDHHMM \n\n' % ident)
msg = 'Template files created'
self.messagebar().message('userevent', msg)
except IOError:
msg = 'Cannot make template %s' % path
_Logger.exception(msg)
self.messagebar().message('systemerror', msg)
def __editTemplate(self):
if not hasattr(self, '_textEditor'):
self._textEditor = EditDialog.Editor(self.interior())
if not self.site.valid():
msg = 'Invalid site id'
self.messagebar().message('usererror', msg)
return
ident = self.site.getvalue().upper()
path = os.path.join('etc', 'twbs', ident, 'template')
if os.path.exists(path):
self._textEditor.getFile(path)
self._textEditor.setworkdir(os.path.dirname(path))
self._textEditor.display()