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

Revision 1584, 5.7 kB (checked in by jalet, 20 years ago)

Better dispatching of error messages

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