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

Revision 1433, 5.8 kB (checked in by jalet, 20 years ago)

Began work on correct handling of child processes when jobs are cancelled by
the user. Especially important when an external requester is running for a
long time.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# PyKota
2# -*- coding: ISO-8859-15 -*-
3#
4# PyKota - Print Quotas for CUPS and LPRng
5#
6# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20#
21# $Id$
22#
23# $Log$
24# Revision 1.13  2004/04/09 22:24:47  jalet
25# Began work on correct handling of child processes when jobs are cancelled by
26# the user. Especially important when an external requester is running for a
27# long time.
28#
29# Revision 1.12  2004/01/11 23:22:42  jalet
30# Major code refactoring, it's way cleaner, and now allows automated addition
31# of printers on first print.
32#
33# Revision 1.11  2004/01/08 14:10:32  jalet
34# Copyright year changed.
35#
36# Revision 1.10  2003/12/27 16:49:25  uid67467
37# Should be ok now.
38#
39# Revision 1.8  2003/11/21 14:28:46  jalet
40# More complete job history.
41#
42# Revision 1.7  2003/11/12 23:29:24  jalet
43# More work on new backend. This commit may be unstable.
44#
45# Revision 1.6  2003/10/07 09:07:29  jalet
46# Character encoding added to please latest version of Python
47#
48# Revision 1.5  2003/07/07 11:49:24  jalet
49# Lots of small fixes with the help of PyChecker
50#
51# Revision 1.4  2003/06/25 14:10:01  jalet
52# Hey, it may work (edpykota --reset excepted) !
53#
54# Revision 1.3  2003/05/06 14:55:47  jalet
55# Missing import !
56#
57# Revision 1.2  2003/04/30 13:36:40  jalet
58# Stupid accounting method was added.
59#
60# Revision 1.1  2003/04/29 18:37:54  jalet
61# Pluggable accounting methods (actually doesn't support external scripts)
62#
63#
64#
65
66import sys
67import os
68import time
69from pykota.accounter import AccounterBase, PyKotaAccounterError
70from pykota.requester import openRequester, PyKotaRequesterError
71
72MAXTRIES = 12    # maximum number of tries to get the printer's internal page counter
73TIMETOSLEEP = 10 # number of seconds to sleep between two tries to get the printer's internal page counter
74
75class Accounter(AccounterBase) :
76    def __init__(self, kotabackend, arguments) :
77        """Initializes querying accounter."""
78        AccounterBase.__init__(self, kotabackend, arguments)
79        self.requester = openRequester(kotabackend, kotabackend.printername)
80        self.isDelayed = 1 # With the pykota filter, accounting is delayed by one job
81       
82    def getPrinterInternalPageCounter(self) :   
83        """Returns the printer's internal page counter."""
84        global MAXTRIES, TIMETOSLEEP
85        self.filter.logdebug("Reading printer's internal page counter...")
86        for dummy in range(MAXTRIES) :
87            try :
88                counter = self.requester.getPrinterPageCounter(self.filter.printerhostname)
89            except PyKotaRequesterError, msg :
90                # can't get actual page counter, assume printer is off or warming up
91                # log the message anyway.
92                self.filter.logger.log_message("%s" % msg, "warn")
93                counter = None
94            else :   
95                # printer answered, it is on so we can exit the loop
96                break
97            time.sleep(TIMETOSLEEP)   
98        self.filter.logdebug("Printer's internal page counter value is : %s" % str(counter))
99        return counter   
100       
101    def beginJob(self, userpquota) :   
102        """Saves printer internal page counter at start of job."""
103        # save page counter before job
104        self.LastPageCounter = self.counterbefore = self.getPrinterInternalPageCounter()
105       
106    def endJob(self, userpquota) :   
107        """Saves printer internal page counter at end of job."""
108        # save page counter after job
109        self.LastPageCounter = self.counterafter = self.getPrinterInternalPageCounter()
110       
111    def getJobSize(self) :   
112        """Returns the actual job size."""
113        try :
114            jobsize = (self.counterafter - self.counterbefore)   
115            if jobsize < 0 :
116                # Try to take care of HP printers
117                # Their internal page counter is saved to NVRAM
118                # only every 10 pages. If the printer was switched
119                # off then back on during the job, and that the
120                # counters difference is negative, we know
121                # the formula (we can't know if more than eleven
122                # pages were printed though) :
123                if jobsize > -10 :
124                    jobsize += 10
125                else :   
126                    # here we may have got a printer being replaced
127                    # DURING the job. This is HIGHLY improbable !
128                    jobsize = 0
129        except :   
130            # takes care of the case where one counter (or both) was never set.
131            jobsize = 0
132        return jobsize
133       
134    def doAccounting(self, userpquota) :
135        """Does print accounting and returns if the job status is ALLOW or DENY."""
136        # Get the page counter directly from the printer itself
137        counterbeforejob = self.getPrinterInternalPageCounter() or 0
138       
139        # Is the current user allowed to print at all ?
140        action = self.filter.warnUserPQuota(userpquota)
141       
142        # adds the current job to history   
143        userpquota.Printer.addJobToHistory(self.filter.jobid, userpquota.User, counterbeforejob, action, filename=self.filter.preserveinputfile, title=self.filter.title, copies=self.filter.copies, options=self.filter.options)
144        return action
145           
Note: See TracBrowser for help on using the browser.