fuel-menu/fuelmenu/fuelmenu.py

248 lines
8.6 KiB
Python
Executable File

import logging
import operator
import os
import subprocess
import sys
import urwid
import urwid.raw_display
import urwid.web_display
# set up logging
#logging.basicConfig(filename='./fuelmenu.log')
#logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(filename='./fuelmenu.log', level=logging.DEBUG)
log = logging.getLogger('fuelmenu.loader')
class Loader:
def __init__(self, parent):
self.modlist = []
self.choices = []
self.child = None
self.children = []
self.childpage = None
self.parent = parent
def load_modules(self, module_dir):
if not module_dir in sys.path:
sys.path.append(module_dir)
modules = [os.path.splitext(f)[0] for f in os.listdir(module_dir)
if f.endswith('.py')]
for module in modules:
log.info('loading module %s' % module)
try:
imported = __import__(module)
pass
#imported = process(module)
except ImportError as e:
log.error('module could not be imported: %s' % e)
continue
clsobj = getattr(imported, module, None)
modobj = clsobj(self.parent)
# add the module to the list
if modobj.visible:
self.modlist.append(modobj)
# sort modules
self.modlist.sort(key=operator.attrgetter('priority'))
for module in self.modlist:
self.choices.append(module.name)
return (self.modlist, self.choices)
version = "3.2"
class FuelSetup():
def __init__(self):
self.footer = None
self.frame = None
self.screen = None
self.defaultsettingsfile = "%s/settings.yaml" \
% (os.path.dirname(__file__))
self.settingsfile = "%s/newsettings.yaml" \
% (os.path.dirname(__file__))
self.managediface = "eth0"
self.main()
self.choices = []
def menu(self, title, choices):
body = [urwid.Text(title), urwid.Divider()]
for c in choices:
button = urwid.Button(c)
urwid.connect_signal(button, 'click', self.menu_chosen, c)
body.append(urwid.AttrMap(button, None, focus_map='reversed'))
return urwid.ListBox(urwid.SimpleListWalker(body))
#return urwid.ListBox(urwid.SimpleFocusListWalker(body))
def menu_chosen(self, button, choice):
size = self.screen.get_cols_rows()
self.screen.draw_screen(size, self.frame.render(size))
for item in self.menuitems.body.contents:
try:
if item.original_widget.get_label() == choice:
item.set_attr_map({None: 'header'})
else:
item.set_attr_map({None: None})
except Exception, e:
log.info("%s" % item)
log.error("%s" % e)
self.setChildScreen(name=choice)
def setChildScreen(self, name=None):
if name is None:
child = self.children[0]
else:
child = self.children[int(self.choices.index(name))]
if not child.screen:
child.screen = child.screenUI()
self.childpage = child.screen
self.childfill = urwid.Filler(self.childpage, 'top', 40)
self.childbox = urwid.BoxAdapter(self.childfill, 40)
self.cols = urwid.Columns([
('fixed', 20, urwid.Pile([
urwid.AttrMap(self.menubox, 'bright'),
urwid.Divider(" ")])),
('weight', 3, urwid.Pile([
urwid.Divider(" "),
self.childbox,
urwid.Divider(" ")]))
], 1)
child.refresh()
self.listwalker[:] = [self.cols]
def refreshScreen(self):
size = self.screen.get_cols_rows()
self.screen.draw_screen(size, self.frame.render(size))
def refreshChildScreen(self, name):
child = self.children[int(self.choices.index(name))]
#Refresh child listwalker
child.listwalker[:] = child.listbox_content
#reassign childpage top level objects
self.childpage = urwid.ListBox(child.listwalker)
self.childfill = urwid.Filler(self.childpage, 'middle', 22)
self.childbox = urwid.BoxAdapter(self.childfill, 22)
self.cols = urwid.Columns([
('fixed', 20, urwid.Pile([
urwid.AttrMap(self.menubox, 'bright'),
urwid.Divider(" ")])),
('weight', 3, urwid.Pile([
urwid.Divider(" "),
self.childbox,
urwid.Divider(" ")]))
], 1)
#Refresh top level listwalker
#self.listwalker[:] = [self.cols]
def main(self):
#Disable kernel print messages. They make our UI ugly
noout = open('/dev/null', 'w')
retcode = subprocess.call(["sysctl", "-w", "kernel.printk=4 1 1 7"],
stdout=noout,
stderr=noout)
text_header = (u"Fuel %s setup "
u"Use Up/Down/Left/Right to navigate. F8 exits."
% version)
text_footer = (u"Status messages go here.")
blank = urwid.Divider()
#Top and bottom lines of frame
self.header = urwid.AttrWrap(urwid.Text(text_header), 'header')
self.footer = urwid.AttrWrap(urwid.Text(text_footer), 'footer')
#Prepare submodules
loader = Loader(self)
moduledir = "%s/modules" % (os.path.dirname(__file__))
self.children, self.choices = loader.load_modules(module_dir=moduledir)
if len(self.children) == 0:
import sys
sys.exit(1)
self.menuitems = self.menu(u'Menu', self.choices)
menufill = urwid.Filler(self.menuitems, 'top', 40)
self.menubox = urwid.BoxAdapter(menufill, 40)
child = self.children[0]
self.childpage = child.screenUI()
self.childfill = urwid.Filler(self.childpage, 'top', 22)
self.childbox = urwid.BoxAdapter(self.childfill, 22)
self.cols = urwid.Columns([
('fixed', 20, urwid.Pile([
urwid.AttrMap(self.menubox, 'bright'),
urwid.Divider(" ")])),
('weight', 3, urwid.Pile([
urwid.Divider(" "),
self.childbox,
urwid.Divider(" ")]))
], 1)
self.listwalker = urwid.SimpleListWalker([self.cols])
#self.listwalker = urwid.TreeWalker([self.cols])
self.listbox = urwid.ListBox(self.listwalker)
#listbox = urwid.ListBox(urwid.SimpleListWalker(listbox_content))
self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'),
header=self.header, footer=self.footer)
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'),
('light gray', 'white', 'light gray', 'bold'),
('red', 'dark red', 'light gray', 'bold'),
('black', 'black', 'black', 'bold'),
]
# use appropriate Screen class
if urwid.web_display.is_web_request():
self.screen = urwid.web_display.Screen()
else:
self.screen = urwid.raw_display.Screen()
def unhandled(key):
if key == 'f8':
raise urwid.ExitMainLoop()
self.mainloop = urwid.MainLoop(self.frame, palette, self.screen,
unhandled_input=unhandled)
self.mainloop.run()
def exit_program(self, button):
#return kernel logging to normal
noout = open('/dev/null', 'w')
retcode = subprocess.call(["sysctl", "-w", "kernel.printk=7 4 1 7"],
stdout=noout,
stderr=noout)
raise urwid.ExitMainLoop()
def setup():
urwid.web_display.set_preferences("Fuel Setup")
# try to handle short web requests quickly
if urwid.web_display.handle_short_request():
return
fm = FuelSetup()
if '__main__' == __name__ or urwid.web_display.is_web_request():
if urwid.VERSION < (1, 1, 0):
print "This program requires urwid 1.1.0 or greater."
setup()