145 | | self.requester = openRequester(self.config, self.printername) |
146 | | |
| 146 | self.accounter = openAccounter(self) |
| 147 | |
| 148 | def extractInfoFromCupsOrLprng(self) : |
| 149 | """Returns a tuple (printingsystem, printerhostname, printername, username, jobid, filename) depending on the printing system in use (as seen by the print filter). |
| 150 | |
| 151 | Returns (None, None, None, None, None, None) if no printing system is recognized. |
| 152 | """ |
| 153 | # Try to detect CUPS |
| 154 | if os.environ.has_key("CUPS_SERVERROOT") and os.path.isdir(os.environ.get("CUPS_SERVERROOT", "")) : |
| 155 | if len(sys.argv) == 7 : |
| 156 | inputfile = sys.argv[6] |
| 157 | else : |
| 158 | inputfile = None |
| 159 | |
| 160 | device_uri = os.environ.get("DEVICE_URI", "") |
| 161 | # TODO : check this for more complex urls than ipp://myprinter.dot.com:631/printers/lp |
| 162 | try : |
| 163 | (backend, destination) = device_uri.split(":", 1) |
| 164 | except ValueError : |
| 165 | raise PyKotaToolError, "Invalid DEVICE_URI : %s\n" % device_uri |
| 166 | while destination.startswith("/") : |
| 167 | destination = destination[1:] |
| 168 | printerhostname = destination.split("/")[0].split(":")[0] |
| 169 | return ("CUPS", printerhostname, os.environ.get("PRINTER"), sys.argv[2].strip(), sys.argv[1].strip(), inputfile) |
| 170 | else : |
| 171 | # Try to detect LPRng |
| 172 | jseen = Jseen = Pseen = nseen = rseen = None |
| 173 | for arg in sys.argv : |
| 174 | if arg.startswith("-j") : |
| 175 | jseen = arg[2:].strip() |
| 176 | elif arg.startswith("-J") : |
| 177 | Jseen = arg[2:].strip() |
| 178 | if Jseen == "(STDIN)" : |
| 179 | Jseen = None |
| 180 | elif arg.startswith("-n") : |
| 181 | nseen = arg[2:].strip() |
| 182 | elif arg.startswith("-P") : |
| 183 | Pseen = arg[2:].strip() |
| 184 | elif arg.startswith("-r") : |
| 185 | rseen = arg[2:].strip() |
| 186 | if jseen and Pseen and nseen and rseen : |
| 187 | return ("LPRNG", rseen, Pseen, nseen, jseen, Jseen) |
| 188 | return (None, None, None, None, None, None) # Unknown printing system |
| 189 | |
218 | | # Get the page counter directly from the printer itself |
219 | | # Tries MAXTRIES times, sleeping two seconds each time, in case the printer is sleeping. |
220 | | # This was seen with my Apple LaserWriter 16/600 PS which doesn't answer before having warmed up. |
221 | | for i in range(MAXTRIES) : |
222 | | try : |
223 | | counterbeforejob = kotafilter.requester.getPrinterPageCounter(kotafilter.printerhostname) |
224 | | except PyKotaRequesterError, msg : |
225 | | # can't get actual page counter, assume printer is off or warming up |
226 | | # log the message anyway. |
227 | | kotafilter.logger.log_message("%s" % msg, "warn") |
228 | | counterbeforejob = None |
229 | | printerIsOff = 1 |
230 | | else : |
231 | | # printer answered, it is on so we can exit the loop |
232 | | printerIsOff = 0 |
233 | | break |
234 | | time.sleep(TIMETOSLEEP) |
235 | | |
236 | | # get last job information for this printer |
237 | | pgc = kotafilter.storage.getPrinterPageCounter(printerid) |
238 | | if pgc is None : |
239 | | # The printer hasn't been used yet, from PyKota's point of view |
240 | | lasthistoryid = None |
241 | | lastjobid = kotafilter.jobid |
242 | | lastuserid = userid |
243 | | lastusername = kotafilter.username |
244 | | lastpagecounter = counterbeforejob |
245 | | else : |
246 | | # get last values from Quota Storage |
247 | | (lasthistoryid, lastjobid, lastuserid, lastusername, lastpagecounter) = (pgc["id"], pgc["jobid"], pgc["userid"], pgc["username"], pgc["pagecounter"]) |
248 | | |
249 | | # if printer is off then we assume the correct counter value is the last one |
250 | | if printerIsOff : |
251 | | counterbeforejob = lastpagecounter |
252 | | |
253 | | # if the internal lifetime page counter for this printer is 0 |
254 | | # then this may be a printer with a volatile counter (never |
255 | | # saved to NVRAM) which has just been switched off and then on |
256 | | # so we use the last page counter from the Quota Storage instead |
257 | | # explanation at : http://web.mit.edu/source/third/lprng/doc/LPRng-HOWTO-15.html |
258 | | if counterbeforejob == 0 : |
259 | | counterbeforejob = lastpagecounter |
260 | | |
261 | | # Computes the last job size as the difference between internal page |
262 | | # counter in the printer and last page counter taken from the Quota |
263 | | # Storage database for this particular printer |
264 | | try : |
265 | | jobsize = (counterbeforejob - lastpagecounter) |
266 | | except TypeError : |
267 | | # never used, and internal page counter not accessible |
268 | | jobsize = 0 |
269 | | |
270 | | if jobsize < 0 : |
271 | | # Probably an HP printer which was switched off and back on, |
272 | | # its primary counter is only saved in a 10 increment, so |
273 | | # it may be lower than the last page counter saved in the |
274 | | # Quota Storage. |
275 | | # We unconditionnally set the last job's size to |
276 | | # abs(int((10 - abs(lastcounter(snmp) - lastcounter(storage)) / 2)) |
277 | | # For more accurate accounting, don't switch off your HP printers ! |
278 | | # explanation at : http://web.mit.edu/source/third/lprng/doc/LPRng-HOWTO-15.html |
279 | | kotafilter.logger.log_message(_("Error in page count value %i for user %s on printer %s") % (jobsize, lastusername, kotafilter.printername), "error") |
280 | | jobsize = abs(int((10 - abs(jobsize)) / 2)) # Workaround for HP printers' feature ! |
281 | | |
282 | | # update the quota for the previous user on this printer |
283 | | kotafilter.storage.updateUserPQuota(lastuserid, printerid, jobsize) |
284 | | |
285 | | # update the last job size in the history |
286 | | kotafilter.storage.updateJobSizeInHistory(lasthistoryid, jobsize) |
287 | | |
288 | | # warns the last user if he is over quota |
289 | | kotafilter.warnUserPQuota(lastusername, kotafilter.printername) |
290 | | |
291 | | # Is the current user allowed to print at all ? |
292 | | action = kotafilter.warnUserPQuota(kotafilter.username, kotafilter.printername) |
293 | | |
294 | | # adds the current job to history |
295 | | kotafilter.storage.addJobToHistory(kotafilter.jobid, kotafilter.storage.getUserId(kotafilter.username), printerid, counterbeforejob, action) |
| 259 | # Now does the accounting and act depending on the result |
| 260 | action = kotafilter.accounter.doAccounting(printerid, userid) |