root / pykota / trunk / pykota / accounters / hardware.py @ 1536

Revision 1536, 5.6 kB (checked in by jalet, 20 years ago)

Better messages in logs

  • 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.5  2004/06/10 22:42:06  jalet
25# Better messages in logs
26#
27# Revision 1.4  2004/05/24 22:45:49  jalet
28# New 'enforcement' directive added
29# Polling loop improvements
30#
31# Revision 1.3  2004/05/24 14:36:40  jalet
32# Revert to old polling loop. Will need optimisations
33#
34# Revision 1.2  2004/05/18 14:49:22  jalet
35# Big code changes to completely remove the need for "requester" directives,
36# jsut use "hardware(... your previous requester directive's content ...)"
37#
38# Revision 1.1  2004/05/13 13:59:30  jalet
39# Code simplifications
40#
41#
42#
43
44import sys
45import os
46import popen2
47from pykota.accounter import AccounterBase, PyKotaAccounterError
48
49class Accounter(AccounterBase) :
50    def __init__(self, kotabackend, arguments) :
51        """Initializes querying accounter."""
52        AccounterBase.__init__(self, kotabackend, arguments)
53       
54    def getPrinterInternalPageCounter(self) :   
55        """Returns the printer's internal page counter."""
56        self.filter.logdebug("Reading printer's internal page counter...")
57        try :
58            counter = self.askPrinterPageCounter(self.filter.printerhostname)
59        except PyKotaAccounterError, msg :
60            # can't get actual page counter, assume printer is off or warming up
61            # log the message anyway.
62            self.filter.logger.log_message("%s" % msg, "warn")
63            counter = None
64        self.filter.logdebug("Printer's internal page counter value is : %s" % str(counter))
65        return counter   
66       
67    def beginJob(self, userpquota) :   
68        """Saves printer internal page counter at start of job."""
69        # save page counter before job
70        self.LastPageCounter = self.counterbefore = self.getPrinterInternalPageCounter()
71       
72    def endJob(self, userpquota) :   
73        """Saves printer internal page counter at end of job."""
74        # save page counter after job
75        self.LastPageCounter = self.counterafter = self.getPrinterInternalPageCounter()
76       
77    def getJobSize(self) :   
78        """Returns the actual job size."""
79        try :
80            jobsize = (self.counterafter - self.counterbefore)   
81            if jobsize < 0 :
82                # Try to take care of HP printers
83                # Their internal page counter is saved to NVRAM
84                # only every 10 pages. If the printer was switched
85                # off then back on during the job, and that the
86                # counters difference is negative, we know
87                # the formula (we can't know if more than eleven
88                # pages were printed though) :
89                if jobsize > -10 :
90                    jobsize += 10
91                else :   
92                    # here we may have got a printer being replaced
93                    # DURING the job. This is HIGHLY improbable !
94                    jobsize = 0
95        except :   
96            # takes care of the case where one counter (or both) was never set.
97            jobsize = 0
98        return jobsize
99       
100    def askPrinterPageCounter(self, printer) :
101        """Returns the page counter from the printer via an external command.
102       
103           The external command must report the life time page number of the printer on stdout.
104        """
105        commandline = self.arguments.strip() % locals()
106        if printer is None :
107            raise PyKotaAccounterError, _("Unknown printer address in HARDWARE(%s) for printer %s") % (commandline, self.filter.printername)
108        self.filter.logger.log_message(_("Launching HARDWARE(%s)...") % commandline, "info")
109        error = 1
110        pagecounter = None
111        child = popen2.Popen4(commandline)   
112        try :
113            line = child.fromchild.readline()
114            pagecounter = int(line.strip())
115        except ValueError :   
116            self.filter.logger.log_message(_("Incorrect answer : %s") % repr(line), "error")
117        except IOError :   
118            # we were interrupted by a signal, certainely a SIGTERM
119            # caused by the user cancelling the current job
120            try :
121                os.kill(child.pid, signal.SIGTERM)
122            except :   
123                pass # already killed ?
124            self.filter.logger.log_message(_("SIGTERM was sent to hardware accounter %s (pid: %s)") % (commandline, child.pid), "info")
125        else :   
126            error = 0
127        child.fromchild.close()   
128        child.tochild.close()
129        try :
130            status = child.wait()
131        except OSError, msg :   
132            self.filter.logdebug("Error while waiting for hardware accounter pid %s : %s" % (child.pid, msg))
133            error = 1
134        if (not error) and os.WIFEXITED(status) and (not os.WEXITSTATUS(status)) :
135            return pagecounter
136        else :   
137            raise PyKotaAccounterError, _("Unable to query printer %s via HARDWARE(%s)") % (printer, commandline) 
138           
Note: See TracBrowser for help on using the browser.