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

Former-commit-id: 77e1a4d8f5237e5fae930c1e00589c752f8b3738
2013-08-15 12:21:43 -05:00

385 lines
14 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:
# ProductDialog.py
# GFS1-NHD:A8056.0000-SCRIPT;13
#
# Status:
# $TO_BE_DEFINED
#
# History:
# Revision 12 (DELIVERED)
# Created: 01-JUN-2006 08:37:50 TROJAN
# spr 7157 - errors when adding new product
#
# Revision 11 (REVIEW)
# Created: 01-JUN-2006 08:34:30 TROJAN
# spr 7156 - errors when adding new product
#
# Revision 10 (DELIVERED)
# Created: 23-MAR-2006 15:14:14 TROJAN
# spr 7109 - modified method to determine work PIL
#
# Revision 9 (DELIVERED)
# Created: 22-MAR-2006 13:05:17 TROJAN
# spr 7110. Revised TAF handling for consistency
#
# Revision 8 (DELIVERED)
# Created: 29-JAN-2006 12:25:33 TROJAN
# spr 7083
#
# Revision 7 (DELIVERED)
# Created: 06-JUL-2005 20:50:38 TROJAN
# spr 6910
#
# Revision 6 (DELIVERED)
# Created: 01-JUN-2005 17:41:18 OBERFIEL
# Bug fixes since RHE3 initial snapshot
#
# Revision 5 (DELIVERED)
# Created: 07-MAY-2005 11:37:00 OBERFIEL
# Added Item Header Block
#
# Revision 4 (DELIVERED)
# Created: 18-APR-2005 17:32:17 OBERFIEL
# Changes to support gamin
#
# Revision 3 (DELIVERED)
# Created: 28-FEB-2005 19:42:40 TROJAN
# spr 6284
#
# Revision 2 (APPROVED)
# Created: 28-FEB-2005 19:04:55 TROJAN
# spr 6685
#
# Revision 1 (BUILD_RELEASE)
# Created: 30-SEP-2004 18:17:38 TROJAN
# rewrite of avnsetup
#
# Change Document History:
# 1:
# Change Document: GFS1-NHD_SPR_7407
# Action Date: 29-SEP-2008 15:38:12
# Relationship Type: In Response to
# Status: UNDER WORK
# Title: AvnFPS: Allow WFOs to update HDF5 climate files
#
#
# ProductDialog.py
# Aviation setup editor
# Author: George Trojan, SAIC/MDL, September 2004
# last update: 06/01/06
import logging, os
import ConfigParser
from Tkinter import *
import Pmw
from Balloon import Balloon
import Avn, AvnDialog, AvnParser, Busy
_Help = {
'title': 'Route Setup Help',
'content': """
This dialog is used to define TAF/TWEB product (list of forecasts).
Thee products should be defined AFTER relevant site/route configuration
files have been created.
To add a new product, enter product label in the "Products" entry
field and press <Enter>. Then enter all TAF ids or TWEB routes in
the "Idents" entry field, press <Enter> after typing one item.
Press "Save" button to save configuration file.
To remove a product, press "Delede" below "Products" list.
To remove an ident from the product definition, use "Delete"
button in the "Idents" column. You must then save the product.
This will NOT delete TAF/TWEB configuration files, this can only be
done from the command line.
The "Verify" button can be used to check for existence and proper
syntax of all relevant files.
"""
}
_Logger = logging.getLogger(__name__)
##############################################################################
class _Editor(AvnDialog.Dialog):
Key = ''
def __init__(self, parent, **kw):
AvnDialog.Dialog.__init__(self, parent, **kw)
# from AvnDialog
self.createMessageBar(self.interior(), True)
frame = Frame(self.interior())
self.products = Pmw.ComboBox(frame,
label_text='Products',
labelpos='n',
dropdown=0,
scrolledlist_vscrollmode='static',
listbox_width=16,
entryfield_entry_width=16,
listbox_exportselection=0,
selectioncommand=self.listIdents,
)
self.products.grid(row=0, column=0, sticky='news')
btn = Button(frame, text='Delete', command=self.__deleteProduct)
btn.grid(row=1, column=0, sticky='news')
frame.grid_rowconfigure(0, weight=1)
frame.grid_rowconfigure(1, weight=0)
frame.pack(side='left', expand='yes', fill='both')
frame = Frame(self.interior())
self.idents = Pmw.ComboBox(frame,
label_text='Idents',
labelpos='n',
dropdown=0,
scrolledlist_vscrollmode='static',
listbox_width=4,
entryfield_entry_width=4,
listbox_exportselection=0,
)
self.idents.grid(row=0, column=0, sticky='news')
btn = Button(frame, text='Delete', command=self.__deleteIdent)
btn.grid(row=1, column=0, sticky='news')
Balloon().bind(btn, 'Delete selected id from list')
frame.grid_rowconfigure(0, weight=1)
frame.grid_rowconfigure(1, weight=0)
frame.pack(side='left', expand='yes', fill='both', padx=5)
bbox = Pmw.ButtonBox(self.interior(),
orient='vertical',
hull_borderwidth=2,
hull_relief='groove',
pady=1,
)
btn = bbox.add('Save', command=self.__save)
Balloon().bind(btn, 'Saves route info to a file')
btn = bbox.add('Verify', command=self.verify)
Balloon().bind(btn, 'Verifies existence of all relevant files')
btn = bbox.add('Default', command=self.__setDefault)
Balloon().bind(btn, 'Makes selected product default one')
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='top', expand='no')
self.pil = Pmw.EntryField(self.interior(),
labelpos='n',
label_text='Work PIL',
entry_width=9,
validate={'validator': 'alphabetic', 'minstrict': 0, \
'min': 8, 'max': 9}
)
self.pil.pack(side='top', expand='no')
self.initialiseoptions(_Editor)
self.setGeometry()
def __deleteIdent(self):
self.messagebar().resetmessages('systemerror')
try:
self.idents.delete('active')
except IndexError:
self.messagebar().message('usererror', 'Select ident to delete')
return
def __deleteProduct(self):
self.messagebar().resetmessages('systemerror')
try:
item = self.products.getcurselection()[0]
path = os.path.join('etc', self.Key, item+'.cfg')
if not Busy.askokcancel('This will remove file %s' % \
path + '\nAre you sure?', self.interior()):
return
os.unlink(path)
self.products.delete('active')
msg = 'Deleted %s' % os.path.basename(path)
_Logger.info(msg)
self.messagebar().message('userevent', msg)
except IndexError:
self.messagebar().message('usererror', 'Select product to delete')
except Exception:
msg = 'Cannot delete %s' % os.path.basename(path)
_Logger.exception(msg)
self.messagebar().message('systemerror', msg)
def __setDefault(self):
self.messagebar().resetmessages('systemerror')
try:
item = self.products.getcurselection()[0]
file(os.path.join('etc', self.Key, 'DEFAULT'), 'w').write(item+'\n')
products = list(self.products.get(0, 'end'))
products.remove(item)
products.sort()
products.insert(0, item)
self.products.setlist(products)
except IndexError:
self.messagebar().message('usererror',
'Select product to mark as default')
except IOError:
msg = 'Cannot write DEFAULT file'
_Logger.exception(msg)
self.messagebar().message('systemerror', msg)
def __save(self):
self.messagebar().resetmessages('systemerror')
try:
product = self.products.getcurselection()[0]
idents = [i.upper() for i in self.idents.get(0, 'end')]
if self.pil.valid():
pil = self.pil.get().strip().upper()
else:
Busy.showerror('Invalid Work PIL', self.interior())
return
path = os.path.join('etc', self.Key, product+'.cfg')
cp = ConfigParser.ConfigParser()
cp.add_section('sites')
cp.set('sites', 'idents', ','.join(idents))
cp.set('sites', 'workpil', pil)
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 IndexError:
self.messagebar().message('usererror', 'Select product to save')
except Exception:
msg = 'Failed to update %s' % path
_Logger.exception(msg)
##############################################################################
class TafEditor(_Editor):
Key = 'tafs'
def __init__(self, parent, **kw):
_Editor.__init__(self, parent, **kw)
self.title(Avn.Name + ' TAF Product Configuration')
def verify(self):
self.messagebar().resetmessages('systemerror')
try:
product = self.products.getcurselection()[0]
cfg = AvnParser.getTafProductCfg(product)
if not cfg:
raise Avn.AvnError('Cannot parse product definition file')
idents = cfg.get('sites', [])
for i in idents:
if not AvnParser.getTafSiteCfg(i):
raise Avn.AvnError('Cannot parse %s info file' % i)
for h in [0, 6, 12, 18]:
try:
AvnParser.getTafTemplate(i, h)
except IOError:
raise Avn.AvnError('Cannot read %s %02dZ template' % \
(i, h))
self.messagebar().message('userevent', 'Verify succeeded')
except IndexError:
self.messagebar().message('usererror', 'Select product to verify')
except Avn.AvnError, e:
self.messagebar().message('usererror', str(e))
def listIdents(self, product):
self.messagebar().resetmessages('systemerror')
cfg = AvnParser.getTafProductCfg(product)
if cfg:
idents = cfg.get('sites', [])
pil = cfg.get('workpil')
self.idents.setlist(idents)
if pil is None:
pil = Avn.TAFWorkPIL
self.pil.setvalue(pil)
else:
self.idents.clear()
self.pil.clear()
msg = 'Cannot read product %s' % product
self.messagebar().message('usererror', msg)
def listProducts(self):
self.messagebar().resetmessages('systemerror')
products = AvnParser.getTafProducts()
if products:
self.products.setlist(products)
self.products.selectitem(0)
self.products.invoke()
else:
self.products.clear()
self.messagebar().message('usererror', 'Empty product list')
##############################################################################
class TwbEditor(_Editor):
Key = 'twbs'
def __init__(self, parent, **kw):
_Editor.__init__(self, parent, **kw)
self.title(Avn.Name + ' TWEB Product Configuration')
def verify(self):
self.messagebar().resetmessages('systemerror')
try:
product = self.products.getcurselection()[0]
cfg = AvnParser.getTwbProductCfg(product)
if not cfg:
raise Avn.AvnError('Cannot parse product definition')
idents = cfg.get('sites', [])
for i in idents:
if not AvnParser.getTwbSiteCfg(i):
raise Avn.AvnError('Cannot parse %s info file' % i)
try:
AvnParser.getTwbTemplate(i)
except IOError:
raise Avn.AvnError('Cannot read %s template' % i)
self.messagebar().message('userevent', 'Verify succeeded')
except IndexError:
self.messagebar().message('usererror', 'Select product to verify')
except Avn.AvnError, e:
self.messagebar().message('usererror', str(e))
def listIdents(self, product):
self.messagebar().resetmessages('systemerror')
cfg = AvnParser.getTwbProductCfg(product)
if cfg:
idents = cfg.get('sites', [])
pil = cfg.get('workpil')
self.idents.setlist(idents)
if pil is None:
pil = Avn.TWBWorkPIL
self.pil.setvalue(pil)
else:
self.idents.clear()
self.pil.clear()
msg = 'Cannot read product %s' % product
self.messagebar().message('usererror', msg)
def listProducts(self):
self.messagebar().resetmessages('systemerror')
products = AvnParser.getTwbProducts()
if products:
self.products.setlist(products)
self.products.selectitem(0)
self.products.invoke()
else:
self.products.clear()
self.messagebar().message('usererror', 'Empty product list')