mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			197 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #! /usr/local/bin/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()
 | 
