#! /usr/bin/env 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(event):
	type, win, detail = event
	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()
