home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Demo / stdwin / lpwin.py < prev    next >
Text File  |  1996-11-27  |  5KB  |  199 lines

  1. #! /usr/bin/env python
  2.  
  3. # Watch line printer queues (only works with BSD 4.3 lpq).
  4. #
  5. # This brings up a window containing one line per printer argument.
  6. #
  7. # Each line gives a small summary of the printer's status and queue.
  8. # The status tries to give as much relevant information as possible,
  9. # and gives extra info if you have jobs in the queue.
  10. #
  11. # The line's background color gives a hint at the status: navajo white
  12. # for idle, green if your job is now printing, yellow/orange for
  13. # small/large queue, red for errors.
  14. #
  15. # To reduce the duration of the unresponsive time while it is waiting
  16. # for an lpq subprocess to finish, it polls one printer every
  17. # delay/len(printers) seconds.  A tiny dot indicates the last printer
  18. # updated.  Hit the mouse button in the window to update the next one.
  19. #
  20. # To do:
  21. # - add an argument to override the default delay
  22. # - add arguments to override the default colors
  23. # - better heuristic for small/large queue (and more colors!)
  24. # - mouse clicks should update the printer clicked in
  25. # - better visual appearance, e.g., boxes around the lines?
  26.  
  27. import posix
  28. import sys
  29. import time
  30. import string
  31.  
  32. import stdwin
  33. from stdwinevents import *
  34. import mainloop
  35.  
  36. # Default parameters
  37. DEF_PRINTER = 'oce' # This is CWI specific!
  38. DEF_DELAY = 10
  39.  
  40. # Color assignments
  41. c_unknown = stdwin.fetchcolor('white')
  42. c_idle = stdwin.fetchcolor('navajo white')
  43. c_ontop = stdwin.fetchcolor('green')
  44. c_smallqueue = stdwin.fetchcolor('yellow')
  45. c_bigqueue = stdwin.fetchcolor('orange')
  46. c_error = stdwin.fetchcolor('red')
  47.  
  48. def main():
  49.     delay = DEF_DELAY
  50.     #
  51.     try:
  52.         thisuser = posix.environ['LOGNAME']
  53.     except:
  54.         thisuser = posix.environ['USER']
  55.     #
  56.     printers = sys.argv[1:]
  57.     if printers:
  58.         # Strip '-P' from printer names just in case
  59.         # the user specified it...
  60.         for i in range(len(printers)):
  61.             if printers[i][:2] == '-P':
  62.                 printers[i] = printers[i][2:]
  63.     else:
  64.         if posix.environ.has_key('PRINTER'):
  65.             printers = [posix.environ['PRINTER']]
  66.         else:
  67.             printers = [DEF_PRINTER]
  68.     #
  69.     width = stdwin.textwidth('in')*20
  70.     height = len(printers) * stdwin.lineheight() + 5
  71.     stdwin.setdefwinsize(width, height)
  72.     stdwin.setdefscrollbars(0, 0)
  73.     #
  74.     win = stdwin.open('lpwin')
  75.     #
  76.     win.printers = printers
  77.     win.colors = [c_unknown] * len(printers)
  78.     win.texts = printers[:]
  79.     win.next = 0
  80.     win.delay = DEF_DELAY
  81.     win.thisuser = thisuser
  82.     win.dispatch = lpdispatch
  83.     #
  84.     win.settimer(1)
  85.     #
  86.     mainloop.register(win)
  87.     mainloop.mainloop()
  88.  
  89. def lpdispatch(event):
  90.     type, win, detail = event
  91.     if type == WE_CLOSE or type == WE_CHAR and detail in ('q', 'Q'):
  92.         mainloop.unregister(win)
  93.     elif type == WE_DRAW:
  94.         drawproc(win)
  95.     elif type == WE_TIMER:
  96.         update(win)
  97.         win.change((0,0), (10000, 10000))
  98.     elif type == WE_MOUSE_UP:
  99.         win.settimer(1)
  100.  
  101. def drawproc(win):
  102.     d = win.begindrawing()
  103.     offset = d.textwidth('.')
  104.     h, v = 0, 0
  105.     for i in range(len(win.printers)):
  106.         text = win.texts[i]
  107.         color = win.colors[i]
  108.         d.setbgcolor(color)
  109.         d.erase((h, v), (h+10000, v+d.lineheight()))
  110.         if (i+1) % len(win.printers) == win.next and color <> c_unknown:
  111.             d.text((h, v), '.')
  112.         d.text((h+offset, v), text)
  113.         v = v + d.lineheight()
  114.  
  115. def update(win):
  116.     i = win.next
  117.     win.next = (i+1) % len(win.printers)
  118.     win.texts[i], win.colors[i] = makestatus(win.printers[i], win.thisuser)
  119.     win.settimer(int(win.delay * 10.0 / len(win.printers)))
  120.  
  121. def makestatus(name, thisuser):
  122.     pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r')
  123.     lines = []
  124.     users = {}
  125.     aheadbytes = 0
  126.     aheadjobs = 0
  127.     userseen = 0
  128.     totalbytes = 0
  129.     totaljobs = 0
  130.     color = c_unknown
  131.     while 1:
  132.         line = pipe.readline()
  133.         if not line: break
  134.         fields = string.split(line)
  135.         n = len(fields)
  136.         if len(fields) >= 6 and fields[n-1] == 'bytes':
  137.             rank = fields[0]
  138.             user = fields[1]
  139.             job = fields[2]
  140.             files = fields[3:-2]
  141.             bytes = eval(fields[n-2])
  142.             if user == thisuser:
  143.                 userseen = 1
  144.                 if aheadjobs == 0:
  145.                     color = c_ontop
  146.             elif not userseen:
  147.                 aheadbytes = aheadbytes + bytes
  148.                 aheadjobs = aheadjobs + 1
  149.             totalbytes = totalbytes + bytes
  150.             totaljobs = totaljobs + 1
  151.             if color == c_unknown:
  152.                 color = c_smallqueue
  153.             elif color == c_smallqueue:
  154.                 color = c_bigqueue
  155.             if users.has_key(user):
  156.                 ujobs, ubytes = users[user]
  157.             else:
  158.                 ujobs, ubytes = 0, 0
  159.             ujobs = ujobs + 1
  160.             ubytes = ubytes + bytes
  161.             users[user] = ujobs, ubytes
  162.         else:
  163.             if fields and fields[0] <> 'Rank':
  164.                 line = string.strip(line)
  165.                 if line == 'no entries':
  166.                     line = name + ': idle'
  167.                     if color == c_unknown:
  168.                         color = c_idle
  169.                 elif line[-22:] == ' is ready and printing':
  170.                     line = line[:-22]
  171.                 else:
  172.                     line = name + ': ' + line
  173.                     color = c_error
  174.                 lines.append(line)
  175.     #
  176.     if totaljobs:
  177.         line = `(totalbytes+1023)/1024` + ' K'
  178.         if totaljobs <> len(users):
  179.             line = line + ' (' + `totaljobs` + ' jobs)'
  180.         if len(users) == 1:
  181.             line = line + ' for ' + users.keys()[0]
  182.         else:
  183.             line = line + ' for ' + `len(users)` + ' users'
  184.             if userseen:
  185.                 if aheadjobs == 0:
  186.                   line =  line + ' (' + thisuser + ' first)'
  187.                 else:
  188.                   line = line + ' (' + `(aheadbytes+1023)/1024`
  189.                   line = line + ' K before ' + thisuser + ')'
  190.         lines.append(line)
  191.     #
  192.     sts = pipe.close()
  193.     if sts:
  194.         lines.append('lpq exit status ' + `sts`)
  195.         color = c_error
  196.     return string.joinfields(lines, ': '), color
  197.  
  198. main()
  199.