Changeset 1271 for pykota/trunk/pykota

Show
Ignore:
Timestamp:
01/12/04 00:22:42 (20 years ago)
Author:
jalet
Message:

Major code refactoring, it's way cleaner, and now allows automated addition
of printers on first print.

Location:
pykota/trunk/pykota
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/pykota/accounter.py

    r1257 r1271  
    2222# 
    2323# $Log$ 
     24# Revision 1.11  2004/01/11 23:22:42  jalet 
     25# Major code refactoring, it's way cleaner, and now allows automated addition 
     26# of printers on first print. 
     27# 
    2428# Revision 1.10  2004/01/08 14:10:32  jalet 
    2529# Copyright year changed. 
     
    6973        self.filter = kotafilter 
    7074        self.arguments = arguments 
     75        self.isDelayed = 0      # Accounting is immediate by default 
    7176         
    7277    def getLastPageCounter(self) :     
     
    7681        except :     
    7782            return 0 
    78          
    79     def filterInput(self, inputfile) : 
    80         """Transparent filter.""" 
    81         mustclose = 0     
    82         if inputfile is not None :     
    83             if hasattr(inputfile, "read") : 
    84                 infile = inputfile 
    85             else :     
    86                 infile = open(inputfile, "rb") 
    87             mustclose = 1 
    88         else :     
    89             infile = sys.stdin 
    90         data = infile.read(256*1024)     
    91         while data : 
    92             sys.stdout.write(data) 
    93             data = infile.read(256*1024) 
    94         if mustclose :     
    95             infile.close() 
    9683             
    97     def beginJob(self, printer, user) :     
     84    def beginJob(self, userpquota) :     
    9885        """Saves the computed job size.""" 
    9986        # computes job's size 
     
    10188         
    10289        # get last job information for this printer 
    103         if not printer.LastJob.Exists : 
     90        if not userpquota.Printer.LastJob.Exists : 
    10491            # The printer hasn't been used yet, from PyKota's point of view 
    10592            self.LastPageCounter = 0 
     
    10895            # Last lifetime page counter before actual job is  
    10996            # last page counter + last job size 
    110             self.LastPageCounter = int(printer.LastJob.PrinterPageCounter or 0) + int(printer.LastJob.JobSize or 0) 
     97            self.LastPageCounter = int(userpquota.Printer.LastJob.PrinterPageCounter or 0) + int(userpquota.Printer.LastJob.JobSize or 0) 
    11198         
    112     def endJob(self, printer, user) :     
     99    def endJob(self, userpquota) :     
    113100        """Do nothing.""" 
    114101        pass 
     
    121108            return 0 
    122109         
    123     def doAccounting(self, printer, user) : 
    124         """Deletgates the computation of the job size to an external command. 
     110    def doAccounting(self, userpquota) : 
     111        """Delegates the computation of the job size to an external command. 
    125112         
    126113           The command must print the job size on its standard output and exit successfully. 
    127114        """ 
    128         self.beginJob(printer, user) 
     115        self.beginJob(userpquota) 
    129116         
    130117        # get the job size, which is real job size * number of copies. 
     118        # TODO : Double check with CUPS documentation : this is not always correct 
    131119        jobsize = self.getJobSize() * self.filter.copies 
    132120             
    133121        # Is the current user allowed to print at all ? 
    134         userpquota = self.filter.storage.getUserPQuota(user, printer) 
    135122        action = self.filter.warnUserPQuota(userpquota) 
    136123         
     
    142129         
    143130        # adds the current job to history     
    144         jobprice = (float(printer.PricePerPage or 0.0) * jobsize) + float(printer.PricePerJob or 0.0) 
    145         printer.addJobToHistory(self.filter.jobid, user, self.getLastPageCounter(), action, jobsize, jobprice, self.filter.preserveinputfile, self.filter.title, self.filter.copies, self.filter.options) 
    146         self.endJob(printer, user) 
     131        jobprice = (float(userpquota.Printer.PricePerPage or 0.0) * jobsize) + float(userpquota.Printer.PricePerJob or 0.0) 
     132        userpquota.Printer.addJobToHistory(self.filter.jobid, userpquota.User, self.getLastPageCounter(), action, jobsize, jobprice, self.filter.preserveinputfile, self.filter.title, self.filter.copies, self.filter.options) 
     133        self.endJob(userpquota) 
    147134        return action 
    148135         
  • pykota/trunk/pykota/accounters/querying.py

    r1257 r1271  
    2222# 
    2323# $Log$ 
     24# Revision 1.12  2004/01/11 23:22:42  jalet 
     25# Major code refactoring, it's way cleaner, and now allows automated addition 
     26# of printers on first print. 
     27# 
    2428# Revision 1.11  2004/01/08 14:10:32  jalet 
    2529# Copyright year changed. 
     
    6973        AccounterBase.__init__(self, kotabackend, arguments) 
    7074        self.requester = openRequester(kotabackend.config, kotabackend.printername) 
     75        self.isDelayed = 1 # With the pykota filter, accounting is delayed by one job 
    7176         
    7277    def getPrinterInternalPageCounter(self) :     
     
    8994        return counter     
    9095         
    91     def beginJob(self, printer, user) :     
     96    def beginJob(self, userpquota) :     
    9297        """Saves printer internal page counter at start of job.""" 
    9398        # save page counter before job 
    9499        self.LastPageCounter = self.counterbefore = self.getPrinterInternalPageCounter() 
    95100         
    96     def endJob(self, printer, user) :     
     101    def endJob(self, userpquota) :     
    97102        """Saves printer internal page counter at end of job.""" 
    98103        # save page counter after job 
     
    122127        return jobsize 
    123128         
    124     def doAccounting(self, printer, user) : 
     129    def doAccounting(self, userpquota) : 
    125130        """Does print accounting and returns if the job status is ALLOW or DENY.""" 
    126131        # Get the page counter directly from the printer itself 
    127         # Tries MAXTRIES times, sleeping two seconds each time, in case the printer is sleeping. 
    128         # This was seen with my Apple LaserWriter 16/600 PS which doesn't answer before having warmed up. 
    129         counterbeforejob = self.getPrinterInternalPageCounter() 
     132        counterbeforejob = self.getPrinterInternalPageCounter() or 0 
    130133         
    131         # get last job information for this printer 
    132         if not printer.LastJob.Exists : 
    133             # The printer hasn't been used yet, from PyKota's point of view 
    134             lastuser = user 
    135             lastpagecounter = counterbeforejob 
    136         else :     
    137             # get last values from Quota Storage 
    138             lastuser = printer.LastJob.User 
    139             lastpagecounter = printer.LastJob.PrinterPageCounter 
    140              
    141         # if printer is off then we assume the correct counter value is the last one 
    142         if counterbeforejob is None : 
    143             counterbeforejob = lastpagecounter 
    144              
    145         # if the internal lifetime page counter for this printer is 0     
    146         # then this may be a printer with a volatile counter (never 
    147         # saved to NVRAM) which has just been switched off and then on 
    148         # so we use the last page counter from the Quota Storage instead 
    149         # explanation at : http://web.mit.edu/source/third/lprng/doc/LPRng-HOWTO-15.html 
    150         if counterbeforejob == 0 : 
    151             counterbeforejob = lastpagecounter 
    152              
    153         # Computes the last job size as the difference between internal page 
    154         # counter in the printer and last page counter taken from the Quota 
    155         # Storage database for this particular printer 
    156         try : 
    157             jobsize = (counterbeforejob - lastpagecounter)     
    158         except TypeError :     
    159             # never used, and internal page counter not accessible 
    160             jobsize = 0 
    161              
    162         if jobsize < 0 : 
    163             # Probably an HP printer which was switched off and back on,  
    164             # its primary counter is only saved in a 10 increment, so 
    165             # it may be lower than the last page counter saved in the 
    166             # Quota Storage.  
    167             # We unconditionnally set the last job's size to  
    168             # abs(int((10 - abs(lastcounter(snmp) - lastcounter(storage)) / 2)) 
    169             # For more accurate accounting, don't switch off your HP printers ! 
    170             # explanation at : http://web.mit.edu/source/third/lprng/doc/LPRng-HOWTO-15.html 
    171             self.filter.logger.log_message(_("Error in page count value %i for user %s on printer %s") % (jobsize, lastuser.Name, self.filter.printername), "error") 
    172             jobsize = abs(int((10 - abs(jobsize)) / 2))     # Workaround for HP printers' feature ! 
    173              
    174         # update the quota for the previous user on this printer  
    175         lastuserquota = self.filter.storage.getUserPQuota(lastuser, printer) 
    176         if lastuserquota.Exists : 
    177             lastuserquota.increasePagesUsage(jobsize) 
    178          
    179         # update the last job size in the history 
    180         if printer.LastJob.Exists : 
    181             printer.LastJob.setSize(jobsize) 
    182          
    183         # warns the last user if he is over quota 
    184         if lastuserquota.Exists : 
    185             self.filter.warnUserPQuota(lastuserquota) 
    186              
    187134        # Is the current user allowed to print at all ? 
    188         action = self.filter.warnUserPQuota(self.filter.storage.getUserPQuota(user, printer)) 
     135        action = self.filter.warnUserPQuota(userpquota) 
    189136         
    190137        # adds the current job to history     
    191         printer.addJobToHistory(self.filter.jobid, user, counterbeforejob, action, filename=self.filter.preserveinputfile, title=self.filter.title, copies=self.filter.copies, options=self.filter.options) 
     138        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) 
    192139        return action 
    193140             
  • pykota/trunk/pykota/tool.py

    r1257 r1271  
    2222# 
    2323# $Log$ 
     24# Revision 1.71  2004/01/11 23:22:42  jalet 
     25# Major code refactoring, it's way cleaner, and now allows automated addition 
     26# of printers on first print. 
     27# 
    2428# Revision 1.70  2004/01/08 14:10:32  jalet 
    2529# Copyright year changed. 
     
    775779                    self.logger.log_message(_("User %s doesn't have quota on printer %s in the PyKota system, applying external policy (%s) for printer %s") % (self.username, self.printername, commandline, self.printername), "info") 
    776780                if os.system(commandline) : 
    777                     # if an error occured, we die without error, 
    778                     # so that the job doesn't stop the print queue. 
    779781                    self.logger.log_message(_("External policy %s for printer %s produced an error. Job rejected. Please check PyKota's configuration files.") % (commandline, self.printername), "error") 
    780782                    policy = "EXTERNALERROR" 
    781783                    break 
    782784            else :         
     785                if not printer.Exists : 
     786                    self.logger.log_message(_("Printer %s not registered in the PyKota system, applying default policy (%s)") % (self.printername, policy), "info") 
     787                if not user.Exists : 
     788                    self.logger.log_message(_("User %s not registered in the PyKota system, applying default policy (%s) for printer %s") % (self.username, policy, self.printername), "info") 
     789                if not userpquota.Exists : 
     790                    self.logger.log_message(_("User %s doesn't have quota on printer %s in the PyKota system, applying default policy (%s)") % (self.username, self.printername, policy), "info") 
    783791                break 
     792        if policy == "EXTERNAL" :     
     793            if not printer.Exists : 
     794                self.logger.log_message(_("Printer %s still not registered in the PyKota system, job will be rejected") % self.printername, "info") 
     795            if not user.Exists : 
     796                self.logger.log_message(_("User %s still not registered in the PyKota system, job will be rejected on printer %s") % (self.username, self.printername), "info") 
     797            if not userpquota.Exists : 
     798                self.logger.log_message(_("User %s still doesn't have quota on printer %s in the PyKota system, job will be rejected") % (self.username, self.printername), "info") 
    784799        return (policy, printer, user, userpquota) 
    785800         
    786     def main(self) :     
     801    def mainWork(self) :     
    787802        """Main work is done here.""" 
    788803        (policy, printer, user, userpquota) = self.getPrinterUserAndUserPQuota() 
     804        # TODO : check for last user's quota in case pykota filter is used with querying 
    789805        if policy == "EXTERNALERROR" : 
    790806            # Policy was 'EXTERNAL' and the external command returned an error code 
    791             pass # TODO : reject job 
     807            return self.removeJob() 
    792808        elif policy == "EXTERNAL" : 
    793809            # Policy was 'EXTERNAL' and the external command wasn't able 
    794810            # to add either the printer, user or user print quota 
    795             pass # TODO : reject job 
    796         elif policy == "ALLOW": 
    797             # Either printer, user or user print quota doesn't exist, 
    798             # but the job should be allowed anyway. 
    799             pass # TODO : accept job 
    800         elif policy == "OK" : 
    801             # Both printer, user and user print quota exist, job should 
    802             # be allowed if current user is allowed to print on this 
    803             # printer 
    804             pass # TODO : decide what to do based on user quota. 
    805         else : # DENY 
     811            return self.removeJob() 
     812        elif policy == "DENY" :     
    806813            # Either printer, user or user print quota doesn't exist, 
    807814            # and the job should be rejected. 
    808             pass # TODO : reject job 
     815            return self.removeJob() 
     816        else : 
     817            if policy not in ("OK", "ALLOW") : 
     818                self.logger.log_message(_("Invalid policy %s for printer %s") % (policy, self.printername)) 
     819                return self.removeJob() 
     820            else : 
     821                return self.doWork(policy, printer, user, userpquota) 
  • pykota/trunk/pykota/version.py

    r1269 r1271  
    2222# 
    2323 
    24 __version__ = "1.16alpha23_unofficial" 
     24__version__ = "1.16alpha24_unofficial" 
    2525 
    2626__doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""