Changeset 2692 for pykota/trunk

Show
Ignore:
Timestamp:
02/14/06 16:18:45 (19 years ago)
Author:
jerome
Message:

Added the 'duplicatesdelay' and 'balancezero' directives.

Location:
pykota/trunk
Files:
9 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/cupspykota

    r2687 r2692  
    4040from email.MIMEText import MIMEText 
    4141from email.Header import Header 
     42 
     43from mx import DateTime 
    4244 
    4345from pykota.tool import PyKotaTool, PyKotaToolError, crashed 
     
    768770        if not denyduplicates : 
    769771            self.logdebug("We don't care about duplicate jobs after all.") 
    770         elif self.Printer.LastJob.Exists \ 
    771              and (self.Printer.LastJob.UserName == self.UserName) \ 
    772              and (self.Printer.LastJob.JobMD5Sum == self.JobMD5Sum) : 
    773             # TODO : use the current user's last job instead of   
    774             # TODO : the current printer's last job. This would be 
    775             # TODO : better but requires an additional database query 
    776             # TODO : with SQL, and is much more complex with the  
    777             # TODO : actual LDAP schema. Maybe this is not very 
    778             # TODO : important, because usually duplicate jobs are sucessive. 
    779             msg = _("Job is a dupe") 
    780             if denyduplicates == 1 : 
    781                 self.printInfo("%s : %s." % (msg, _("Printing is denied by configuration")), "warn") 
    782                 self.Action = "DENY" 
    783                 self.Reason = _("Duplicate print jobs are not allowed on printer %s.") % self.PrinterName 
    784             else :     
    785                 self.logdebug("Launching subprocess [%s] to see if duplicate jobs should be allowed or not." % denyduplicates) 
    786                 fanswer = os.popen(denyduplicates, "r") 
    787                 self.Action = fanswer.read().strip().upper() 
    788                 fanswer.close() 
    789                 if self.Action == "DENY" :      
    790                     self.printInfo("%s : %s." % (msg, _("Subprocess denied printing of a dupe")), "warn") 
    791                     self.Reason = _("Duplicate print jobs are not allowed on printer %s at this time.") % self.PrinterName 
    792                 else :     
    793                     self.printInfo("%s : %s." % (msg, _("Subprocess allowed printing of a dupe")), "warn") 
    794         else :             
    795             self.logdebug("Job doesn't seem to be a duplicate.") 
     772        else : 
     773            if self.Printer.LastJob.Exists \ 
     774                    and (self.Printer.LastJob.UserName == self.UserName) \ 
     775                    and (self.Printer.LastJob.JobMD5Sum == self.JobMD5Sum) : 
     776                now = DateTime.now() 
     777                try : 
     778                    previous = DateTime.ISO.ParseDateTime(self.Printer.LastJob.JobDate).localtime() 
     779                except : 
     780                    previous = now 
     781                difference = (now - previous).seconds 
     782                duplicatesdelay = self.config.getDuplicatesDelay(self.PrinterName) 
     783                self.logdebug("Difference with previous job : %.2f seconds. Duplicates delay : %.2f seconds." % (difference, duplicatesdelay)) 
     784                if difference > duplicatesdelay : 
     785                    self.logdebug("Duplicate job allowed because previous one is more than %.2f seconds old." % duplicatesdelay) 
     786                else : 
     787                    # TODO : use the current user's last job instead of   
     788                    # TODO : the current printer's last job. This would be 
     789                    # TODO : better but requires an additional database query 
     790                    # TODO : with SQL, and is much more complex with the  
     791                    # TODO : actual LDAP schema. Maybe this is not very 
     792                    # TODO : important, because usually duplicate jobs are sucessive. 
     793                    msg = _("Job is a dupe") 
     794                    if denyduplicates == 1 : 
     795                        self.printInfo("%s : %s." % (msg, _("Printing is denied by configuration")), "warn") 
     796                        self.Action = "DENY" 
     797                        self.Reason = _("Duplicate print jobs are not allowed on printer %s.") % self.PrinterName 
     798                    else :     
     799                        self.logdebug("Launching subprocess [%s] to see if duplicate jobs should be allowed or not." % denyduplicates) 
     800                        fanswer = os.popen(denyduplicates, "r") 
     801                        self.Action = fanswer.read().strip().upper() 
     802                        fanswer.close() 
     803                        if self.Action == "DENY" :      
     804                            self.printInfo("%s : %s." % (msg, _("Subprocess denied printing of a dupe")), "warn") 
     805                            self.Reason = _("Duplicate print jobs are not allowed on printer %s at this time.") % self.PrinterName 
     806                        else :     
     807                            self.printInfo("%s : %s." % (msg, _("Subprocess allowed printing of a dupe")), "warn") 
     808            else :             
     809                self.logdebug("Job doesn't seem to be a duplicate.") 
    796810        self.logdebug("Checking if the job is a duplicate done.") 
    797811         
  • pykota/trunk/bin/pykosd

    r2622 r2692  
    112112        while 1 : 
    113113            color = savecolor 
    114             user = cmd.storage.getUserFromBackend(uname)        # don't use cache 
     114            user = self.storage.getUserFromBackend(uname)        # don't use cache 
    115115            if not user.Exists : 
    116116                raise PyKotaCommandLineError, _("User %s doesn't exist in PyKota's database") % uname 
    117117            if user.LimitBy == "quota" :     
    118                 printers = cmd.storage.getMatchingPrinters("*") 
    119                 upquotas = [ cmd.storage.getUserPQuotaFromBackend(user, p) for p in printers ] # don't use cache 
     118                printers = self.storage.getMatchingPrinters("*") 
     119                upquotas = [ self.storage.getUserPQuotaFromBackend(user, p) for p in printers ] # don't use cache 
    120120                nblines = len(upquotas) 
    121121                display = pyosd.osd(font=options["font"], colour=color, timeout=duration, shadow=2, lines=nblines) 
     
    131131                    display.display(_("Pages used on %s : %s") % (upq.Printer.Name, percent), type=pyosd.TYPE_STRING, line=line) 
    132132            elif user.LimitBy == "balance" : 
    133                 if user.AccountBalance <= 0 : 
     133                if user.AccountBalance <= self.config.getBalanceZero() : 
    134134                    color = "#FF0000" 
    135135                display = pyosd.osd(font=options["font"], colour=color, timeout=duration, shadow=2) 
  • pykota/trunk/bin/warnpykota

    r2622 r2692  
    118118                    # we only want to warn users who have ever printed something 
    119119                    # and don't want to warn users who have never printed 
    120                     if (user.AccountBalance and (user.AccountBalance != user.LifeTimePaid)) or \ 
     120                    if ((user.AccountBalance > self.config.getBalanceZero()) and \ 
     121                       (user.AccountBalance != user.LifeTimePaid)) or \ 
    121122                       userpquota.PageCounter or userpquota.LifePageCounter or \ 
    122123                       self.storage.getUserNbJobsFromHistory(user) : 
  • pykota/trunk/conf/pykota.conf.sample

    r2681 r2692  
    681681# This option can only appear in the global section 
    682682poorman: 2.0 
     683 
     684# The value of the zero for account balance limitations. 
     685# If an user his limited by balance, he can print until 
     686# his balance reaches the value defined here. If unset, 
     687# the default value is 0. Any floating point value 
     688# is accepted. 
     689# 
     690# This option can only appear in the global section 
     691# balancezero : -0.25 
     692balancezero: 0.0 
    683693 
    684694# Poor man's warning message 
     
    10031013denyduplicates : no 
    10041014 
     1015# Sets the delay in seconds after which two identical jobs are  
     1016# not considered as being a duplicate. 
     1017#  
     1018# This can be defined either globally or on a per printer basis 
     1019# The default value if not set is 0, for 0 seconds. 
     1020# duplicatesdelay : 300 
     1021duplicatesdelay : 0 
     1022 
  • pykota/trunk/NEWS

    r2686 r2692  
    2222PyKota NEWS : 
    2323        
     24    - 1.24alpha12 : 
     25     
     26        - Introduced the 'duplicatesdelay' directive to specify after 
     27          which duration two duplicate jobs are not considered duplicate 
     28          jobs anymore. 
     29           
     30        - Introduced the 'balancezero' directive to specify any value   
     31          as the balance limit instead of 0.0. This can allow admins to 
     32          give a few free credits to users, for example. 
     33           
    2434    - 1.24alpha11 : 
    2535     
  • pykota/trunk/pykota/config.py

    r2635 r2692  
    439439            raise PyKotaConfigError, _("Invalid poor man's threshold %s") % pm 
    440440             
     441    def getBalanceZero(self) :     
     442        """Returns the value of the zero for balance limitation.""" 
     443        try : 
     444            bz = self.getGlobalOption("balancezero") 
     445        except PyKotaConfigError :     
     446            bz = 0.0    # default value, zero is 0.0 
     447        try : 
     448            return float(bz) 
     449        except (TypeError, ValueError) :     
     450            raise PyKotaConfigError, _("Invalid balancezero value %s") % bz 
     451             
    441452    def getPoorWarn(self) :     
    442453        """Returns the poor man's warning message.""" 
     
    516527                # it's a command to run. 
    517528                return denyduplicates 
     529                 
     530    def getDuplicatesDelay(self, printername) :           
     531        """Returns the number of seconds after which two identical jobs are not considered a duplicate anymore.""" 
     532        try :  
     533            duplicatesdelay = self.getPrinterOption(printername, "duplicatesdelay") 
     534        except PyKotaConfigError :     
     535            return 0 
     536        else :     
     537            try : 
     538                return int(duplicatesdelay) 
     539            except (TypeError, ValueError) : 
     540                raise PyKotaConfigError, _("Incorrect value %s for the duplicatesdelay directive in section %s") % (str(duplicatesdelay), printername) 
    518541         
    519542    def getWinbindSeparator(self) :           
  • pykota/trunk/pykota/reporter.py

    r2622 r2692  
    100100        else : 
    101101            if entry.LimitBy.lower() == "balance" : 
    102                 if balance == 0.0 : 
     102                balancezero = self.tool.config.getBalanceZero() 
     103                if balance == balancezero : 
    103104                    if entry.OverCharge > 0 : 
    104105                        datelimit = "DENY" 
     
    109110                        datelimit = "" 
    110111                        reached = "-B" 
    111                 elif balance < 0 : 
     112                elif balance < balancezero : 
    112113                    datelimit = "DENY" 
    113114                    reached = "+B" 
  • pykota/trunk/pykota/tool.py

    r2657 r2692  
    458458            if enforcement == "STRICT" :  
    459459                val -= self.softwareJobPrice # use precomputed size. 
    460             if val <= 0.0 : 
     460            balancezero = self.config.getBalanceZero() 
     461            if val <= balancezero : 
    461462                action = "DENY" 
    462463            elif val <= self.config.getPoorMan() :     
     
    464465            else :     
    465466                action = "ALLOW" 
    466             if (enforcement == "STRICT") and (val == 0.0) : 
     467            if (enforcement == "STRICT") and (val == balancezero) : 
    467468                action = "WARN" # we can still print until account is 0 
    468469        else : 
     
    549550                    if enforcement == "STRICT" :  
    550551                        val -= self.softwareJobPrice # use precomputed size. 
    551                     if val <= 0.0 : 
     552                    balancezero = self.config.getBalanceZero()     
     553                    if val <= balancezero : 
    552554                        action = "DENY" 
    553555                    elif val <= self.config.getPoorMan() :     
     
    555557                    else : 
    556558                        action = "ALLOW" 
    557                     if (enforcement == "STRICT") and (val == 0.0) : 
     559                    if (enforcement == "STRICT") and (val == balancezero) : 
    558560                        action = "WARN" # we can still print until account is 0 
    559561                return action     
  • pykota/trunk/pykota/version.py

    r2668 r2692  
    2222# 
    2323 
    24 __version__ = "1.24alpha11_unofficial" 
     24__version__ = "1.24alpha12_unofficial" 
    2525 
    2626__doc__ = "PyKota : a complete Printing Quota Solution for CUPS."