scripts/kvm/kvm_stat: Make tui function a class

The tui function itself had a few sub-functions and therefore
basically already was class-like. Making it an actual one with proper
methods improved readability.

The curses wrapper was dropped in favour of __entry/exit__ methods
that implement the same behaviour.

Also renamed single character variable name, so the name reflects the
content.

Signed-off-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Message-Id: <1452525484-32309-28-git-send-email-frankja@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Janosch Frank 2016-01-11 16:17:57 +01:00 committed by Paolo Bonzini
parent 9c0ab054ed
commit 8a2a33316c
1 changed files with 79 additions and 44 deletions

View File

@ -539,58 +539,92 @@ class Stats(object):
LABEL_WIDTH = 40 LABEL_WIDTH = 40
NUMBER_WIDTH = 10 NUMBER_WIDTH = 10
def tui(screen, stats): class Tui(object):
curses.use_default_colors() def __init__(self, stats):
self.stats = stats
self.screen = None
self.drilldown = False
self.fields_filter = self.stats.fields_filter
self.update_drilldown()
def __enter__(self):
"""Initialises curses for later use. Based on curses.wrapper
implementation from the Python standard library."""
self.screen = curses.initscr()
curses.noecho() curses.noecho()
drilldown = False curses.cbreak()
fields_filter = stats.fields_filter
def update_drilldown(): # The try/catch works around a minor bit of
if not fields_filter: # over-conscientiousness in the curses module, the error
if drilldown: # return from C start_color() is ignorable.
stats.fields_filter = None try:
curses.start_color()
except:
pass
curses.use_default_colors()
return self
def __exit__(self, *exception):
"""Resets the terminal to its normal state. Based on curses.wrappre
implementation from the Python standard library."""
if self.screen:
self.screen.keypad(0)
curses.echo()
curses.nocbreak()
curses.endwin()
def update_drilldown(self):
if not self.fields_filter:
if self.drilldown:
self.stats.fields_filter = None
else: else:
stats.fields_filter = r'^[^\(]*$' self.stats.fields_filter = r'^[^\(]*$'
update_drilldown()
def refresh(sleeptime): def refresh(self, sleeptime):
screen.erase() self.screen.erase()
screen.addstr(0, 0, 'kvm statistics') self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
screen.addstr(2, 1, 'Event') self.screen.addstr(2, 1, 'Event')
screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH - len('Total'), 'Total') self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 - len('Current'), 'Current') len('Total'), 'Total')
self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
len('Current'), 'Current')
row = 3 row = 3
s = stats.get() stats = self.stats.get()
def sortkey(x): def sortkey(x):
if s[x][1]: if stats[x][1]:
return (-s[x][1], -s[x][0]) return (-stats[x][1], -stats[x][0])
else: else:
return (0, -s[x][0]) return (0, -stats[x][0])
for key in sorted(s.keys(), key=sortkey): for key in sorted(stats.keys(), key=sortkey):
if row >= screen.getmaxyx()[0]:
if row >= self.screen.getmaxyx()[0]:
break break
values = s[key] values = stats[key]
if not values[0] and not values[1]: if not values[0] and not values[1]:
break break
col = 1 col = 1
screen.addstr(row, col, key) self.screen.addstr(row, col, key)
col += LABEL_WIDTH col += LABEL_WIDTH
screen.addstr(row, col, '%10d' % (values[0],)) self.screen.addstr(row, col, '%10d' % (values[0],))
col += NUMBER_WIDTH col += NUMBER_WIDTH
if values[1] is not None: if values[1] is not None:
screen.addstr(row, col, '%8d' % (values[1] / sleeptime,)) self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
row += 1 row += 1
screen.refresh() self.screen.refresh()
def show_stats(self):
sleeptime = 0.25 sleeptime = 0.25
while True: while True:
refresh(sleeptime) self.refresh(sleeptime)
curses.halfdelay(int(sleeptime * 10)) curses.halfdelay(int(sleeptime * 10))
sleeptime = 3 sleeptime = 3
try: try:
c = screen.getkey() char = self.screen.getkey()
if c == 'x': if char == 'x':
drilldown = not drilldown self.drilldown = not self.drilldown
update_drilldown() self.update_drilldown()
if c == 'q': if char == 'q':
break break
except KeyboardInterrupt: except KeyboardInterrupt:
break break
@ -698,7 +732,8 @@ def main():
if options.log: if options.log:
log(stats) log(stats)
elif not options.once: elif not options.once:
curses.wrapper(tui, stats) with Tui(stats) as tui:
tui.show_stats()
else: else:
batch(stats) batch(stats)