Changeset 927 for pykota

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

Groups quota work now !

Location:
pykota/trunk
Files:
13 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/edpykota

    r924 r927  
    2323# 
    2424# $Log$ 
     25# Revision 1.41  2003/04/16 12:35:49  jalet 
     26# Groups quota work now ! 
     27# 
    2528# Revision 1.40  2003/04/16 08:22:09  jalet 
    2629# More strict error detection. 
     
    340343        if not names :     
    341344            if options["add"] and not printeradded : 
    342                 raise PyKotaToolError, _("You have to pass user names on the command line") 
     345                raise PyKotaToolError, _("You have to pass user or group names on the command line") 
    343346            else :     
    344347                names = [ "*" ] # all users 
     
    366369        if limitby and (limitby not in ('quota', 'balance')) :     
    367370            raise PyKotaToolError, _("Invalid limitby value %s" % options["limitby"]) 
     371             
     372        if options["ingroups"] :     
     373            groupnames = [gname.strip() for gname in options["ingroups"].split(',')] 
     374        else :     
     375            groupnames = [] 
    368376             
    369377        for (printerid, printer) in printers : 
     
    393401                if softlimit is not None : 
    394402                    self.logger.log_message(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer)) 
    395             if (not options["reset"] and not options["noquota"] and not options["prototype"] and not options["limitby"] and not options["balance"] and not options["delete"] and not options["charge"]) and ((hardlimit is None) or (softlimit is None)) : 
     403            if (not options["ingroups"] and not options["reset"] and not options["noquota"] and not options["prototype"] and not options["limitby"] and not options["balance"] and not options["delete"] and not options["charge"]) and ((hardlimit is None) or (softlimit is None)) : 
    396404                raise PyKotaToolError, _("Both hard and soft limits must be set ! Aborting.") 
    397405            if options["add"] :     
     
    458466                                else : 
    459467                                    self.storage.setUserBalance(ident, balancevalue) 
     468                            for groupname in groupnames :         
     469                                groupid = self.storage.getGroupId(groupname) 
     470                                if groupid is not None : 
     471                                    self.storage.addUserToGroup(ident, groupid) 
    460472                            self.warnUserPQuota(name, printer)     
    461473                      
     
    506518        elif options["groups"] and (options["balance"] or options["ingroups"]) : 
    507519            raise PyKotaToolError, _("incompatible options, see help.") 
    508         elif options["groups"] :     
    509             raise PyKotaToolError, _("option --groups is currently not implemented.") 
    510520        else : 
    511521            sys.exit(editor.main(args, options)) 
  • pykota/trunk/bin/repykota

    r915 r927  
    2323# 
    2424# $Log$ 
     25# Revision 1.26  2003/04/16 12:35:49  jalet 
     26# Groups quota work now ! 
     27# 
    2528# Revision 1.25  2003/04/15 11:30:57  jalet 
    2629# More work done on money print charging. 
     
    177180                print _("Group            used     soft     hard   grace        total") 
    178181                print "------------------------------------------------------------" 
    179                 for name in self.storage.getPrinterGroups(printerid) : 
     182                for (ident, name) in self.storage.getPrinterGroups(printerid) : 
    180183                    quota = self.storage.getGroupPQuota(ident, printerid)  
    181184                    total += self.printQuota(name, quota) 
     
    200203        """Prints the quota information.""" 
    201204        if quota is not None : 
    202             lifepagecounter = quota["lifepagecounter"] 
    203             pagecounter = quota["pagecounter"] 
     205            lifepagecounter = quota["lifepagecounter"] or 0 
     206            pagecounter = quota["pagecounter"] or 0 
    204207            softlimit = quota["softlimit"] 
    205208            hardlimit = quota["hardlimit"] 
     
    244247        elif options["users"] and options["groups"] :     
    245248            raise PyKotaToolError, _("incompatible options, see help.") 
    246         elif options["groups"] :     
    247             raise PyKotaToolError, _("option --groups is currently not implemented.") 
    248249        elif args :     
    249250            raise PyKotaToolError, _("unused arguments [%s]. Aborting.") % ", ".join(args) 
  • pykota/trunk/bin/warnpykota

    r900 r927  
    2323# 
    2424# $Log$ 
     25# Revision 1.16  2003/04/16 12:35:49  jalet 
     26# Groups quota work now ! 
     27# 
    2528# Revision 1.15  2003/04/10 21:47:20  jalet 
    2629# Job history added. Upgrade script neutralized for now ! 
     
    175178        elif options["users"] and options["groups"] :     
    176179            raise PyKotaToolError, _("incompatible options, see help.") 
    177         elif options["groups"] :     
    178             raise PyKotaToolError, _("option --groups is currently not implemented.") 
    179180        elif args :     
    180181            raise PyKotaToolError, _("unused arguments [%s]. Aborting.") % ", ".join(args) 
  • pykota/trunk/NEWS

    r926 r927  
    2222PyKota NEWS : 
    2323 
     24    - 1.03beta : 
     25     
     26        - Group quotas seem to work now ! 
     27         
    2428    - 1.03alpha : 
    2529     
  • pykota/trunk/po/en/pykota.po

    r925 r927  
    2121# 
    2222# $Log$ 
     23# Revision 1.18  2003/04/16 12:35:49  jalet 
     24# Groups quota work now ! 
     25# 
    2326# Revision 1.17  2003/04/16 08:53:14  jalet 
    2427# Printing can now be limited either by user's account balance or by 
     
    253256msgstr "" 
    254257 
    255 msgid "You have to pass user names on the command line" 
     258msgid "You have to pass user or group names on the command line" 
    256259msgstr "" 
    257260 
     
    279282msgid "Unable to find user %s's account balance, applying default policy (%s) for printer %s" 
    280283msgstr "" 
     284 
     285msgid "Unable to find group %s's account balance, applying default policy (%s) for printer %s" 
     286msgstr "" 
     287 
     288msgid "Unable to match group %s on printer %s, applying default policy (%s)" 
     289msgstr "" 
     290 
     291msgid "Print Quota exceeded for group %s on printer %s" 
     292msgstr "" 
     293 
     294msgid "" 
     295"You are not allowed to print anymore because\n" 
     296"your group Print Quota is exceeded on printer %s." 
     297msgstr "" 
     298 
     299msgid "Print Quota soft limit exceeded for group %s on printer %s" 
     300msgstr "" 
     301 
     302msgid "" 
     303"You will soon be forbidden to print anymore because\n" 
     304"your group Print Quota is almost reached on printer %s." 
     305msgstr "" 
  • pykota/trunk/po/fr/pykota.po

    r925 r927  
    2121# 
    2222# $Log$ 
     23# Revision 1.16  2003/04/16 12:35:49  jalet 
     24# Groups quota work now ! 
     25# 
    2326# Revision 1.15  2003/04/16 08:53:14  jalet 
    2427# Printing can now be limited either by user's account balance or by 
     
    261264msgstr "R� : %s" 
    262265 
    263 msgid "You have to pass user names on the command line" 
    264 msgstr "Vous devez passer des noms d'utilisateur sur la ligne de commande" 
     266msgid "You have to pass user or group names on the command line" 
     267msgstr "Vous devez passer des noms d'utilisateurs ou de groupes sur la ligne de commande" 
    265268 
    266269msgid "unknown" 
     
    287290msgid "Unable to find user %s's account balance, applying default policy (%s) for printer %s" 
    288291msgstr "Impossible de trouver le solde du compte de l'utilisateur %s, action par d�ut (%s) appliqu�sur l'imprimante %s" 
     292 
     293msgid "Unable to find group %s's account balance, applying default policy (%s) for printer %s" 
     294msgstr "Impossible de trouver le solde du compte du groupe %s, action par d�ut (%s) appliqu�sur l'imprimante %s" 
     295 
     296msgid "Unable to match group %s on printer %s, applying default policy (%s)" 
     297msgstr "Impossible de trouver le groupe %s sur l'imprimante %s, action par d�ut (%s) appliqu� 
     298 
     299msgid "Print Quota exceeded for group %s on printer %s" 
     300msgstr "D�ssement de Quota d'impression pour le groupe %s sur l'imprimante %s" 
     301 
     302msgid "" 
     303"You are not allowed to print anymore because\n" 
     304"your group Print Quota is exceeded on printer %s." 
     305msgstr "" 
     306"Vous n'�s plus autoris� imprimer car\n" 
     307"le Quota d'Impression de votre groupe est d�ss�ur l'imprimante %s." 
     308 
     309msgid "Print Quota soft limit exceeded for group %s on printer %s" 
     310msgstr "Limite souple de Quota d'Impression d�ss�pour le groupe %s sur l'imprimante %s" 
     311 
     312msgid "" 
     313"You will soon be forbidden to print anymore because\n" 
     314"your group Print Quota is almost reached on printer %s." 
     315msgstr "" 
     316"Vous n'aurez bient�lus le droit d'imprimer car\n" 
     317"le Quota d'Impression de votre groupe sur l'imprimante %s est presque atteint." 
  • pykota/trunk/po/pykota.pot

    r925 r927  
    2121# 
    2222# $Log$ 
     23# Revision 1.18  2003/04/16 12:35:49  jalet 
     24# Groups quota work now ! 
     25# 
    2326# Revision 1.17  2003/04/16 08:53:14  jalet 
    2427# Printing can now be limited either by user's account balance or by 
     
    253256msgstr "" 
    254257 
    255 msgid "You have to pass user names on the command line" 
     258msgid "You have to pass user or group names on the command line" 
    256259msgstr "" 
    257260 
     
    279282msgid "Unable to find user %s's account balance, applying default policy (%s) for printer %s" 
    280283msgstr "" 
     284 
     285msgid "Unable to find group %s's account balance, applying default policy (%s) for printer %s" 
     286msgstr "" 
     287 
     288msgid "Unable to match group %s on printer %s, applying default policy (%s)" 
     289msgstr "" 
     290 
     291msgid "Print Quota exceeded for group %s on printer %s" 
     292msgstr "" 
     293 
     294msgid "" 
     295"You are not allowed to print anymore because\n" 
     296"your group Print Quota is exceeded on printer %s." 
     297msgstr "" 
     298 
     299msgid "Print Quota soft limit exceeded for group %s on printer %s" 
     300msgstr "" 
     301 
     302msgid "" 
     303"You will soon be forbidden to print anymore because\n" 
     304"your group Print Quota is almost reached on printer %s." 
     305msgstr "" 
  • 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.""" 
  • pykota/trunk/README

    r926 r927  
    3030Actual working features : 
    3131 
    32         - Per printer user quotas. 
     32        - Per printer user and group quotas. 
    3333         
    3434        - Automated email warning of users above quota to the 
     
    195195Copy the conf/pykota.conf.sample sample configuration file to 
    196196/etc/pykota.conf, and adapt this file to your own needs and  
    197 configuration. 
     197configuration. The installation script tries to do this for 
     198you if needed and you agreed to this action. 
    198199 
    199200Modify the PPD files for each printer on which you want to manage 
     
    249250    along with totals. 
    250251     
    251 WARNING : as of today, 2003-02-06, group quotas are not 
    252 implemented. 
    253  
    254252SECURITY : You should ensure that only the print quota administrator 
    255253           can run the warnpykota command, but this is actually not 
  • pykota/trunk/TODO

    r873 r927  
    2222TODO, in order of importance : 
    2323 
    24         - Finalize the implementation of group quotas. 
    25          
    2624        - Group administrators (think quotagrpdmins for disk quotas). 
    2725