Changeset 1502
- Timestamp:
- 05/26/04 16:50:12 (21 years ago)
- Location:
- pykota/trunk
- Files:
-
- 8 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/cupspykota
r1499 r1502 24 24 # 25 25 # $Log$ 26 # Revision 1.53 2004/05/26 14:49:35 jalet 27 # First try at saving the job-originating-hostname in the database 28 # 26 29 # Revision 1.52 2004/05/25 09:15:13 jalet 27 30 # accounter.py : old code deleted … … 252 255 return 0 253 256 257 def getPageLogLocation(self) : 258 """Retrieves CUPS' page_log file location.""" 259 location = None 260 cupsroot = os.environ.get("CUPS_SERVERROOT", "/etc/cups") 261 cupsdconf = os.path.join(cupsroot, "cupsd.conf") 262 try : 263 conffile = open(cupsdconf, "r") 264 except IOError : 265 return # file doesn't exist or can't be read 266 else : 267 for line in conffile.readlines() : 268 linecopy = line.strip().lower() 269 if linecopy.startswith("pagelog ") : 270 try : 271 location = line.split()[1] 272 except : 273 pass # ignore errors, we take the last value in any case. 274 conffile.close() 275 return location 276 277 def getJobOriginatingHostname(self, printername, username, jobid) : 278 """Retrieves the job-originating-hostname from the CUPS page_log file if possible.""" 279 pagelogpath = self.getPageLogLocation() or "/var/log/cups/page_log" 280 try : 281 pagelog = open(pagelogpath, "r") 282 except IOError : 283 return # no page log or can't read it, originating hostname unknown yet 284 else : 285 # TODO : read backward so we could take first value seen 286 # TODO : here we read forward so we must take the last value seen 287 prefix = "%s %s %s" % (printername, username, jobid) 288 matchingline = None 289 while 1 : 290 line = pagelog.readline() 291 if not line : 292 break 293 else : 294 line = line.strip() 295 if line.startswith(prefix) : 296 matchingline = line # no break, because we read forward 297 pagelog.close() 298 if matchingline is None : 299 return # correct line not found, job-originating-hostname unknown 300 else : 301 return matchingline.split()[-1] 302 254 303 def doWork(self, policy, printer, user, userpquota) : 255 304 """Most of the work is done here.""" … … 262 311 # exports user information with initial values 263 312 self.exportUserInfo(userpquota) 313 314 # tries to extract job-originating-hostname 315 clienthost = self.getJobOriginatingHostname(printer.Name, user.Name, self.jobid) 316 os.putenv("PYKOTAJOBORIGINATINGHOSTNAME", str(clienthost or "")) 264 317 265 318 # enters first phase … … 317 370 318 371 # adds the current job to history 319 printer.addJobToHistory(self.jobid, user, self.accounter.getLastPageCounter(), action, jobsize, jobprice, self.preserveinputfile, self.title, self.copies, self.options )372 printer.addJobToHistory(self.jobid, user, self.accounter.getLastPageCounter(), action, jobsize, jobprice, self.preserveinputfile, self.title, self.copies, self.options, clienthost) 320 373 self.logdebug("Job added to history.") 321 374 -
pykota/trunk/cgi-bin/printquota.cgi
r1419 r1502 23 23 # 24 24 # $Log$ 25 # Revision 1.27 2004/05/26 14:49:40 jalet 26 # First try at saving the job-originating-hostname in the database 27 # 25 28 # Revision 1.26 2004/03/24 19:37:04 jalet 26 29 # Doesn't retrieve users or printers objects to display the history, … … 266 269 else : 267 270 self.report.append('<table class="pykotatable" border="1">') 268 headers = ["Date", "User", "Printer", "PageCounter", "JobId", "JobSize", "JobPrice", "Copies", "Title", "Filename", "Options", " Action"]271 headers = ["Date", "User", "Printer", "PageCounter", "JobId", "JobSize", "JobPrice", "Copies", "Title", "Filename", "Options", "HostName", "Action"] 269 272 self.report.append('<tr class="pykotacolsheader">%s</tr>' % "".join(["<th>%s</th>" % h for h in headers])) 270 273 oddeven = 0 … … 280 283 oddevenclass = "warn" 281 284 username = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "username" : job.UserName}), job.UserName) 282 self.report.append('<tr class="%s">%s</tr>' % (oddevenclass, "".join(["<td>%s</td>" % h for h in (job.JobDate[:19], username, job.PrinterName, job.PrinterPageCounter, job.JobId, job.JobSize, job.JobPrice, job.JobCopies, job.JobTitle, job.JobFileName, job.JobOptions, job.Job Action)])))285 self.report.append('<tr class="%s">%s</tr>' % (oddevenclass, "".join(["<td>%s</td>" % h for h in (job.JobDate[:19], username, job.PrinterName, job.PrinterPageCounter, job.JobId, job.JobSize, job.JobPrice, job.JobCopies, job.JobTitle, job.JobFileName, job.JobOptions, job.JobHostName, job.JobAction)]))) 283 286 self.report.append('</table>') 284 287 dico = { "history" : 1, -
pykota/trunk/conf/pykota.conf.sample
r1499 r1502 455 455 # PYKOTAPRECOMPUTEDJOBSIZE : contains the precomputed job's size 456 456 # PYKOTAPRECOMPUTEDJOBPRICE : contains the precomputed job's price 457 # 457 # PYKOTAJOBORIGINATINGHOSTNAME : contains the client's hostname if 458 # it is possible to retrieve it. 458 459 459 460 # PreHook : gets executed after being sure the user, printer and user quota -
pykota/trunk/NEWS
r1500 r1502 23 23 24 24 25 - 1.19alpha16 : 26 27 - The job's originating hostname is now stored in the database, 28 and exported as PYKOTAJOBORIGINATINGHOSTNAME in the environment. 29 25 30 - 1.19alpha15 : 26 31 -
pykota/trunk/pykota/storage.py
r1418 r1502 22 22 # 23 23 # $Log$ 24 # Revision 1.52 2004/05/26 14:49:57 jalet 25 # First try at saving the job-originating-hostname in the database 26 # 24 27 # Revision 1.51 2004/03/24 15:15:24 jalet 25 28 # Began integration of Henrik Janhagen's work on quota-then-balance … … 300 303 raise AttributeError, name 301 304 302 def addJobToHistory(self, jobid, user, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None ) :305 def addJobToHistory(self, jobid, user, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None, clienthost=None) : 303 306 """Adds a job to the printer's history.""" 304 self.parent.writeJobNew(self, user, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options )307 self.parent.writeJobNew(self, user, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options, clienthost) 305 308 # TODO : update LastJob object ? Probably not needed. 306 309 … … 454 457 self.JobCopies = None 455 458 self.JobOptions = None 459 self.JobHostName = None 456 460 457 461 def __getattr__(self, name) : -
pykota/trunk/pykota/storages/ldapstorage.py
r1451 r1502 22 22 # 23 23 # $Log$ 24 # Revision 1.64 2004/05/26 14:50:01 jalet 25 # First try at saving the job-originating-hostname in the database 26 # 24 27 # Revision 1.63 2004/05/06 12:37:46 jalet 25 28 # pkpgcounter : comments … … 591 594 lastjob.lastjobident = result[0][0] 592 595 lastjobident = result[0][1]["pykotaLastJobIdent"][0] 593 result = self.doSearch("objectClass=pykotaJob", ["pykota UserName", "pykotaJobId", "pykotaPrinterPageCounter", "pykotaJobSize", "pykotaAction", "pykotaJobPrice", "pykotaFileName", "pykotaTitle", "pykotaCopies", "pykotaOptions", "createTimestamp"], base="cn=%s,%s" % (lastjobident, self.info["jobbase"]), scope=ldap.SCOPE_BASE)596 result = self.doSearch("objectClass=pykotaJob", ["pykotaHostName", "pykotaUserName", "pykotaJobId", "pykotaPrinterPageCounter", "pykotaJobSize", "pykotaAction", "pykotaJobPrice", "pykotaFileName", "pykotaTitle", "pykotaCopies", "pykotaOptions", "createTimestamp"], base="cn=%s,%s" % (lastjobident, self.info["jobbase"]), scope=ldap.SCOPE_BASE) 594 597 if result : 595 598 fields = result[0][1] … … 605 608 lastjob.JobCopies = int(fields.get("pykotaCopies", [0])[0]) 606 609 lastjob.JobOptions = fields.get("pykotaOptions", [""])[0] 610 lastjob.JobHostName = fields.get("pykotaHostName", [""])[0] 607 611 date = fields.get("createTimestamp", ["19700101000000"])[0] 608 612 year = int(date[:4]) … … 912 916 self.doModify(lastjob.ident, fields) 913 917 914 def writeJobNew(self, printer, user, jobid, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None ) :918 def writeJobNew(self, printer, user, jobid, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None, clienthost=None) : 915 919 """Adds a job in a printer's history.""" 916 920 if (not self.disablehistory) or (not printer.LastJob.Exists) : … … 932 936 "pykotaCopies" : str(copies), 933 937 "pykotaOptions" : str(options), 938 "pykotaHostName" : str(clienthost), 934 939 } 935 940 if (not self.disablehistory) or (not printer.LastJob.Exists) : … … 997 1002 self.doModify(pgroup.ident, fields) 998 1003 999 def retrieveHistory(self, user=None, printer=None, datelimit=None, limit=100) :1004 def retrieveHistory(self, user=None, printer=None, datelimit=None, hostname=None, limit=100) : 1000 1005 """Retrieves all print jobs for user on printer (or all) before date, limited to first 100 results.""" 1001 1006 precond = "(objectClass=pykotaJob)" … … 1005 1010 if (printer is not None) and printer.Exists : 1006 1011 where.append("(pykotaPrinterName=%s)" % printer.Name) 1012 if hostname is not None : 1013 where.append("(pykotaHostName=%s)" % hostname) 1007 1014 if where : 1008 1015 where = "(&%s)" % "".join([precond] + where) … … 1010 1017 where = precond 1011 1018 jobs = [] 1012 result = self.doSearch(where, fields=["pykota UserName", "pykotaPrinterName", "pykotaJobId", "pykotaPrinterPageCounter", "pykotaAction", "pykotaJobSize", "pykotaJobPrice", "pykotaFileName", "pykotaTitle", "pykotaCopies", "pykotaOptions", "createTimestamp"], base=self.info["jobbase"])1019 result = self.doSearch(where, fields=["pykotaHostName", "pykotaUserName", "pykotaPrinterName", "pykotaJobId", "pykotaPrinterPageCounter", "pykotaAction", "pykotaJobSize", "pykotaJobPrice", "pykotaFileName", "pykotaTitle", "pykotaCopies", "pykotaOptions", "createTimestamp"], base=self.info["jobbase"]) 1013 1020 if result : 1014 1021 for (ident, fields) in result : … … 1024 1031 job.JobCopies = int(fields.get("pykotaCopies", [0])[0]) 1025 1032 job.JobOptions = fields.get("pykotaOptions", [""])[0] 1033 job.JobHostName = fields.get("pykotaHostName", [""])[0] 1026 1034 date = fields.get("createTimestamp", ["19700101000000"])[0] 1027 1035 year = int(date[:4]) -
pykota/trunk/pykota/storages/sql.py
r1451 r1502 22 22 # 23 23 # $Log$ 24 # Revision 1.39 2004/05/26 14:50:12 jalet 25 # First try at saving the job-originating-hostname in the database 26 # 24 27 # Revision 1.38 2004/05/06 12:37:47 jalet 25 28 # pkpgcounter : comments … … 143 146 """Extracts a printer's last job information.""" 144 147 lastjob = StorageLastJob(self, printer) 145 result = self.doSearch("SELECT jobhistory.id, jobid, userid, username, pagecounter, jobsize, jobprice, filename, title, copies, options, jobdate FROM jobhistory, users WHERE printerid=%s AND userid=users.id ORDER BY jobdate DESC LIMIT 1" % self.doQuote(printer.ident))148 result = self.doSearch("SELECT jobhistory.id, jobid, userid, username, pagecounter, jobsize, jobprice, filename, title, copies, options, hostname, jobdate FROM jobhistory, users WHERE printerid=%s AND userid=users.id ORDER BY jobdate DESC LIMIT 1" % self.doQuote(printer.ident)) 146 149 if result : 147 150 fields = result[0] … … 158 161 lastjob.JobOptions = fields.get("options") 159 162 lastjob.JobDate = fields.get("jobdate") 163 lastjob.JobHostName = fields.get("hostname") 160 164 lastjob.Exists = 1 161 165 return lastjob … … 335 339 self.doModify("UPDATE jobhistory SET jobsize=%s, jobprice=%s WHERE id=%s" % (self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(lastjob.ident))) 336 340 337 def writeJobNew(self, printer, user, jobid, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None ) :341 def writeJobNew(self, printer, user, jobid, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None, clienthost=None) : 338 342 """Adds a job in a printer's history.""" 339 343 if (not self.disablehistory) or (not printer.LastJob.Exists) : 340 344 if jobsize is not None : 341 self.doModify("INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(printer.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options)))345 self.doModify("INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options, hostname) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(printer.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options), self.doQuote(clienthost))) 342 346 else : 343 self.doModify("INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, filename, title, copies, options ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(printer.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options)))347 self.doModify("INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, filename, title, copies, options, hostname) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(printer.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options), self.doQuote(clienthost))) 344 348 else : 345 349 # here we explicitly want to reset jobsize to NULL if needed 346 self.doModify("UPDATE jobhistory SET userid=%s, jobid=%s, pagecounter=%s, action=%s, jobsize=%s, jobprice=%s, filename=%s, title=%s, copies=%s, options=%s, jobdate=now() WHERE id=%s" % (self.doQuote(user.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options), self.doQuote(printer.LastJob.ident)))350 self.doModify("UPDATE jobhistory SET userid=%s, jobid=%s, pagecounter=%s, action=%s, jobsize=%s, jobprice=%s, filename=%s, title=%s, copies=%s, options=%s, hostname=%s, jobdate=now() WHERE id=%s" % (self.doQuote(user.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options), self.doQuote(clienthost), self.doQuote(printer.LastJob.ident))) 347 351 348 352 def writeUserPQuotaLimits(self, userpquota, softlimit, hardlimit) : … … 368 372 self.doModify("DELETE FROM printergroupsmembers WHERE groupid=%s AND printerid=%s" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident))) 369 373 370 def retrieveHistory(self, user=None, printer=None, datelimit=None, limit=100) :374 def retrieveHistory(self, user=None, printer=None, datelimit=None, hostname=None, limit=100) : 371 375 """Retrieves all print jobs for user on printer (or all) before date, limited to first 100 results.""" 372 376 query = "SELECT jobhistory.*,username,printername FROM jobhistory,users,printers WHERE users.id=userid AND printers.id=printerid" … … 376 380 if (printer is not None) and printer.Exists : 377 381 where.append("printerid=%s" % self.doQuote(printer.ident)) 382 if hostname is not None : 383 where.append("hostname=%s" % self.doQuote(hostname)) 378 384 if datelimit is not None : 379 385 where.append("jobdate<=%s" % self.doQuote(datelimit)) … … 399 405 job.JobOptions = fields.get("options") 400 406 job.JobDate = fields.get("jobdate") 407 job.JobHostName = fields.get("hostname") 401 408 job.UserName = fields.get("username") 402 409 job.PrinterName = fields.get("printername") -
pykota/trunk/pykota/version.py
r1500 r1502 22 22 # 23 23 24 __version__ = "1.19alpha1 5_unofficial"24 __version__ = "1.19alpha16_unofficial" 25 25 26 26 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""