Created the UnixWatchCommandOutput file.
TODO: Add configurable time support.
Possibly add the rest of watch's options as well
This commit is contained in:
parent
ff261bb2e6
commit
d20bfbd2f0
1 changed files with 157 additions and 0 deletions
157
pwatch.py
Executable file
157
pwatch.py
Executable file
|
|
@ -0,0 +1,157 @@
|
|||
#!/usr/bin/python
|
||||
"""
|
||||
Based on the code that
|
||||
Lyle Scott, III wrote.
|
||||
lyle@digitalfoo.net
|
||||
|
||||
Watches the output of a command in a
|
||||
scrollable curses window.
|
||||
"""
|
||||
import curses
|
||||
import sys
|
||||
import random
|
||||
import locale
|
||||
import threading
|
||||
import subprocess
|
||||
import time
|
||||
locale.setlocale(locale.LC_ALL,"")
|
||||
|
||||
class UnixWatchCommand:
|
||||
DOWN = 1
|
||||
UP = -1
|
||||
SPACE_KEY = 32
|
||||
ESC_KEY = 27
|
||||
|
||||
PREFIX_SELECTED = '-'
|
||||
PREFIX_DESELECTED = ''
|
||||
|
||||
outputLines = []
|
||||
screen = None
|
||||
|
||||
def __init__(self, command):
|
||||
self.stop = threading.Event()
|
||||
self.timer=threading.Thread(target=self.display)
|
||||
self.command = ' '.join(command)
|
||||
self.screen = curses.initscr()
|
||||
curses.noecho()
|
||||
curses.cbreak()
|
||||
self.screen.keypad(1)
|
||||
self.screen.border(0)
|
||||
self.topLineNum = 0
|
||||
self.highlightLineNum = 0
|
||||
self.markedLineNums = []
|
||||
self.getOutputLines()
|
||||
self.timer.start()
|
||||
self.run()
|
||||
self.timer.join()
|
||||
|
||||
def display(self):
|
||||
while not self.stop.is_set():
|
||||
try:
|
||||
self.displayScreen()
|
||||
time.sleep(1)
|
||||
except:
|
||||
break
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
try:
|
||||
self.displayScreen()
|
||||
# get user command
|
||||
c = self.screen.getch()
|
||||
if c == curses.KEY_UP:
|
||||
self.updown(self.UP)
|
||||
elif c == curses.KEY_DOWN:
|
||||
self.updown(self.DOWN)
|
||||
elif c == self.SPACE_KEY:
|
||||
self.markLine()
|
||||
elif c == self.ESC_KEY:
|
||||
self.stop.set()
|
||||
break
|
||||
except:
|
||||
self.stop.set()
|
||||
break
|
||||
|
||||
|
||||
def markLine(self):
|
||||
linenum = self.topLineNum + self.highlightLineNum
|
||||
if linenum in self.markedLineNums:
|
||||
self.markedLineNums.remove(linenum)
|
||||
else:
|
||||
self.markedLineNums.append(linenum)
|
||||
|
||||
def check_output(self, command):
|
||||
|
||||
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True)
|
||||
output,stderr = process.communicate()
|
||||
retcode = process.poll()
|
||||
|
||||
if retcode:
|
||||
raise subprocess.CalledProcessError(retcode, command,
|
||||
output=output[0])
|
||||
return output.splitlines()
|
||||
|
||||
def getOutputLines(self):
|
||||
self.outputLines = self.check_output(self.command)
|
||||
self.nOutputLines = len(self.outputLines)
|
||||
|
||||
def displayScreen(self):
|
||||
# clear screen
|
||||
self.screen.clear()
|
||||
self.getOutputLines()
|
||||
# now paint the rows
|
||||
top = self.topLineNum
|
||||
bottom = self.topLineNum+curses.LINES
|
||||
for (index,line,) in enumerate(self.outputLines[top:bottom]):
|
||||
linenum = self.topLineNum + index
|
||||
if linenum in self.markedLineNums:
|
||||
prefix = self.PREFIX_SELECTED
|
||||
else:
|
||||
prefix = self.PREFIX_DESELECTED
|
||||
|
||||
#line = '%s %s' % (prefix, line,)
|
||||
# highlight current line
|
||||
if index != self.highlightLineNum:
|
||||
self.screen.addstr(index, 0, line)
|
||||
else:
|
||||
self.screen.addstr(index, 0, line, curses.A_BOLD)
|
||||
self.screen.refresh()
|
||||
|
||||
# move highlight up/down one line
|
||||
def updown(self, increment):
|
||||
nextLineNum = self.highlightLineNum + increment
|
||||
|
||||
# paging
|
||||
if increment == self.UP and self.highlightLineNum == 0\
|
||||
and self.topLineNum != 0:
|
||||
self.topLineNum += self.UP
|
||||
return
|
||||
elif increment == self.DOWN and nextLineNum == curses.LINES\
|
||||
and (self.topLineNum+curses.LINES) != self.nOutputLines:
|
||||
self.topLineNum += self.DOWN
|
||||
return
|
||||
|
||||
# scroll highlight line
|
||||
if increment == self.UP and (self.topLineNum != 0 or\
|
||||
self.highlightLineNum != 0):
|
||||
self.highlightLineNum = nextLineNum
|
||||
elif increment == self.DOWN and\
|
||||
(self.topLineNum+self.highlightLineNum+1) != self.nOutputLines\
|
||||
and self.highlightLineNum != curses.LINES:
|
||||
self.highlightLineNum = nextLineNum
|
||||
|
||||
def restoreScreen(self):
|
||||
curses.initscr()
|
||||
curses.nocbreak()
|
||||
curses.echo()
|
||||
curses.endwin()
|
||||
|
||||
# catch any weird termination situations
|
||||
def __del__(self):
|
||||
self.restoreScreen()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ih = UnixWatchCommand(sys.argv[1:])
|
||||
Loading…
Add table
Add a link
Reference in a new issue