diff options
Diffstat (limited to 'Demo/stdwin/lpwin.py')
-rwxr-xr-x | Demo/stdwin/lpwin.py | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/Demo/stdwin/lpwin.py b/Demo/stdwin/lpwin.py new file mode 100755 index 0000000..07a2bf7 --- /dev/null +++ b/Demo/stdwin/lpwin.py @@ -0,0 +1,197 @@ +#! /usr/local/python + +# Watch line printer queues (only works with BSD 4.3 lpq). +# +# This brings up a window containing one line per printer argument. +# +# Each line gives a small summary of the printer's status and queue. +# The status tries to give as much relevant information as possible, +# and gives extra info if you have jobs in the queue. +# +# The line's background color gives a hint at the status: navajo white +# for idle, green if your job is now printing, yellow/orange for +# small/large queue, red for errors. +# +# To reduce the duration of the unresponsive time while it is waiting +# for an lpq subprocess to finish, it polls one printer every +# delay/len(printers) seconds. A tiny dot indicates the last printer +# updated. Hit the mouse button in the window to update the next one. +# +# To do: +# - add an argument to override the default delay +# - add arguments to override the default colors +# - better heuristic for small/large queue (and more colors!) +# - mouse clicks should update the printer clicked in +# - better visual appearance, e.g., boxes around the lines? + +import posix +import sys +import time +import string + +import stdwin +from stdwinevents import * +import mainloop + +# Default parameters +DEF_PRINTER = 'oce' # This is CWI specific! +DEF_DELAY = 10 + +# Color assignments +c_unknown = stdwin.fetchcolor('white') +c_idle = stdwin.fetchcolor('navajo white') +c_ontop = stdwin.fetchcolor('green') +c_smallqueue = stdwin.fetchcolor('yellow') +c_bigqueue = stdwin.fetchcolor('orange') +c_error = stdwin.fetchcolor('red') + +def main(): + delay = DEF_DELAY + # + try: + thisuser = posix.environ['LOGNAME'] + except: + thisuser = posix.environ['USER'] + # + printers = sys.argv[1:] + if printers: + # Strip '-P' from printer names just in case + # the user specified it... + for i in range(len(printers)): + if printers[i][:2] == '-P': + printers[i] = printers[i][2:] + else: + if posix.environ.has_key('PRINTER'): + printers = [posix.environ['PRINTER']] + else: + printers = [DEF_PRINTER] + # + width = stdwin.textwidth('in')*20 + height = len(printers) * stdwin.lineheight() + 5 + stdwin.setdefwinsize(width, height) + stdwin.setdefscrollbars(0, 0) + # + win = stdwin.open('lpwin') + # + win.printers = printers + win.colors = [c_unknown] * len(printers) + win.texts = printers[:] + win.next = 0 + win.delay = DEF_DELAY + win.thisuser = thisuser + win.dispatch = lpdispatch + # + win.settimer(1) + # + mainloop.register(win) + mainloop.mainloop() + +def lpdispatch(type, win, detail): + if type == WE_CLOSE or type == WE_CHAR and detail in ('q', 'Q'): + mainloop.unregister(win) + elif type == WE_DRAW: + drawproc(win) + elif type == WE_TIMER: + update(win) + win.change((0,0), (10000, 10000)) + elif type == WE_MOUSE_UP: + win.settimer(1) + +def drawproc(win): + d = win.begindrawing() + offset = d.textwidth('.') + h, v = 0, 0 + for i in range(len(win.printers)): + text = win.texts[i] + color = win.colors[i] + d.setbgcolor(color) + d.erase((h, v), (h+10000, v+d.lineheight())) + if (i+1) % len(win.printers) == win.next and color <> c_unknown: + d.text((h, v), '.') + d.text((h+offset, v), text) + v = v + d.lineheight() + +def update(win): + i = win.next + win.next = (i+1) % len(win.printers) + win.texts[i], win.colors[i] = makestatus(win.printers[i], win.thisuser) + win.settimer(int(win.delay * 10.0 / len(win.printers))) + +def makestatus(name, thisuser): + pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r') + lines = [] + users = {} + aheadbytes = 0 + aheadjobs = 0 + userseen = 0 + totalbytes = 0 + totaljobs = 0 + color = c_unknown + while 1: + line = pipe.readline() + if not line: break + fields = string.split(line) + n = len(fields) + if len(fields) >= 6 and fields[n-1] == 'bytes': + rank = fields[0] + user = fields[1] + job = fields[2] + files = fields[3:-2] + bytes = eval(fields[n-2]) + if user == thisuser: + userseen = 1 + if aheadjobs == 0: + color = c_ontop + elif not userseen: + aheadbytes = aheadbytes + bytes + aheadjobs = aheadjobs + 1 + totalbytes = totalbytes + bytes + totaljobs = totaljobs + 1 + if color == c_unknown: + color = c_smallqueue + elif color == c_smallqueue: + color = c_bigqueue + if users.has_key(user): + ujobs, ubytes = users[user] + else: + ujobs, ubytes = 0, 0 + ujobs = ujobs + 1 + ubytes = ubytes + bytes + users[user] = ujobs, ubytes + else: + if fields and fields[0] <> 'Rank': + line = string.strip(line) + if line == 'no entries': + line = name + ': idle' + if color == c_unknown: + color = c_idle + elif line[-22:] == ' is ready and printing': + line = line[:-22] + else: + line = name + ': ' + line + color = c_error + lines.append(line) + # + if totaljobs: + line = `(totalbytes+1023)/1024` + ' K' + if totaljobs <> len(users): + line = line + ' (' + `totaljobs` + ' jobs)' + if len(users) == 1: + line = line + ' for ' + users.keys()[0] + else: + line = line + ' for ' + `len(users)` + ' users' + if userseen: + if aheadjobs == 0: + line = line + ' (' + thisuser + ' first)' + else: + line = line + ' (' + `(aheadbytes+1023)/1024` + line = line + ' K before ' + thisuser + ')' + lines.append(line) + # + sts = pipe.close() + if sts: + lines.append('lpq exit status ' + `sts`) + color = c_error + return string.joinfields(lines, ': '), color + +main() |