Files
sics/site_ansto/instrument/util/config_edit.py
2014-03-28 10:57:13 +11:00

237 lines
8.2 KiB
Python
Executable File

#!/usr/bin/env python
# vim: tabstop=8 softtabstop=2 shiftwidth=2 nocin si et ft=python
import os
import sys
global config
global verbose
global depth_list, line_list
config = None
verbose = False
depth_list = []
line_list = []
Radio_Groups = {}
def read_config_file(config_filename):
import ConfigParser
config = ConfigParser.SafeConfigParser()
config.read(config_filename)
return config
def reread_config_file(config_filename, cb_list):
config = read_config_file(config_filename)
for cb in cb_list:
lbl = cb.get_label()
if ":" in lbl:
lbl = lbl.split(":")[0]
state = False
if 'enabled' in config.options(lbl):
if config.get(lbl, 'enabled').lower() in ['1', 'yes', 'true']:
state = True
config.set(lbl, 'enabled', str(state))
cb.set_state(state, False)
return config
def write_config_file(config, config_filename):
for idx in range(8, 0, -1):
if os.path.exists(config_filename + "." + str(idx)):
os.rename(config_filename + "." + str(idx),
config_filename + "." + str(idx + 1))
if os.path.exists(config_filename):
os.rename(config_filename, config_filename + ".1")
with open(config_filename, "wb") as configfile:
for section in sorted(config.sections()):
configfile.write("[%s]\n" % section)
for option in sorted(config.options(section)):
configfile.write("%s = %s\n" % (option, config.get(section, option)))
configfile.write("\n")
#config.write(configfile)
def do_cascade(config, name, cb_list, label, new_state):
global depth_list
try:
if name in depth_list:
depth_list.append(name)
raise Exception("Recursion on " + str(depth_list))
depth_list.append(name)
if label in config.options(name):
cascade_list = config.get(name, label).lower().split(",")
for cb in cb_list:
lbl = cb.get_label().lower()
if ":" in lbl:
lbl = lbl.split(":")[0]
if lbl in cascade_list:
cb.set_state(new_state)
finally:
depth_list.pop()
def main(config_filename):
import urwid
global config
config = read_config_file(config_filename)
text_header = (
u"SICS Config Editor! SPACE/ENTER: Toggle, w/W/F12: Write+Exit\n"
u"UP/DOWN/PAGE UP/PAGE DOWN: scroll, r/R: Reread, q/Q/F8: Quit")
def checkbox_change(check_box, new_state, user_data):
global config, verbose, depth_list, line_list
if len(depth_list) == 0:
line_list = []
frame.footer = urwid.AttrWrap(urwid.Text(""), 'header')
config.set(user_data, 'enabled', str(new_state))
if verbose:
line = u"Checkbox: name=%s, new_state=%s, user_data=%s" % (
check_box.get_label(), str(new_state), str(user_data))
line_list.append(line + "\n")
frame.footer = urwid.AttrWrap(urwid.Text(line_list), 'header')
try:
order = ['offifoff', 'offifon', 'onifon', 'onifoff', 'cascade']
if 'order' in config.options(user_data):
order = config.get(user_data, 'order').lower().split(",")
for item in order:
if 'cascade' == item:
do_cascade(config, user_data, cb_list, 'cascade', new_state)
if (True == new_state) and 'onifon' == item:
do_cascade(config, user_data, cb_list, 'onifon', True)
if (True == new_state) and 'offifon' == item:
do_cascade(config, user_data, cb_list, 'offifon', False)
if (False == new_state) and 'onifoff' == item:
do_cascade(config, user_data, cb_list, 'onifoff', True)
if (False == new_state) and 'offifoff' == item:
do_cascade(config, user_data, cb_list, 'offifoff', False)
except Exception as prang:
line = "Exception: %s" % prang
line_list.append(line + "\n")
frame.footer = urwid.AttrWrap(urwid.Text(line_list), 'header')
text_cb_list = list(config.sections())
cb_map = {}
for txt in sorted(text_cb_list):
if 'group' in config.options(txt):
group = config.get(txt, 'group').lower()
else:
group = ""
if group not in cb_map:
cb_map[group] = []
cb_map[group].append(txt)
lb_list = []
cb_list = []
for key in sorted(cb_map.keys()):
if len(key) > 0:
lb_list.append(urwid.AttrWrap(urwid.Text("Group: %s" % key), 'bright'))
for txt in sorted(cb_map[key]):
state = False
if 'enabled' in config.options(txt):
if config.get(txt, 'enabled').lower() in ['1', 'yes', 'true']:
state = True
config.set(txt, 'enabled', str(state))
cb_text = txt
if 'group' in config.options(txt) or 'desc' in config.options(txt):
cb_text += ": ("
if 'group' in config.options(txt):
cb_text += config.get(txt, 'group').strip("\"") + ": "
if 'desc' in config.options(txt):
cb_text += config.get(txt, 'desc').strip("\"")
cb_text += ")"
if 'radio' in config.options(txt):
radio = config.get(txt, 'radio').strip("\"")
if radio not in Radio_Groups:
Radio_Groups[radio] = []
cb = urwid.AttrWrap(urwid.RadioButton(
Radio_Groups[radio],
cb_text,
state=state,
on_state_change=checkbox_change,
user_data=txt), 'buttn', 'buttnf')
else:
cb = urwid.AttrWrap(urwid.CheckBox(cb_text,
state=state,
on_state_change=checkbox_change,
user_data=txt), 'buttn', 'buttnf')
cb_list.append(cb)
lb_list.append(cb)
def fcc(focus):
frame.footer = urwid.AttrWrap(urwid.Text(
[u"Focus: " + str(focus)]), 'header')
blank = urwid.Divider()
listbox_content = [
blank,
urwid.Padding(urwid.GridFlow(
cb_list,
76, 1, 0, 'left'),
left=2, right=2, min_width=76),
blank,
blank
]
header = urwid.AttrWrap(urwid.Text(text_header), 'header')
sflw = urwid.SimpleListWalker(lb_list)
listbox = urwid.ListBox(sflw)
frame = urwid.Frame(urwid.AttrWrap(listbox, 'body'), header=header)
frame.footer = urwid.AttrWrap(urwid.Text(""), 'header')
palette = [
('body', 'black', 'light gray', 'standout'),
('reverse', 'light gray', 'black'),
('header', 'white', 'dark red', 'bold'),
('important', 'dark blue', 'light gray', ('standout', 'underline')),
('editfc', 'white', 'dark blue', 'bold'),
('editbx', 'light gray', 'dark blue'),
('editcp', 'black', 'light gray', 'standout'),
('bright', 'dark gray', 'light gray', ('bold', 'standout')),
('buttn', 'black', 'dark cyan'),
('buttnf', 'white', 'dark blue', 'bold'),
]
def unhandled(key):
global config
if key in ['w', 'W', 'f12']:
write_config_file(config, config_filename)
raise urwid.ExitMainLoop()
elif key in ['r', 'R']:
config = reread_config_file(config_filename, cb_list)
elif key in ['e', 'E', 'f4']:
f = sflw.get_focus()
frame.footer = urwid.AttrWrap(urwid.Text([u"EditE: " + str(dir(f[0]))]), 'header')
elif key in ['q', 'Q', 'f8']:
raise urwid.ExitMainLoop()
# elif key in ['b', 'B']:
# l = sflw[1].base_widget
# f = l.focus_cell
# b = l.cells.index(f)
# l.cells.insert(b + 1, urwid.AttrWrap(urwid.Edit(edit_text=u"Hello"), 'header'))
# l.set_focus(b + 1)
# frame.footer = urwid.AttrWrap(urwid.Text([u"EditB: " + str(b)]), 'header')
else:
if not key[0] == 'mouse release':
frame.footer = urwid.AttrWrap(urwid.Text([u"Press: " + str(key)]), 'header')
urwid.MainLoop(frame, palette, unhandled_input=unhandled).run()
if '__main__'==__name__:
global verbose
import argparse
# set default_ini to the name of the file to edit when no name is supplied
default_ini = "/usr/local/sics/sics_config.ini"
parser = argparse.ArgumentParser(description = """
Edit a configuration (*.ini) file using python urwid widget library.
Options can be enabled or disabled with mouse or spacebar.
The default configuration filename is %s.
""" % default_ini)
parser.add_argument("-v", "--verbose", action="store_true", help="give more infor in the footer")
parser.add_argument("path", nargs="?", default = default_ini, help="name of file to edit [%s]" % default_ini)
args = parser.parse_args()
default_ini = os.path.abspath(args.path)
if args.verbose:
verbose = True
main(default_ini)