Index: pykota/trunk/pykota/accounters/stupid.py
===================================================================
--- pykota/trunk/pykota/accounters/stupid.py (revision 1144)
+++ pykota/trunk/pykota/accounters/stupid.py (revision 1180)
@@ -22,4 +22,7 @@
 #
 # $Log$
+# 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
@@ -46,4 +49,29 @@
 
 class Accounter(AccounterBase) :
+    def beginJob(self) :    
+        """Saves the computed job size."""
+        self.JobSize = self.computeJobSize()
+        
+        # get last job information for this printer
+        if not printer.LastJob.Exists :
+            # The printer hasn't been used yet, from PyKota's point of view
+            self.LastPageCounter = 0
+        else :    
+            # get last job size and page counter from Quota Storage
+            # Last lifetime page counter before actual job is 
+            # last page counter + last job size
+            self.LastPageCounter = int(printer.LastJob.PrinterPageCounter or 0) + int(printer.LastJob.JobSize or 0)
+        
+    def endJob(self) :    
+        """Do nothing."""
+        pass
+        
+    def getJobSize(self) :    
+        """Returns the actual job size."""
+        try :
+            return self.JobSize
+        except AttributeError :    
+            return 0
+        
     def doAccounting(self, printer, user) :
         """Does print accounting by stupidly counting the 'showpage' postscript instructions in the document.
@@ -55,5 +83,5 @@
         
         # get the job size    
-        jobsize = self.getJobSize() * self.filter.copies
+        jobsize = self.computeJobSize() * self.filter.copies
             
         # get last job information for this printer
@@ -82,5 +110,5 @@
         return action
         
-    def getJobSize(self) :    
+    def computeJobSize(self) :    
         """Computes the job size and return its value.
         
Index: pykota/trunk/pykota/accounters/external.py
===================================================================
--- pykota/trunk/pykota/accounters/external.py (revision 1144)
+++ pykota/trunk/pykota/accounters/external.py (revision 1180)
@@ -22,4 +22,7 @@
 #
 # $Log$
+# 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
@@ -54,4 +57,30 @@
 
 class Accounter(AccounterBase) :
+    def beginJob(self, printer, user) :    
+        """Saves the computed job size."""
+        # computes job's size
+        self.JobSize = self.computeJobSize()
+        
+        # get last job information for this printer
+        if not printer.LastJob.Exists :
+            # The printer hasn't been used yet, from PyKota's point of view
+            self.LastPageCounter = 0
+        else :    
+            # get last job size and page counter from Quota Storage
+            # Last lifetime page counter before actual job is 
+            # last page counter + last job size
+            self.LastPageCounter = int(printer.LastJob.PrinterPageCounter or 0) + int(printer.LastJob.JobSize or 0)
+        
+    def endJob(self, printer, user) :    
+        """Do nothing."""
+        pass
+        
+    def getJobSize(self) :    
+        """Returns the actual job size."""
+        try :
+            return self.JobSize
+        except AttributeError :    
+            return 0
+        
     def doAccounting(self, printer, user) :
         """Deletgates the computation of the job size to an external command.
@@ -59,16 +88,8 @@
            The command must print the job size on its standard output and exit successfully.
         """
+        self.beginJob(printer, user)
+        
         # get the job size, which is real job size * number of copies.
         jobsize = self.getJobSize() * self.filter.copies
-            
-        # get last job information for this printer
-        if not printer.LastJob.Exists :
-            # The printer hasn't been used yet, from PyKota's point of view
-            counterbeforejob = 0
-        else :    
-            # get last job size and page counter from Quota Storage
-            # Last lifetime page counter before actual job is 
-            # last page counter + last job size
-            counterbeforejob = int(printer.LastJob.PrinterPageCounter or 0) + int(printer.LastJob.JobSize or 0)
             
         # Is the current user allowed to print at all ?
@@ -83,9 +104,11 @@
         
         # adds the current job to history    
-        printer.addJobToHistory(self.filter.jobid, user, counterbeforejob, action, jobsize)
+        printer.addJobToHistory(self.filter.jobid, user, self.getLastPageCounter(), action, jobsize)
+        
+        self.endJob(printer, user)
             
         return action
         
-    def getJobSize(self) :    
+    def computeJobSize(self) :    
         """Feeds an external command with our datas to let it compute the job size, and return its value."""
         temporary = None    
Index: pykota/trunk/pykota/accounters/querying.py
===================================================================
--- pykota/trunk/pykota/accounters/querying.py (revision 1144)
+++ pykota/trunk/pykota/accounters/querying.py (revision 1180)
@@ -22,4 +22,7 @@
 #
 # $Log$
+# 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
@@ -44,4 +47,5 @@
 
 import sys
+import os
 import time
 from pykota.accounter import AccounterBase, PyKotaAccounterError
@@ -52,4 +56,59 @@
 
 class Accounter(AccounterBase) :
+    def __init__(self, kotabackend, arguments) :
+        """Initializes querying accounter."""
+        AccounterBase.__init__(self, kotabackend, arguments)
+        self.requester = openRequester(kotabackend.config, kotabackend.printername)
+        
+    def getPrinterInternalPageCounter(self) :    
+        """Returns the printer's internal page counter."""
+        global MAXTRIES, TIMETOSLEEP
+        for i 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)    
+        return counter    
+        
+    def beginJob(self, printer, user) :    
+        """Saves printer internal page counter at start of job."""
+        # save page counter before job
+        self.LastPageCounter = self.counterbefore = self.getPrinterInternalPageCounter()
+        
+    def endJob(self, printer, user) :    
+        """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, printer, user) :
         """Does print accounting and returns if the job status is ALLOW or DENY."""
@@ -57,20 +116,5 @@
         # Tries MAXTRIES times, sleeping two seconds each time, in case the printer is sleeping.
         # This was seen with my Apple LaserWriter 16/600 PS which doesn't answer before having warmed up.
-        global MAXTRIES, TIMETOSLEEP
-        requester = openRequester(self.filter.config, self.filter.printername)
-        for i in range(MAXTRIES) :
-            try :
-                counterbeforejob = 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")
-                counterbeforejob = None
-                printerIsOff = 1
-            else :    
-                # printer answered, it is on so we can exit the loop
-                printerIsOff = 0
-                break
-            time.sleep(TIMETOSLEEP)    
+        counterbeforejob = self.getPrinterInternalPageCounter()
         
         # get last job information for this printer
@@ -85,5 +129,5 @@
             
         # if printer is off then we assume the correct counter value is the last one
-        if printerIsOff :
+        if counterbeforejob is None :
             counterbeforejob = lastpagecounter
             
