added example tree structure to urlish and a TODO with a lot to think about

This commit is contained in:
Johannes Findeisen 2013-12-02 01:15:39 +01:00
commit 2109e0f81e

View file

@ -21,36 +21,41 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
"""
TODO:
General:
- think about if a simple scrollable list of jobs may be a lot easier to use
in combination with some tabs for job list, hostgroup jobs, host jobs etc.
i think this is a lot more flexible when reloading data. using the current
we have to rebuild the complete tree on reloading. or figure out how to
rebuild only selected nodes on reload. when using a tab/list based solution
we could even build a tab that on shows current errors, one for warnings etc.
these could we rebuild on access or on key stroke. these lists then only need
some action handlers for disabling/enabling or for showing detailed
information about the selected job. i think the tab/list approach is much
easier to handle then jumping like a monkey through a tree structure... ;)
For the tree based solution:
- remove all this global stuff and set needed stuff as arguments
- fix mouse handling; nice feature to select stuff using the mouse. currently
it raises an exception.
"""
import urwid import urwid
from logging import getLogger from logging import getLogger
from linspector.frontends.frontend import Frontend from linspector.frontends.frontend import Frontend
__version__ = "0.1.1" __version__ = "0.1.2"
logger = getLogger(__name__) logger = getLogger(__name__)
class JobWidget(urwid.FlowWidget):
def __init__(self):
pass
class JobListBox(urwid.WidgetWrap):
def __init__(self):
self.body = urwid.SimpleListWalker([])
self.listbox = urwid.ListBox(self.body)
urwid.WidgetWrap.__init__(self, self.listbox)
def keypress(self, size, key):
if key == ':':
main_frame.set_focus('footer')
command_prompt.set_caption(':')
else:
return self.listbox.keypress(size, key)
class CommandPrompt(urwid.Edit): class CommandPrompt(urwid.Edit):
def __init__(self): def __init__(self):
urwid.Edit.__init__(self, '') urwid.Edit.__init__(self, '')
@ -141,13 +146,91 @@ class CommandPrompt(urwid.Edit):
return urwid.Edit.keypress(self, size, key) return urwid.Edit.keypress(self, size, key)
def update(main_loop, user_data): class ExampleTreeWidget(urwid.TreeWidget):
thread_count = interface.get_thread_count() def __init__(self, node):
header_bar.set_text(" Linspector," self.__super.__init__(node)
" Jobs: " + str(interface.get_job_count()) + #self.expanded = False
" Threads: " + str(thread_count["Num Threads"]) + #self.update_expanded_icon()
"/" + str(thread_count["Max Threads"]))
main_loop.set_alarm_in(1, update) def get_display_text(self):
return self.get_node().get_value()['name']
class ExampleNode(urwid.TreeNode):
def load_widget(self):
return ExampleTreeWidget(self)
class ServiceParentNode(urwid.ParentNode):
def load_widget(self):
return ExampleTreeWidget(self)
def load_child_keys(self):
data = self.get_value()
return range(len(data['children']))
def load_child_node(self, key):
childdata = self.get_value()['children'][key]
childdepth = self.get_depth() + 1
if 'children' in childdata:
childclass = ServiceParentNode
else:
childclass = ExampleNode
return childclass(childdata, parent=self, key=key, depth=childdepth)
class HostParentNode(urwid.ParentNode):
def load_widget(self):
return ExampleTreeWidget(self)
def load_child_keys(self):
data = self.get_value()
return range(len(data['children']))
def load_child_node(self, key):
childdata = self.get_value()['children'][key]
childdepth = self.get_depth() + 1
if 'children' in childdata:
childclass = ServiceParentNode
else:
childclass = ExampleNode
return childclass(childdata, parent=self, key=key, depth=childdepth)
class HostgroupParentNode(urwid.ParentNode):
def load_widget(self):
return ExampleTreeWidget(self)
def load_child_keys(self):
data = self.get_value()
return range(len(data['children']))
def load_child_node(self, key):
childdata = self.get_value()['children'][key]
childdepth = self.get_depth() + 1
if 'children' in childdata:
childclass = HostParentNode
else:
childclass = ExampleNode
return childclass(childdata, parent=self, key=key, depth=childdepth)
class RootParentNode(urwid.ParentNode):
def load_widget(self):
return ExampleTreeWidget(self)
def load_child_keys(self):
data = self.get_value()
return range(len(data['children']))
def load_child_node(self, key):
childdata = self.get_value()['children'][key]
childdepth = self.get_depth() + 1
if 'children' in childdata:
childclass = HostgroupParentNode
else:
childclass = ExampleNode
return childclass(childdata, parent=self, key=key, depth=childdepth)
class UrlishFrontend(Frontend): class UrlishFrontend(Frontend):
@ -162,26 +245,98 @@ class UrlishFrontend(Frontend):
global loop global loop
global interface global interface
palette = [('top', 'white', 'dark red'), palette = [('body', 'white', 'black'),
('foot_bar', 'white', 'black'),
('top', 'white', 'dark red'),
('status', 'white', 'dark blue'), ('status', 'white', 'dark blue'),
('prompt', 'white', 'black')] ('prompt', 'white', 'black')]
foot_text = [('title', "Navigation:"), " ",
('key', "UP"), ",", ('key', "DOWN"), ",",
('key', "PAGE UP"), ",", ('key', "PAGE DOWN"),
" ",
('key', "+"), ",",
('key', "-"), " ",
('key', "LEFT"), " ",
('key', "HOME"), " ",
('key', "END")]
interface = linspector_interface interface = linspector_interface
top_node = RootParentNode(get_example_tree())
job_list_box = urwid.TreeListBox(urwid.TreeWalker(top_node))
job_list_box.offset_rows = 1
header_message = ' Linspector (' + str(linspector_interface.get_version()) + ')' header_message = ' Linspector (' + str(linspector_interface.get_version()) + ')'
header_bar = urwid.Text(header_message, align='left') header_bar = urwid.Text(header_message, align='left')
header = urwid.Pile([urwid.AttrMap(header_bar, 'top')]) header = urwid.Pile([urwid.AttrMap(header_bar, 'top')])
command_prompt = CommandPrompt() command_prompt = CommandPrompt()
foot_bar = urwid.Text(foot_text, align='left')
welcome_message = ' Type ":h <Enter>" for help, ":q <Enter>" to quit' welcome_message = ' Type ":h <Enter>" for help, ":q <Enter>" to quit'
status_bar = urwid.Text(welcome_message, align='left') status_bar = urwid.Text(welcome_message, align='left')
footer = urwid.Pile([urwid.AttrMap(status_bar, 'status'), urwid.AttrMap(command_prompt, 'prompt')]) footer = urwid.Pile([urwid.AttrMap(foot_bar, 'foot_bar'),
urwid.AttrMap(status_bar, 'status'),
job_list_box = JobListBox() urwid.AttrMap(command_prompt, 'prompt')])
main_frame = urwid.Frame(body=job_list_box, header=header, footer=footer) main_frame = urwid.Frame(body=job_list_box, header=header, footer=footer)
loop = urwid.MainLoop(main_frame, palette) loop = urwid.MainLoop(main_frame, palette, unhandled_input=self.unhandled_input, handle_mouse=False)
loop.set_alarm_in(0, update) loop.set_alarm_in(0, update)
loop.run() loop.run()
@staticmethod
def unhandled_input(key):
if key in (':'):
main_frame.set_focus('footer')
command_prompt.set_caption(':')
elif key in ('c'):
#collapse all children of current node
pass
elif key in ('C'):
#collapse all nodes
pass
elif key in ('d'):
#disable all jobs for current node
pass
elif key in ('e'):
#enable all jobs for current node
pass
elif key in ('r'):
#reload child data of current node
pass
elif key in ('R'):
#reload child data of all nodes
pass
elif key in ('x'):
#expand all children of current node
pass
elif key in ('X'):
#expand all nodes
pass
def update(main_loop, user_data):
thread_count = interface.get_thread_count()
header_bar.set_text(" Linspector,"
" Jobs: " + str(interface.get_job_count()) +
" Threads: " + str(thread_count["Num Threads"]) +
"/" + str(thread_count["Max Threads"]))
main_loop.set_alarm_in(1, update)
def get_example_tree():
retval = {"name": "ROOT", "children": []}
for i in range(10):
retval['children'].append({"name": "HOSTGROUP " + str(i)})
retval['children'][i]['children'] = []
for j in range(5):
retval['children'][i]['children'].append({"name": "HOST " + str(i) + "." + str(j)})
retval['children'][i]['children'][j]['children'] = []
for k in range(3):
retval['children'][i]['children'][j]['children'].append({"name": "SERVICE " + str(i) +
"." + str(j) +
"." + str(k)})
return retval