root / pykota / trunk / pykota / accounters / software.py @ 2074

Revision 2074, 5.5 kB (checked in by jalet, 19 years ago)

Optimize print job parsing by avoiding to pass the job's datas through
PyKota's internal parser if the special construct "software()" is used
with no argument in the 'accounter' directive.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[1475]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$
[2074]24# Revision 1.12  2005/02/19 18:16:06  jalet
25# Optimize print job parsing by avoiding to pass the job's datas through
26# PyKota's internal parser if the special construct "software()" is used
27# with no argument in the 'accounter' directive.
28#
[1743]29# Revision 1.11  2004/09/24 21:19:48  jalet
30# Did a pass of PyChecker
31#
[1687]32# Revision 1.10  2004/08/31 23:29:53  jalet
33# Introduction of the new 'onaccountererror' configuration directive.
34# Small fix for software accounter's return code which can't be None anymore.
35# Make software and hardware accounting code look similar : will be factorized
36# later.
37#
[1680]38# Revision 1.9  2004/08/25 22:34:39  jalet
39# Now both software and hardware accounting raise an exception when no valid
40# result can be extracted from the subprocess' output.
41# Hardware accounting now reads subprocess' output until an integer is read
42# or data is exhausted : it now behaves just like software accounting in this
43# aspect.
44#
[1678]45# Revision 1.8  2004/08/22 14:04:47  jalet
46# Tries to fix problem with subprocesses outputting more datas than needed
47#
[1665]48# Revision 1.7  2004/08/06 13:45:51  jalet
49# Fixed french translation problem.
50# Fixed problem with group quotas and strict enforcement.
51#
[1584]52# Revision 1.6  2004/07/01 19:56:43  jalet
53# Better dispatching of error messages
54#
[1536]55# Revision 1.5  2004/06/10 22:42:06  jalet
56# Better messages in logs
57#
[1514]58# Revision 1.4  2004/06/02 21:51:14  jalet
59# Moved the sigterm capturing elsewhere
60#
[1495]61# Revision 1.3  2004/05/24 22:45:49  jalet
62# New 'enforcement' directive added
63# Polling loop improvements
64#
[1483]65# Revision 1.2  2004/05/18 14:49:23  jalet
66# Big code changes to completely remove the need for "requester" directives,
67# jsut use "hardware(... your previous requester directive's content ...)"
68#
[1475]69# Revision 1.1  2004/05/13 13:59:30  jalet
70# Code simplifications
71#
72#
73
74import os
75import popen2
76from pykota.accounter import AccounterBase, PyKotaAccounterError
77
78class Accounter(AccounterBase) :
79    def computeJobSize(self) :   
80        """Feeds an external command with our datas to let it compute the job size, and return its value."""
[1584]81        self.filter.printInfo(_("Launching SOFTWARE(%s)...") % self.arguments)
[2074]82        if not self.arguments :
83            pagecounter = self.filter.softwareJobSize   # Optimize : already computed !
84            self.filter.logdebug("Internal software accounter said job is %s pages long." % repr(pagecounter))
85        else :
86            MEGABYTE = 1024*1024
87            self.filter.jobdatastream.seek(0)
88            child = popen2.Popen4(self.arguments)
89            try :
90                data = self.filter.jobdatastream.read(MEGABYTE)   
91                while data :
92                    child.tochild.write(data)
93                    data = self.filter.jobdatastream.read(MEGABYTE)
94                child.tochild.flush()
95                child.tochild.close()   
96            except (IOError, OSError), msg :   
97                msg = "%s : %s" % (self.arguments, msg) 
98                self.filter.printInfo(_("Unable to compute job size with accounter %s") % msg)
[1475]99           
[2074]100            pagecounter = None
101            try :
102                answer = child.fromchild.read()
103            except (IOError, OSError), msg :   
104                msg = "%s : %s" % (self.arguments, msg) 
105                self.filter.printInfo(_("Unable to compute job size with accounter %s") % msg)
106            else :   
107                lines = [l.strip() for l in answer.split("\n")]
108                for i in range(len(lines)) : 
109                    try :
110                        pagecounter = int(lines[i])
111                    except (AttributeError, ValueError) :
112                        self.filter.printInfo(_("Line [%s] skipped in accounter's output. Trying again...") % lines[i])
113                    else :   
114                        break
115            child.fromchild.close()
[1680]116           
[2074]117            try :
118                status = child.wait()
119            except OSError, msg :   
120                self.filter.printInfo(_("Problem while waiting for software accounter pid %s to exit : %s") % (child.pid, msg))
121            else :   
122                if os.WIFEXITED(status) :
123                    status = os.WEXITSTATUS(status)
124                self.filter.printInfo(_("Software accounter %s exit code is %s") % (self.arguments, str(status)))
125               
126            if pagecounter is None :   
127                message = _("Unable to compute job size with accounter %s") % self.arguments
128                if self.onerror == "CONTINUE" :
129                    self.filter.printInfo(message, "error")
130                else :
131                    raise PyKotaAccounterError, message
132            self.filter.logdebug("Software accounter %s said job is %s pages long." % (self.arguments, repr(pagecounter)))
133           
[1687]134        return pagecounter or 0
Note: See TracBrowser for help on using the browser.