Changeset 927 for pykota/trunk/pykota

Show
Ignore:
Timestamp:
04/16/03 14:35:49 (21 years ago)
Author:
jalet
Message:

Groups quota work now !

Location:
pykota/trunk/pykota
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/pykota/storages/sql.py

    r925 r927  
    2121# 
    2222# $Log$ 
     23# Revision 1.27  2003/04/16 12:35:49  jalet 
     24# Groups quota work now ! 
     25# 
    2326# Revision 1.26  2003/04/16 08:53:14  jalet 
    2427# Printing can now be limited either by user's account balance or by 
     
    196199            return [(record["id"], record["groupname"]) for record in result] 
    197200         
     201    def getGroupMembersNames(self, groupname) :         
     202        """Returns the list of user's names which are member of this group.""" 
     203        groupid = self.getGroupId(groupname) 
     204        if groupid is None : 
     205            return [] 
     206        else : 
     207            result = self.doQuery("SELECT DISTINCT username FROM users WHERE id IN (SELECT userid FROM groupsmembers WHERE groupid=%s)" % self.doQuote(groupid)) 
     208            return [record["username"] for record in (self.doParseResult(result) or [])] 
     209         
     210    def getUserGroupsNames(self, userid) :         
     211        """Returns the list of groups' names the user is a member of.""" 
     212        result = self.doQuery("SELECT DISTINCT groupname FROM groups WHERE id IN (SELECT groupid FROM groupsmembers WHERE userid=%s)" % self.doQuote(userid)) 
     213        return [record["groupname"] for record in (self.doParseResult(result) or [])] 
     214         
    198215    def addPrinter(self, printername) :         
    199216        """Adds a printer to the quota storage, returns its id.""" 
     
    216233        if userid is None :     
    217234            userid = self.addUser(username) 
    218         self.doQuery("INSERT INTO userpquota (userid, printerid) VALUES (%s, %s)" % (self.doQuote(userid), self.doQuote(printerid))) 
     235        uqexists = (self.getUserPQuota(userid, printerid) is not None)     
     236        if not uqexists :  
     237            self.doQuery("INSERT INTO userpquota (userid, printerid) VALUES (%s, %s)" % (self.doQuote(userid), self.doQuote(printerid))) 
    219238        return (userid, printerid) 
    220239         
     
    223242        groupid = self.getGroupId(groupname)      
    224243        if groupid is None :     
    225             groupid = self.addUser(groupname) 
    226         self.doQuery("INSERT INTO grouppquota (groupid, printerid) VALUES (%s, %s)" % (self.doQuote(groupid), self.doQuote(printerid))) 
     244            groupid = self.addGroup(groupname) 
     245        gqexists = (self.getGroupPQuota(groupid, printerid) is not None)     
     246        if not gqexists :  
     247            self.doQuery("INSERT INTO grouppquota (groupid, printerid) VALUES (%s, %s)" % (self.doQuote(groupid), self.doQuote(printerid))) 
    227248        return (groupid, printerid) 
    228249         
     
    234255        """Returns the current account balance for a given user.""" 
    235256        result = self.doQuery("SELECT balance FROM users WHERE id=%s" % self.doQuote(userid)) 
     257        try : 
     258            return self.doParseResult(result)[0]["balance"] 
     259        except TypeError :      # Not found     
     260            return 
     261         
     262    def getGroupBalance(self, groupid) :     
     263        """Returns the current account balance for a given group, as the sum of each of its users' account balance.""" 
     264        result = self.doQuery("SELECT SUM(balance) AS balance FROM users WHERE id in (SELECT userid FROM groupsmembers WHERE groupid=%s)" % self.doQuote(groupid)) 
    236265        try : 
    237266            return self.doParseResult(result)[0]["balance"] 
     
    273302        self.doQuery("UPDATE userpquota SET softlimit=%s, hardlimit=%s, datelimit=NULL WHERE userid=%s AND printerid=%s" % (self.doQuote(softlimit), self.doQuote(hardlimit), self.doQuote(userid), self.doQuote(printerid))) 
    274303         
     304    def setGroupPQuota(self, groupid, printerid, softlimit, hardlimit) : 
     305        """Sets soft and hard limits for a group quota on a specific printer given (groupid, printerid).""" 
     306        self.doQuery("UPDATE grouppquota SET softlimit=%s, hardlimit=%s, datelimit=NULL WHERE groupid=%s AND printerid=%s" % (self.doQuote(softlimit), self.doQuote(hardlimit), self.doQuote(groupid), self.doQuote(printerid))) 
     307         
    275308    def resetUserPQuota(self, userid, printerid) :     
    276309        """Resets the page counter to zero for a user on a printer. Life time page counter is kept unchanged.""" 
    277310        self.doQuery("UPDATE userpquota SET pagecounter=0, datelimit=NULL WHERE userid=%s AND printerid=%s" % (self.doQuote(userid), self.doQuote(printerid))) 
     311         
     312    def resetGroupPQuota(self, groupid, printerid) :     
     313        """Resets the page counter to zero for a group on a printer. Life time page counter is kept unchanged.""" 
     314        self.doQuery("UPDATE grouppquota SET pagecounter=0, datelimit=NULL WHERE groupid=%s AND printerid=%s" % (self.doQuote(groupid), self.doQuote(printerid))) 
    278315         
    279316    def updateUserPQuota(self, userid, printerid, pagecount) : 
     
    293330            return 
    294331         
     332    def getGroupPQuota(self, groupid, printerid) : 
     333        """Returns the Print Quota information for a given (groupid, printerid).""" 
     334        result = self.doQuery("SELECT softlimit, hardlimit, datelimit FROM grouppquota WHERE groupid=%s AND printerid=%s" % (self.doQuote(groupid), self.doQuote(printerid))) 
     335        try : 
     336            grouppquota = self.doParseResult(result)[0] 
     337        except TypeError :     
     338            return 
     339        else :     
     340            result = self.doQuery("SELECT SUM(lifepagecounter) as lifepagecounter, SUM(pagecounter) as pagecounter FROM userpquota WHERE printerid=%s AND userid in (SELECT userid FROM groupsmembers WHERE groupid=%s)" % (self.doQuote(printerid), self.doQuote(groupid))) 
     341            try : 
     342                result = self.doParseResult(result)[0] 
     343            except TypeError :      # Not found     
     344                return 
     345            else :     
     346                grouppquota.update({"lifepagecounter": result["lifepagecounter"], "pagecounter": result["pagecounter"]}) 
     347                return grouppquota 
     348         
    295349    def setUserDateLimit(self, userid, printerid, datelimit) : 
    296350        """Sets the limit date for a soft limit to become an hard one given (userid, printerid).""" 
    297351        self.doQuery("UPDATE userpquota SET datelimit=%s::TIMESTAMP WHERE userid=%s AND printerid=%s" % (self.doQuote("%04i-%02i-%02i %02i:%02i:%02i" % (datelimit.year, datelimit.month, datelimit.day, datelimit.hour, datelimit.minute, datelimit.second)), self.doQuote(userid), self.doQuote(printerid))) 
     352         
     353    def setGroupDateLimit(self, groupid, printerid, datelimit) : 
     354        """Sets the limit date for a soft limit to become an hard one given (groupid, printerid).""" 
     355        self.doQuery("UPDATE grouppquota SET datelimit=%s::TIMESTAMP WHERE groupid=%s AND printerid=%s" % (self.doQuote("%04i-%02i-%02i %02i:%02i:%02i" % (datelimit.year, datelimit.month, datelimit.day, datelimit.hour, datelimit.minute, datelimit.second)), self.doQuote(groupid), self.doQuote(printerid))) 
    298356         
    299357    def addJobToHistory(self, jobid, userid, printerid, pagecounter, action) : 
     
    314372            return 
    315373         
     374    def addUserToGroup(self, userid, groupid) :     
     375        """Adds an user to a group.""" 
     376        result = self.doQuery("SELECT COUNT(*) AS mexists FROM groupsmembers WHERE groupid=%s AND userid=%s" % (self.doQuote(groupid), self.doQuote(userid))) 
     377        try : 
     378            mexists = self.doParseResult(result)[0]["mexists"] 
     379        except TypeError :     
     380            mexists = 0 
     381        if not mexists :     
     382            self.doQuery("INSERT INTO groupsmembers (groupid, userid) VALUES (%s, %s)" % (self.doQuote(groupid), self.doQuote(userid))) 
     383         
    316384    def deleteUser(self, userid) :     
    317385        """Completely deletes an user from the Quota Storage.""" 
  • pykota/trunk/pykota/tool.py

    r925 r927  
    2121# 
    2222# $Log$ 
     23# Revision 1.33  2003/04/16 12:35:49  jalet 
     24# Groups quota work now ! 
     25# 
    2326# Revision 1.32  2003/04/16 08:53:14  jalet 
    2427# Printing can now be limited either by user's account balance or by 
     
    287290        self.sendMessage(adminmail, adminmail, "Subject: %s\n\n%s" % (subject, message)) 
    288291         
     292    def checkGroupPQuota(self, groupname, printername) :     
     293        """Checks the group quota on a printer and deny or accept the job.""" 
     294        printerid = self.storage.getPrinterId(printername) 
     295        groupid = self.storage.getGroupId(groupname) 
     296        limitby = self.storage.getGroupLimitBy(groupid) 
     297        if limitby == "balance" :  
     298            balance = self.storage.getGroupBalance(groupid) 
     299            if balance is None : 
     300                policy = self.config.getPrinterPolicy(printername) 
     301                if policy in [None, "ALLOW"] : 
     302                    action = "POLICY_ALLOW" 
     303                else :     
     304                    action = "POLICY_DENY" 
     305                self.logger.log_message(_("Unable to find group %s's account balance, applying default policy (%s) for printer %s") % (groupname, action, printername)) 
     306            else :     
     307                # TODO : there's no warning (no account balance soft limit) 
     308                if balance <= 0.0 : 
     309                    action = "DENY" 
     310                else :     
     311                    action = "ALLOW" 
     312        else : 
     313            quota = self.storage.getGroupPQuota(groupid, printerid) 
     314            if quota is None : 
     315                # Unknown group or printer or combination 
     316                policy = self.config.getPrinterPolicy(printername) 
     317                if policy in [None, "ALLOW"] : 
     318                    action = "POLICY_ALLOW" 
     319                else :     
     320                    action = "POLICY_DENY" 
     321                self.logger.log_message(_("Unable to match group %s on printer %s, applying default policy (%s)") % (groupname, printername, action)) 
     322            else :     
     323                pagecounter = quota["pagecounter"] 
     324                softlimit = quota["softlimit"] 
     325                hardlimit = quota["hardlimit"] 
     326                datelimit = quota["datelimit"] 
     327                if softlimit is not None : 
     328                    if pagecounter < softlimit : 
     329                        action = "ALLOW" 
     330                    else :     
     331                        if hardlimit is None : 
     332                            # only a soft limit, this is equivalent to having only a hard limit 
     333                            action = "DENY" 
     334                        else :     
     335                            if softlimit <= pagecounter < hardlimit :     
     336                                now = DateTime.now() 
     337                                if datelimit is not None : 
     338                                    datelimit = DateTime.ISO.ParseDateTime(datelimit) 
     339                                else : 
     340                                    datelimit = now + self.config.getGraceDelay(printername) 
     341                                    self.storage.setGroupDateLimit(groupid, printerid, datelimit) 
     342                                if now < datelimit : 
     343                                    action = "WARN" 
     344                                else :     
     345                                    action = "DENY" 
     346                            else :          
     347                                action = "DENY" 
     348                else :         
     349                    if hardlimit is not None : 
     350                        # no soft limit, only a hard one. 
     351                        if pagecounter < hardlimit : 
     352                            action = "ALLOW" 
     353                        else :       
     354                            action = "DENY" 
     355                    else : 
     356                        # Both are unset, no quota, i.e. accounting only 
     357                        action = "ALLOW" 
     358        return action 
     359     
    289360    def checkUserPQuota(self, username, printername) : 
    290361        """Checks the user quota on a printer and deny or accept the job.""" 
     362        # first we check any group the user is a member of 
     363        userid = self.storage.getUserId(username) 
     364        for groupname in self.storage.getUserGroupsNames(userid) : 
     365            action = self.checkGroupPQuota(groupname, printername) 
     366            if action in ("DENY", "POLICY_DENY") : 
     367                return action 
     368                 
     369        # then we check the user's own quota 
    291370        printerid = self.storage.getPrinterId(printername) 
    292         userid = self.storage.getUserId(username) 
    293371        limitby = self.storage.getUserLimitBy(userid) 
    294372        if limitby == "balance" :  
     
    355433        return action 
    356434     
    357     def warnGroupPQuota(self, username, printername=None) : 
    358         """Checks a user quota and send him a message if quota is exceeded on current printer.""" 
     435    def warnGroupPQuota(self, groupname, printername=None) : 
     436        """Checks a group quota and send messages if quota is exceeded on current printer.""" 
    359437        pname = printername or self.printername 
    360         raise PyKotaToolError, _("Group quotas are currently not implemented.") 
     438        admin = self.config.getAdmin(pname) 
     439        adminmail = self.config.getAdminMail(pname) 
     440        mailto = self.config.getMailTo(pname) 
     441        action = self.checkGroupPQuota(groupname, pname) 
     442        groupmembers = self.storage.getGroupMembersNames(groupname) 
     443        if action.startswith("POLICY_") : 
     444            action = action[7:] 
     445        if action == "DENY" : 
     446            adminmessage = _("Print Quota exceeded for group %s on printer %s") % (groupname, pname) 
     447            self.logger.log_message(adminmessage) 
     448            if mailto in [ "BOTH", "ADMIN" ] : 
     449                self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage) 
     450            for username in groupmembers : 
     451                if mailto in [ "BOTH", "USER" ] : 
     452                    self.sendMessageToUser(admin, adminmail, username, _("Print Quota Exceeded"), _("You are not allowed to print anymore because\nyour group Print Quota is exceeded on printer %s.") % pname) 
     453        elif action == "WARN" :     
     454            adminmessage = _("Print Quota soft limit exceeded for group %s on printer %s") % (groupname, pname) 
     455            self.logger.log_message(adminmessage) 
     456            if mailto in [ "BOTH", "ADMIN" ] : 
     457                self.sendMessageToAdmin(adminmail, _("Print Quota"), adminmessage) 
     458            for username in groupmembers : 
     459                if mailto in [ "BOTH", "USER" ] : 
     460                    self.sendMessageToUser(admin, adminmail, username, _("Print Quota Exceeded"), _("You will soon be forbidden to print anymore because\nyour group Print Quota is almost reached on printer %s.") % pname) 
     461        return action         
    361462         
    362463    def warnUserPQuota(self, username, printername=None) : 
  • pykota/trunk/pykota/version.py

    r883 r927  
    2121# 
    2222 
    23 __version__ = "1.03alpha-unofficial" 
     23__version__ = "1.03beta-unofficial" 
    2424 
    2525__doc__ = """PyKota : a complete Printing Quota Solution for CUPS."""