Changeset 1746
- Timestamp:
- 09/27/04 21:56:27 (20 years ago)
- Location:
- pykota/trunk
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/conf/pykota.conf.sample
r1729 r1746 213 213 # e.g. myprinter.example.com 214 214 # 215 # Example : 215 # Recommended values : 216 # 217 # accounter: hardware(snmp) 218 # 219 # Extracts the printer's internal page counter via SNMP. 220 # 221 # Or : 222 # 223 # accounter: hardware(pjl) 224 # 225 # Extracts the printer's internal page counter via PJL queries over port tcp/9100. 226 # 227 # Other Examples : 216 228 # 217 229 # accounter: hardware(/usr/bin/snmpget -v1 -c public -Ov %(printer)s mib-2.43.10.2.1.4.1.1 | cut -f 2,2 -d " ") … … 221 233 # accounter: hardware(/usr/bin/npadmin --pagecount %(printer)s) 222 234 # 223 # Another example, using the special 'snmp' value, which doesn't launch224 # any subprocess but instead all SNMP processing is done from PyKota's main225 # code (this is less configurable, but requires less CPU and can prevent zombies) :226 #227 # accounter: hardware(snmp)228 #229 235 # Another example, for AppleTalk printers which works fine : 230 236 # (You may need the pap CUPS backend installed, and copy the … … 275 281 # the printer) 276 282 # 277 # YOU ABSOLUTELY HAVE TO BE SURE YOU HAVE A SCRIPT WHICH WAITS FOR THE 278 # PRINTER BEING READY BEFORE ASKING FOR ITS INTERNAL PAGE COUNTER. 279 # 280 # PYKOTA INCLUDES SUCH SCRIPTS FOR SNMP AND APPLETALK PRINTERS, MORE TO COME 281 # 282 # SOME OF THE ABOVE EXAMPLES DON'T USE SUCH A SCRIPT, YOU HAVE BEEN WARNED 283 # YOU ABSOLUTELY HAVE TO BE SURE YOU HAVE A SCRIPT WHICH WAITS FOR THE 284 # PRINTER BEING READY BEFORE ASKING FOR ITS INTERNAL PAGE COUNTER. 285 # 286 # PYKOTA INCLUDES SUCH SCRIPTS FOR SNMP AND APPLETALK PRINTERS, MORE TO COME 287 # 288 # SOME OF THE ABOVE EXAMPLES DON'T USE SUCH A SCRIPT, YOU HAVE BEEN WARNED 289 # 290 # 291 # WITH THE SPECIAL MAGIC hardware(snmp) AND hardware(pjl) VALUES, PYKOTA 292 # TAKES CARE OF ALL THIS FOR YOU, SO PLEASE UNDERSTAND THAT IT IS PREFERABLE 293 # TO USE THESE TWO METHODS : THEY WORK FINE, REQUIRE LITTLE TO NO CPU, 294 # AND DO ALL THE HARD WORK AUTOMATICALLY. IF YOU REALLY NEED TO YOU CAN USE 295 # YOUR OWN EXTERNAL COMMANDS AS DESCRIBED ABOVE, JUST BE CAREFUL WITH THIS. 283 296 # 284 297 # -
pykota/trunk/NEWS
r1742 r1746 22 22 PyKota NEWS : 23 23 24 - 1.20alpha16 : 25 26 - Internal handling of socket based PJL queries over 27 port tcp/9100 is now available with the magic 28 'pjl' value in the hardware accounter. 29 24 30 - 1.20alpha15 : 25 31 -
pykota/trunk/pykota/accounters/hardware.py
r1745 r1746 22 22 # 23 23 # $Log$ 24 # Revision 1.26 2004/09/27 19:56:27 jalet 25 # Added internal handling for PJL queries over port tcp/9100. Now waits 26 # for printer being idle before asking, just like with SNMP. 27 # 24 28 # Revision 1.25 2004/09/27 09:21:37 jalet 25 29 # Now includes printer's hostname in SNMP error messages … … 111 115 112 116 import os 117 import socket 113 118 import time 114 119 import signal … … 208 213 self.parent.filter.logdebug(_("Waiting for printer %s's idle status to stabilize...") % self.parent.filter.printername) 209 214 time.sleep(SNMPDELAY) 215 216 pjlMessage = "\033%-12345X@PJL USTATUSOFF\r\n@PJL USTATUS DEVICE=ON\r\n@PJL INFO STATUS\r\n@PJL INFO PAGECOUNT\r\n\033%-12345X" 217 pjlStatusValues = { 218 "10000" : "Powersave Mode", 219 "10001" : "Ready Online", 220 "10002" : "Ready Offline", 221 "10003" : "Warming Up", 222 "10004" : "Self Test", 223 "10005" : "Reset", 224 "10023" : "Printing", 225 } 226 class PJLAccounter : 227 """A class for PJL print accounting.""" 228 def __init__(self, parent, printerhostname) : 229 self.parent = parent 230 self.printerHostname = printerhostname 231 self.printerInternalPageCounter = self.printerStatus = None 232 self.printerInternalPageCounter = self.printerStatus = None 233 self.timedout = 0 234 235 def alarmHandler(self, signum, frame) : 236 """Query has timedout, handle this.""" 237 self.timedout = 1 238 raise IOError, "Waiting for PJL answer timed out. Please try again later." 239 240 def retrievePJLValues(self) : 241 """Retrieves a printer's internal page counter and status via PJL.""" 242 port = 9100 243 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 244 try : 245 sock.connect((self.printerHostname, port)) 246 except socket.error, msg : 247 self.parent.filter.printInfo(_("Problem during connection to %s:%s : %s") % (self.printerHostname, port, msg), "warn") 248 else : 249 try : 250 sock.send(pjlMessage) 251 except socket.error, msg : 252 self.parent.filter.printInfo(_("Problem while sending PJL query to %s:%s : %s") % (self.printerHostname, port, msg), "warn") 253 else : 254 actualpagecount = self.printerStatus = None 255 self.timedout = 0 256 while (self.timedout = 0) or (actualpagecount is None) or (self.printerStatus is None) : 257 signal.signal(signal.SIGALRM, self.alarmHandler) 258 signal.alarm(5) 259 try : 260 answer = sock.recv(1024) 261 except IOError, msg : 262 break # our alarm handler was launched, probably 263 else : 264 readnext = 0 265 for line in [l.strip() for l in answer.split()] : 266 if line.startswith("CODE=") : 267 self.printerStatus = line.split("=")[1] 268 elif line.startswith("PAGECOUNT") : 269 readnext = 1 # page counter is on next line 270 elif readnext : 271 actualpagecount = int(line.strip()) 272 readnext = 0 273 signal.alarm(0) 274 self.printerInternalPageCounter = max(actualpagecount, self.printerInternalPageCounter) 275 sock.close() 276 277 def waitPrinting(self) : 278 """Waits for printer status being 'printing'.""" 279 while 1: 280 self.retrievePJLValues() 281 if self.printerStatus in ('10000', '10001', '10023') : 282 break 283 # In reality, and if I'm not mistaken, we will NEVER get there. 284 self.parent.filter.logdebug(_("Waiting for printer %s to be idle or printing...") % self.parent.filter.printername) 285 time.sleep(ITERATIONDELAY) 286 287 def waitIdle(self) : 288 """Waits for printer status being 'idle'.""" 289 idle_num = idle_flag = 0 290 while 1 : 291 self.retrievePJLValues() 292 idle_flag = 0 293 if self.printerStatus in ('10000', '10001',) : 294 idle_flag = 1 295 if idle_flag : 296 idle_num += 1 297 if idle_num > STABILIZATIONDELAY : 298 # printer status is stable, we can exit 299 break 300 else : 301 idle_num = 0 302 self.parent.filter.logdebug(_("Waiting for printer %s's idle status to stabilize...") % self.parent.filter.printername) 303 time.sleep(ITERATIONDELAY) 210 304 211 305 class Accounter(AccounterBase) : … … 289 383 """ 290 384 commandline = self.arguments.strip() % locals() 291 if commandline.lower() == "snmp" : 385 cmdlower = commandline.lower() 386 if cmdlower == "snmp" : 292 387 if hasSNMP : 293 388 return self.askWithSNMP(printer) 294 389 else : 295 390 raise PyKotaAccounterError, _("Internal SNMP accounting asked, but Python-SNMP is not available. Please download it from http://pysnmp.sourceforge.net") 391 elif cmdlower == "pjl" : 392 return self.askWithPJL(printer) 296 393 297 394 if printer is None : … … 355 452 self.filter.printInfo(_("SNMP querying stage interrupted. Using latest value seen for internal page counter (%s) on printer %s.") % (acc.printerInternalPageCounter, self.filter.printername), "warn") 356 453 return acc.printerInternalPageCounter 454 455 def askWithPJL(self, printer) : 456 """Returns the page counter from the printer via internal PJL handling.""" 457 acc = PJLAccounter(self, printer) 458 try : 459 if (os.environ.get("PYKOTASTATUS") != "CANCELLED") and \ 460 (os.environ.get("PYKOTAACTION") != "DENY") and \ 461 (os.environ.get("PYKOTAPHASE") == "AFTER") : 462 acc.waitPrinting() 463 acc.waitIdle() 464 except : 465 if acc.printerInternalPageCounter is None : 466 raise 467 else : 468 self.filter.printInfo(_("PJL querying stage interrupted. Using latest value seen for internal page counter (%s) on printer %s.") % (acc.printerInternalPageCounter, self.filter.printername), "warn") 469 return acc.printerInternalPageCounter -
pykota/trunk/pykota/version.py
r1742 r1746 22 22 # 23 23 24 __version__ = "1.20alpha1 5_unofficial"24 __version__ = "1.20alpha16_unofficial" 25 25 26 26 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""