added example tree structure to urlish and a TODO with a lot to think about
This commit is contained in:
parent
c3cfee6bed
commit
2109e0f81e
1 changed files with 187 additions and 32 deletions
|
|
@ -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/>.
|
||||
"""
|
||||
|
||||
"""
|
||||
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
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.frontends.frontend import Frontend
|
||||
|
||||
__version__ = "0.1.1"
|
||||
__version__ = "0.1.2"
|
||||
|
||||
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):
|
||||
def __init__(self):
|
||||
urwid.Edit.__init__(self, '')
|
||||
|
|
@ -141,13 +146,91 @@ class CommandPrompt(urwid.Edit):
|
|||
return urwid.Edit.keypress(self, size, key)
|
||||
|
||||
|
||||
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)
|
||||
class ExampleTreeWidget(urwid.TreeWidget):
|
||||
def __init__(self, node):
|
||||
self.__super.__init__(node)
|
||||
#self.expanded = False
|
||||
#self.update_expanded_icon()
|
||||
|
||||
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):
|
||||
|
|
@ -162,26 +245,98 @@ class UrlishFrontend(Frontend):
|
|||
global loop
|
||||
global interface
|
||||
|
||||
palette = [('top', 'white', 'dark red'),
|
||||
palette = [('body', 'white', 'black'),
|
||||
('foot_bar', 'white', 'black'),
|
||||
('top', 'white', 'dark red'),
|
||||
('status', 'white', 'dark blue'),
|
||||
('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
|
||||
|
||||
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_bar = urwid.Text(header_message, align='left')
|
||||
header = urwid.Pile([urwid.AttrMap(header_bar, 'top')])
|
||||
|
||||
command_prompt = CommandPrompt()
|
||||
|
||||
foot_bar = urwid.Text(foot_text, align='left')
|
||||
|
||||
welcome_message = ' Type ":h <Enter>" for help, ":q <Enter>" to quit'
|
||||
status_bar = urwid.Text(welcome_message, align='left')
|
||||
footer = urwid.Pile([urwid.AttrMap(status_bar, 'status'), urwid.AttrMap(command_prompt, 'prompt')])
|
||||
|
||||
job_list_box = JobListBox()
|
||||
footer = urwid.Pile([urwid.AttrMap(foot_bar, 'foot_bar'),
|
||||
urwid.AttrMap(status_bar, 'status'),
|
||||
urwid.AttrMap(command_prompt, 'prompt')])
|
||||
|
||||
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.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
|
||||
Loading…
Add table
Add a link
Reference in a new issue