added first usable design of clish using urwid not raw curses; sexy stuff... ;)
This commit is contained in:
parent
95bffed954
commit
63210fe275
1 changed files with 152 additions and 12 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
cLish is the Curses based Linspector Interactive Shell.
|
clish is a urwid based Linspector Interactive Shell.
|
||||||
|
|
||||||
This will become a curses based commandline interface to Linspector.
|
Uses: http://excess.org/urwid/
|
||||||
|
|
||||||
Copyright (c) 2011-2013 by Johannes Findeisen and Rafael Timmerberg
|
Copyright (c) 2011-2013 by Johannes Findeisen and Rafael Timmerberg
|
||||||
|
|
||||||
|
|
@ -21,27 +21,167 @@ 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/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import curses
|
import urwid
|
||||||
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from linspector.frontends.frontend import Frontend
|
from linspector.frontends.frontend import Frontend
|
||||||
|
|
||||||
__version__ = "0.0.0"
|
__version__ = "0.1"
|
||||||
|
|
||||||
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):
|
||||||
|
def __init__(self):
|
||||||
|
urwid.Edit.__init__(self, '')
|
||||||
|
self.current_command = None
|
||||||
|
self.history = []
|
||||||
|
self.history_offset = 0
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.set_caption('')
|
||||||
|
self.set_edit_text('')
|
||||||
|
|
||||||
|
def keypress(self, size, key):
|
||||||
|
if key == 'backspace':
|
||||||
|
if self.edit_text == '':
|
||||||
|
self.set_caption('')
|
||||||
|
loop.draw_screen()
|
||||||
|
main_frame.set_focus('body')
|
||||||
|
else:
|
||||||
|
return urwid.Edit.keypress(self, size, key)
|
||||||
|
|
||||||
|
elif key == 'enter' and not self.get_edit_text() == '':
|
||||||
|
command = self.get_edit_text()
|
||||||
|
self.history.append(command)
|
||||||
|
self.history_offset = 0
|
||||||
|
command = command.split(' ')
|
||||||
|
|
||||||
|
if command[0] in ('log', 'l'):
|
||||||
|
if 2 <= len(command):
|
||||||
|
if command[1] in ('debug', 'info', 'error', 'warning'):
|
||||||
|
self.clear()
|
||||||
|
interface.set_log_level(command[1])
|
||||||
|
status_bar.set_text(" Set log level to: " + command[1])
|
||||||
|
main_frame.set_focus('body')
|
||||||
|
else:
|
||||||
|
status_bar.set_text(" Log level \"" + command[1] + "\" not available")
|
||||||
|
else:
|
||||||
|
status_bar.set_text(" Command argument missing. Args are: debug, info, error and warning")
|
||||||
|
|
||||||
|
elif command[0] in ('quit', 'q'):
|
||||||
|
self.clear()
|
||||||
|
status_bar.set_text(" Stopping Linspector...")
|
||||||
|
raise urwid.ExitMainLoop()
|
||||||
|
|
||||||
|
elif command[0] in ('version', 'v'):
|
||||||
|
self.clear()
|
||||||
|
status_bar.set_text(" Linspector " + str(interface.get_version()))
|
||||||
|
main_frame.set_focus('body')
|
||||||
|
|
||||||
|
else:
|
||||||
|
msg = 'Error: There is no command named "' + command[0] + '"'
|
||||||
|
status_bar.set_text(' ' + msg)
|
||||||
|
logger.debug(msg)
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif key in ('ctrl x', 'esc'):
|
||||||
|
main_frame.set_focus('body')
|
||||||
|
self.history_offset = 0
|
||||||
|
self.clear()
|
||||||
|
|
||||||
|
elif key in ('ctrl p', 'up'):
|
||||||
|
if self.get_edit_text() not in self.history:
|
||||||
|
self.current_command = self.get_edit_text()
|
||||||
|
try:
|
||||||
|
self.history_offset -= 1
|
||||||
|
command = self.history[self.history_offset]
|
||||||
|
self.set_edit_text(command)
|
||||||
|
self.set_edit_pos(len(command))
|
||||||
|
except IndexError:
|
||||||
|
self.history_offset += 1
|
||||||
|
|
||||||
|
elif key in ('ctrl n', 'down'):
|
||||||
|
if self.get_edit_text() not in self.history:
|
||||||
|
self.current_command = self.get_edit_text()
|
||||||
|
try:
|
||||||
|
self.history_offset += 1
|
||||||
|
if self.history_offset == 0:
|
||||||
|
command = self.current_command
|
||||||
|
elif self.history_offset < 0:
|
||||||
|
command = self.history[self.history_offset]
|
||||||
|
else:
|
||||||
|
raise IndexError
|
||||||
|
self.set_edit_text(command)
|
||||||
|
self.set_edit_pos(len(command))
|
||||||
|
except IndexError:
|
||||||
|
self.history_offset -= 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
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 ClishFrontend(Frontend):
|
class ClishFrontend(Frontend):
|
||||||
def __init__(self, linpsector_interface):
|
def __init__(self, linspector_interface):
|
||||||
super(ClishFrontend, self)
|
super(ClishFrontend, self)
|
||||||
|
|
||||||
self.screen = curses.initscr()
|
global job_list_box
|
||||||
|
global command_prompt
|
||||||
|
global header_bar
|
||||||
|
global status_bar
|
||||||
|
global main_frame
|
||||||
|
global loop
|
||||||
|
global interface
|
||||||
|
|
||||||
self.screen.border(0)
|
palette = [('top', 'white', 'dark red'),
|
||||||
self.screen.addstr(12, 25, "Linspector with curses... yeah!")
|
('status', 'white', 'dark blue'),
|
||||||
self.screen.refresh()
|
('prompt', 'white', 'black')]
|
||||||
self.screen.getch()
|
|
||||||
|
|
||||||
curses.endwin()
|
interface = linspector_interface
|
||||||
pass
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
main_frame = urwid.Frame(body=job_list_box, header=header, footer=footer)
|
||||||
|
|
||||||
|
loop = urwid.MainLoop(main_frame, palette)
|
||||||
|
loop.set_alarm_in(0, update)
|
||||||
|
loop.run()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue