root / pykota / trunk / pykota / accounters / querying.py @ 973

Revision 973, 5.7 kB (checked in by jalet, 21 years ago)

Pluggable accounting methods (actually doesn't support external scripts)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# PyKota
2#
3# PyKota - Print Quotas for CUPS and LPRng
4#
5# (c) 2003 Jerome Alet <alet@librelogiciel.com>
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19#
20# $Id$
21#
22# $Log$
23# Revision 1.1  2003/04/29 18:37:54  jalet
24# Pluggable accounting methods (actually doesn't support external scripts)
25#
26#
27#
28
29from pykota.accounter import AccounterBase, PyKotaAccounterError
30from pykota.requester import openRequester, PyKotaRequesterError
31
32MAXTRIES = 6     # maximum number of tries to get the printer's internal page counter
33TIMETOSLEEP = 10 # number of seconds to sleep between two tries to get the printer's internal page counter
34
35class Accounter(AccounterBase) :
36    def doAccounting(self, printerid, userid) :
37        """Does print accounting and returns if the job status is ALLOW or DENY."""
38        # Get the page counter directly from the printer itself
39        # Tries MAXTRIES times, sleeping two seconds each time, in case the printer is sleeping.
40        # This was seen with my Apple LaserWriter 16/600 PS which doesn't answer before having warmed up.
41        global MAXTRIES, TIMETOSLEEP
42        requester = openRequester(self.filter.config, self.filter.printername)
43        for i in range(MAXTRIES) :
44            try :
45                counterbeforejob = requester.getPrinterPageCounter(self.filter.printerhostname)
46            except PyKotaRequesterError, msg :
47                # can't get actual page counter, assume printer is off or warming up
48                # log the message anyway.
49                self.filter.logger.log_message("%s" % msg, "warn")
50                counterbeforejob = None
51                printerIsOff = 1
52            else :   
53                # printer answered, it is on so we can exit the loop
54                printerIsOff = 0
55                break
56            time.sleep(TIMETOSLEEP)   
57       
58        # get last job information for this printer
59        pgc = self.filter.storage.getPrinterPageCounter(printerid)   
60        if pgc is None :
61            # The printer hasn't been used yet, from PyKota's point of view
62            lasthistoryid = None
63            lastjobid = self.filter.jobid
64            lastuserid = userid
65            lastusername = self.filter.username
66            lastpagecounter = counterbeforejob
67        else :   
68            # get last values from Quota Storage
69            (lasthistoryid, lastjobid, lastuserid, lastusername, lastpagecounter) = (pgc["id"], pgc["jobid"], pgc["userid"], pgc["username"], pgc["pagecounter"])
70           
71        # if printer is off then we assume the correct counter value is the last one
72        if printerIsOff :
73            counterbeforejob = lastpagecounter
74           
75        # if the internal lifetime page counter for this printer is 0   
76        # then this may be a printer with a volatile counter (never
77        # saved to NVRAM) which has just been switched off and then on
78        # so we use the last page counter from the Quota Storage instead
79        # explanation at : http://web.mit.edu/source/third/lprng/doc/LPRng-HOWTO-15.html
80        if counterbeforejob == 0 :
81            counterbeforejob = lastpagecounter
82           
83        # Computes the last job size as the difference between internal page
84        # counter in the printer and last page counter taken from the Quota
85        # Storage database for this particular printer
86        try :
87            jobsize = (counterbeforejob - lastpagecounter)   
88        except TypeError :   
89            # never used, and internal page counter not accessible
90            jobsize = 0
91           
92        if jobsize < 0 :
93            # Probably an HP printer which was switched off and back on,
94            # its primary counter is only saved in a 10 increment, so
95            # it may be lower than the last page counter saved in the
96            # Quota Storage.
97            # We unconditionnally set the last job's size to
98            # abs(int((10 - abs(lastcounter(snmp) - lastcounter(storage)) / 2))
99            # For more accurate accounting, don't switch off your HP printers !
100            # explanation at : http://web.mit.edu/source/third/lprng/doc/LPRng-HOWTO-15.html
101            self.filter.logger.log_message(_("Error in page count value %i for user %s on printer %s") % (jobsize, lastusername, self.filter.printername), "error")
102            jobsize = abs(int((10 - abs(jobsize)) / 2))     # Workaround for HP printers' feature !
103           
104        # update the quota for the previous user on this printer
105        self.filter.storage.updateUserPQuota(lastuserid, printerid, jobsize)
106       
107        # update the last job size in the history
108        self.filter.storage.updateJobSizeInHistory(lasthistoryid, jobsize)
109       
110        # warns the last user if he is over quota
111        self.filter.warnUserPQuota(lastusername, self.filter.printername)
112           
113        # Is the current user allowed to print at all ?
114        action = self.filter.warnUserPQuota(self.filter.username, self.filter.printername)
115       
116        # adds the current job to history   
117        self.filter.storage.addJobToHistory(self.filter.jobid, self.filter.storage.getUserId(self.filter.username), printerid, counterbeforejob, action)
118           
119        return action
Note: See TracBrowser for help on using the browser.