Index: pykota/trunk/pykota/accounters/software.py
===================================================================
--- pykota/trunk/pykota/accounters/software.py (revision 1475)
+++ pykota/trunk/pykota/accounters/software.py (revision 1475)
@@ -0,0 +1,102 @@
+# PyKota
+# -*- coding: ISO-8859-15 -*-
+#
+# PyKota - Print Quotas for CUPS and LPRng
+#
+# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+#
+# $Log$
+# Revision 1.1  2004/05/13 13:59:30  jalet
+# Code simplifications
+#
+#
+#
+
+import sys
+import os
+import popen2
+import tempfile
+from pykota.accounter import AccounterBase, PyKotaAccounterError
+
+class Accounter(AccounterBase) :
+    def computeJobSize(self) :    
+        """Feeds an external command with our datas to let it compute the job size, and return its value."""
+        temporary = None    
+        if self.filter.inputfile is None :    
+            infile = sys.stdin
+            # we will have to duplicate our standard input
+            temporary = tempfile.TemporaryFile()
+        else :    
+            infile = open(self.filter.inputfile, "rb")
+            
+        # launches external accounter
+        # TODO : USE tempfile.mkstemp() instead ! Needs some work !
+        infilename = tempfile.mktemp()
+        outfilename = tempfile.mktemp()
+        errfilename = tempfile.mktemp()
+        
+        try :
+            # feed it with our data
+            fakeinput = open(infilename, "wb")
+            data = infile.read(256*1024)    
+            while data :
+                fakeinput.write(data)
+                if temporary is not None :
+                    temporary.write(data)
+                data = infile.read(256*1024)
+            fakeinput.close()
+        
+            # launches child process
+            command = "%s <%s >%s 2>%s" % (self.arguments, infilename, outfilename, errfilename)
+            retcode = os.system(command)
+            
+            # check exit status
+            if (os.WIFEXITED(retcode) and not os.WEXITSTATUS(retcode)) or os.stat(errfilename) :
+                # tries to extract the job size from the external accounter's
+                # standard output
+                childoutput = open(outfilename, "r")
+                try :
+                    pagecount = int(childoutput.readline().strip())
+                except (AttributeError, ValueError) :
+                    self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments)
+                    pagecount = 0
+                childoutput.close()    
+            else :
+                self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments)
+                pagecount = 0
+            os.remove(infilename)
+            os.remove(outfilename)
+            os.remove(errfilename)
+        except IOError, msg :    
+            # TODO : temporary files may remain on the filesystem...
+            msg = "%s : %s" % (self.arguments, msg) 
+            self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % msg)
+            pagecount = 0
+            
+        if temporary is not None :    
+            # this is a copy of our previous standard input
+            # flush, then rewind
+            temporary.flush()
+            temporary.seek(0, 0)
+            # our temporary file will be used later if the
+            # job is allowed.
+            self.filter.inputfile = temporary
+        else :
+            infile.close()
+        return pagecount    
+            
Index: pykota/trunk/pykota/accounters/hardware.py
===================================================================
--- pykota/trunk/pykota/accounters/hardware.py (revision 1475)
+++ pykota/trunk/pykota/accounters/hardware.py (revision 1475)
@@ -0,0 +1,99 @@
+# PyKota
+# -*- coding: ISO-8859-15 -*-
+#
+# PyKota - Print Quotas for CUPS and LPRng
+#
+# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+#
+# $Log$
+# Revision 1.1  2004/05/13 13:59:30  jalet
+# Code simplifications
+#
+#
+#
+
+import sys
+import os
+from pykota.accounter import AccounterBase, PyKotaAccounterError
+from pykota.requester import openRequester, PyKotaRequesterError
+
+class Accounter(AccounterBase) :
+    def __init__(self, kotabackend, arguments) :
+        """Initializes querying accounter."""
+        AccounterBase.__init__(self, kotabackend, arguments)
+        self.requester = openRequester(kotabackend, kotabackend.printername)
+        self.isDelayed = 1 # With the pykota filter, accounting is delayed by one job
+        
+    def getPrinterInternalPageCounter(self) :    
+        """Returns the printer's internal page counter."""
+        self.filter.logdebug("Reading printer's internal page counter...")
+        try :
+            counter = self.requester.getPrinterPageCounter(self.filter.printerhostname)
+        except PyKotaRequesterError, msg :
+            # can't get actual page counter, assume printer is off or warming up
+            # log the message anyway.
+            self.filter.logger.log_message("%s" % msg, "warn")
+            counter = None
+        self.filter.logdebug("Printer's internal page counter value is : %s" % str(counter))
+        return counter    
+        
+    def beginJob(self, userpquota) :    
+        """Saves printer internal page counter at start of job."""
+        # save page counter before job
+        self.LastPageCounter = self.counterbefore = self.getPrinterInternalPageCounter()
+        
+    def endJob(self, userpquota) :    
+        """Saves printer internal page counter at end of job."""
+        # save page counter after job
+        self.LastPageCounter = self.counterafter = self.getPrinterInternalPageCounter()
+        
+    def getJobSize(self) :    
+        """Returns the actual job size."""
+        try :
+            jobsize = (self.counterafter - self.counterbefore)    
+            if jobsize < 0 :
+                # Try to take care of HP printers 
+                # Their internal page counter is saved to NVRAM
+                # only every 10 pages. If the printer was switched
+                # off then back on during the job, and that the
+                # counters difference is negative, we know 
+                # the formula (we can't know if more than eleven
+                # pages were printed though) :
+                if jobsize > -10 :
+                    jobsize += 10
+                else :    
+                    # here we may have got a printer being replaced
+                    # DURING the job. This is HIGHLY improbable !
+                    jobsize = 0
+        except :    
+            # takes care of the case where one counter (or both) was never set.
+            jobsize = 0
+        return jobsize
+        
+    def doAccounting(self, userpquota) :
+        """Does print accounting and returns if the job status is ALLOW or DENY."""
+        # Get the page counter directly from the printer itself
+        counterbeforejob = self.getPrinterInternalPageCounter() or 0
+        
+        # Is the current user allowed to print at all ?
+        action = self.filter.warnUserPQuota(userpquota)
+        
+        # adds the current job to history    
+        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)
+        return action
+            
Index: pykota/trunk/pykota/accounters/Makefile.am
===================================================================
--- pykota/trunk/pykota/accounters/Makefile.am (revision 1417)
+++ pykota/trunk/pykota/accounters/Makefile.am (revision 1475)
@@ -2,7 +2,6 @@
 
 pykota_accounters_PYTHON = 	\
-	external.py				\
+	software.py				\
 	__init__.py				\
-	querying.py				\
-	stupid.py				
+	hardware.py
 
Index: pykota/trunk/pykota/accounters/stupid.py
===================================================================
--- pykota/trunk/pykota/accounters/stupid.py (revision 1257)
+++  (revision )
@@ -1,95 +1,0 @@
-# PyKota
-# -*- coding: ISO-8859-15 -*-
-#
-# PyKota - Print Quotas for CUPS and LPRng
-#
-# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-#
-# $Id$
-#
-# $Log$
-# Revision 1.11  2004/01/08 14:10:32  jalet
-# Copyright year changed.
-#
-# Revision 1.10  2003/12/27 16:49:25  uid67467
-# Should be ok now.
-#
-# Revision 1.8  2003/11/23 19:01:37  jalet
-# Job price added to history
-#
-# Revision 1.7  2003/11/21 14:28:46  jalet
-# More complete job history.
-#
-# Revision 1.6  2003/11/12 23:29:24  jalet
-# More work on new backend. This commit may be unstable.
-#
-# Revision 1.5  2003/10/07 09:07:29  jalet
-# Character encoding added to please latest version of Python
-#
-# Revision 1.4  2003/06/25 14:10:01  jalet
-# Hey, it may work (edpykota --reset excepted) !
-#
-# Revision 1.3  2003/05/27 23:00:21  jalet
-# Big rewrite of external accounting methods.
-# Should work well now.
-#
-# Revision 1.2  2003/04/30 13:40:47  jalet
-# Small fix
-#
-# Revision 1.1  2003/04/30 13:36:40  jalet
-# Stupid accounting method was added.
-#
-#
-#
-
-import sys
-import tempfile
-from pykota.accounter import AccounterBase, PyKotaAccounterError
-
-class Accounter(AccounterBase) :
-    def computeJobSize(self) :    
-        """Computes the job size and return its value.
-        
-           THIS METHOD IS COMPLETELY UNRELIABLE BUT SERVES AS AN EXAMPLE.
-        """
-        # first we log a message because using this accounting method is not recommended.
-        self.filter.logger.log_message(_("Using the 'stupid' accounting method is unreliable."), "warn")
-        
-        temporary = None    
-        if self.filter.inputfile is None :    
-            infile = sys.stdin
-            # we will have to duplicate our standard input
-            temporary = tempfile.TemporaryFile()
-        else :    
-            infile = open(self.filter.inputfile, "rb")
-            
-        pagecount = 0
-        for line in infile.xreadlines() :
-            pagecount += line.count("showpage")
-            if temporary is not None :    
-                temporary.write(line)    
-                
-        if temporary is not None :    
-            # this is a copy of our previous standard input
-            # flush, then rewind
-            temporary.flush()
-            temporary.seek(0, 0)
-            # our temporary file will be used later if the
-            # job is allowed.
-            self.filter.inputfile = temporary
-        else :
-            infile.close()
-        return pagecount    
Index: pykota/trunk/pykota/accounters/external.py
===================================================================
--- pykota/trunk/pykota/accounters/external.py (revision 1257)
+++  (revision )
@@ -1,136 +1,0 @@
-# PyKota
-# -*- coding: ISO-8859-15 -*-
-#
-# PyKota - Print Quotas for CUPS and LPRng
-#
-# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-#
-# $Id$
-#
-# $Log$
-# Revision 1.13  2004/01/08 14:10:32  jalet
-# Copyright year changed.
-#
-# Revision 1.12  2003/12/27 16:49:25  uid67467
-# Should be ok now.
-#
-# Revision 1.10  2003/11/23 19:01:36  jalet
-# Job price added to history
-#
-# Revision 1.9  2003/11/21 14:28:45  jalet
-# More complete job history.
-#
-# Revision 1.8  2003/11/12 23:29:24  jalet
-# More work on new backend. This commit may be unstable.
-#
-# Revision 1.7  2003/10/07 09:07:28  jalet
-# Character encoding added to please latest version of Python
-#
-# Revision 1.6  2003/09/04 07:57:18  jalet
-# Problem with Python 2.3 fixed : a bug of me.
-#
-# Revision 1.5  2003/07/07 11:49:24  jalet
-# Lots of small fixes with the help of PyChecker
-#
-# Revision 1.4  2003/06/25 14:10:01  jalet
-# Hey, it may work (edpykota --reset excepted) !
-#
-# Revision 1.3  2003/05/27 23:00:21  jalet
-# Big rewrite of external accounting methods.
-# Should work well now.
-#
-# Revision 1.2  2003/05/13 13:54:20  jalet
-# Better handling of broken pipes
-#
-# Revision 1.1  2003/05/07 19:47:06  jalet
-# v1.07 Release of the Shame is out !
-#
-#
-#
-
-import sys
-import os
-import popen2
-import tempfile
-from pykota.accounter import AccounterBase, PyKotaAccounterError
-
-class Accounter(AccounterBase) :
-    def computeJobSize(self) :    
-        """Feeds an external command with our datas to let it compute the job size, and return its value."""
-        temporary = None    
-        if self.filter.inputfile is None :    
-            infile = sys.stdin
-            # we will have to duplicate our standard input
-            temporary = tempfile.TemporaryFile()
-        else :    
-            infile = open(self.filter.inputfile, "rb")
-            
-        # launches external accounter
-        # TODO : USE tempfile.mkstemp() instead ! Needs some work !
-        infilename = tempfile.mktemp()
-        outfilename = tempfile.mktemp()
-        errfilename = tempfile.mktemp()
-        
-        try :
-            # feed it with our data
-            fakeinput = open(infilename, "wb")
-            data = infile.read(256*1024)    
-            while data :
-                fakeinput.write(data)
-                if temporary is not None :
-                    temporary.write(data)
-                data = infile.read(256*1024)
-            fakeinput.close()
-        
-            # launches child process
-            command = "%s <%s >%s 2>%s" % (self.arguments, infilename, outfilename, errfilename)
-            retcode = os.system(command)
-            
-            # check exit status
-            if (os.WIFEXITED(retcode) and not os.WEXITSTATUS(retcode)) or os.stat(errfilename) :
-                # tries to extract the job size from the external accounter's
-                # standard output
-                childoutput = open(outfilename, "r")
-                try :
-                    pagecount = int(childoutput.readline().strip())
-                except (AttributeError, ValueError) :
-                    self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments)
-                    pagecount = 0
-                childoutput.close()    
-            else :
-                self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % self.arguments)
-                pagecount = 0
-            os.remove(infilename)
-            os.remove(outfilename)
-            os.remove(errfilename)
-        except IOError, msg :    
-            # TODO : temporary files may remain on the filesystem...
-            msg = "%s : %s" % (self.arguments, msg) 
-            self.filter.logger.log_message(_("Unable to compute job size with external accounter %s") % msg)
-            pagecount = 0
-            
-        if temporary is not None :    
-            # this is a copy of our previous standard input
-            # flush, then rewind
-            temporary.flush()
-            temporary.seek(0, 0)
-            # our temporary file will be used later if the
-            # job is allowed.
-            self.filter.inputfile = temporary
-        else :
-            infile.close()
-        return pagecount    
-            
Index: pykota/trunk/pykota/accounters/querying.py
===================================================================
--- pykota/trunk/pykota/accounters/querying.py (revision 1433)
+++  (revision )
@@ -1,145 +1,0 @@
-# PyKota
-# -*- coding: ISO-8859-15 -*-
-#
-# PyKota - Print Quotas for CUPS and LPRng
-#
-# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-#
-# $Id$
-#
-# $Log$
-# Revision 1.13  2004/04/09 22:24:47  jalet
-# 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.
-#
-# Revision 1.12  2004/01/11 23:22:42  jalet
-# Major code refactoring, it's way cleaner, and now allows automated addition
-# of printers on first print.
-#
-# Revision 1.11  2004/01/08 14:10:32  jalet
-# Copyright year changed.
-#
-# Revision 1.10  2003/12/27 16:49:25  uid67467
-# Should be ok now.
-#
-# Revision 1.8  2003/11/21 14:28:46  jalet
-# More complete job history.
-#
-# Revision 1.7  2003/11/12 23:29:24  jalet
-# More work on new backend. This commit may be unstable.
-#
-# Revision 1.6  2003/10/07 09:07:29  jalet
-# Character encoding added to please latest version of Python
-#
-# Revision 1.5  2003/07/07 11:49:24  jalet
-# Lots of small fixes with the help of PyChecker
-#
-# Revision 1.4  2003/06/25 14:10:01  jalet
-# Hey, it may work (edpykota --reset excepted) !
-#
-# Revision 1.3  2003/05/06 14:55:47  jalet
-# Missing import !
-#
-# Revision 1.2  2003/04/30 13:36:40  jalet
-# Stupid accounting method was added.
-#
-# Revision 1.1  2003/04/29 18:37:54  jalet
-# Pluggable accounting methods (actually doesn't support external scripts)
-#
-#
-#
-
-import sys
-import os
-import time
-from pykota.accounter import AccounterBase, PyKotaAccounterError
-from pykota.requester import openRequester, PyKotaRequesterError
-
-MAXTRIES = 12    # maximum number of tries to get the printer's internal page counter
-TIMETOSLEEP = 10 # number of seconds to sleep between two tries to get the printer's internal page counter
-
-class Accounter(AccounterBase) :
-    def __init__(self, kotabackend, arguments) :
-        """Initializes querying accounter."""
-        AccounterBase.__init__(self, kotabackend, arguments)
-        self.requester = openRequester(kotabackend, kotabackend.printername)
-        self.isDelayed = 1 # With the pykota filter, accounting is delayed by one job
-        
-    def getPrinterInternalPageCounter(self) :    
-        """Returns the printer's internal page counter."""
-        global MAXTRIES, TIMETOSLEEP
-        self.filter.logdebug("Reading printer's internal page counter...")
-        for dummy in range(MAXTRIES) :
-            try :
-                counter = self.requester.getPrinterPageCounter(self.filter.printerhostname)
-            except PyKotaRequesterError, msg :
-                # can't get actual page counter, assume printer is off or warming up
-                # log the message anyway.
-                self.filter.logger.log_message("%s" % msg, "warn")
-                counter = None
-            else :    
-                # printer answered, it is on so we can exit the loop
-                break
-            time.sleep(TIMETOSLEEP)    
-        self.filter.logdebug("Printer's internal page counter value is : %s" % str(counter))
-        return counter    
-        
-    def beginJob(self, userpquota) :    
-        """Saves printer internal page counter at start of job."""
-        # save page counter before job
-        self.LastPageCounter = self.counterbefore = self.getPrinterInternalPageCounter()
-        
-    def endJob(self, userpquota) :    
-        """Saves printer internal page counter at end of job."""
-        # save page counter after job
-        self.LastPageCounter = self.counterafter = self.getPrinterInternalPageCounter()
-        
-    def getJobSize(self) :    
-        """Returns the actual job size."""
-        try :
-            jobsize = (self.counterafter - self.counterbefore)    
-            if jobsize < 0 :
-                # Try to take care of HP printers 
-                # Their internal page counter is saved to NVRAM
-                # only every 10 pages. If the printer was switched
-                # off then back on during the job, and that the
-                # counters difference is negative, we know 
-                # the formula (we can't know if more than eleven
-                # pages were printed though) :
-                if jobsize > -10 :
-                    jobsize += 10
-                else :    
-                    # here we may have got a printer being replaced
-                    # DURING the job. This is HIGHLY improbable !
-                    jobsize = 0
-        except :    
-            # takes care of the case where one counter (or both) was never set.
-            jobsize = 0
-        return jobsize
-        
-    def doAccounting(self, userpquota) :
-        """Does print accounting and returns if the job status is ALLOW or DENY."""
-        # Get the page counter directly from the printer itself
-        counterbeforejob = self.getPrinterInternalPageCounter() or 0
-        
-        # Is the current user allowed to print at all ?
-        action = self.filter.warnUserPQuota(userpquota)
-        
-        # adds the current job to history    
-        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)
-        return action
-            
