Index: pykota/trunk/bin/edpykota
===================================================================
--- pykota/trunk/bin/edpykota (revision 2655)
+++ pykota/trunk/bin/edpykota (revision 2657)
@@ -253,300 +253,304 @@
         suffix = (options["groups"] and "Group") or "User"        
         
-        softlimit = hardlimit = None
-        
-        limitby = options["limitby"]
-        if limitby :
-            limitby = limitby.strip().lower()
-        if limitby :
-            if limitby not in ('quota', 'balance', 'noquota', \
-                                        'noprint', 'nochange') :
-                raise PyKotaCommandLineError, _("Invalid limitby value %s") % options["limitby"]
-            if limitby in ('noquota', 'nochange') :    
-                options["noquota"] = 1
-            if (limitby in ('nochange', 'noprint')) and options["groups"] :    
-                raise PyKotaCommandLineError, _("Invalid limitby value %s") % options["limitby"]
-
-        used = options["used"]
-        if used :
-            used = used.strip()
-            try :
-                int(used)
-            except ValueError :
-                raise PyKotaCommandLineError, _("Invalid used value %s.") % used
+        if options["delete"] :    
+            if not names :
+                raise PyKotaCommandLineError, _("You have to pass user or group names on the command line")
+            self.display("Processing...\n")
+            todelete = getattr(self.storage, "getMatching%ss" % suffix)(",".join(names))
+            nbtotal = len(todelete)
+            for i in range(nbtotal) :
+                todelete[i].delete()
+                percent = 100.0 * float(i) / float(nbtotal)
+                self.display("\r%.02f%%" % percent)
+            self.display("\r100.00%%\r        ")
+            self.display("\r%s\n" % _("Done."))
+        else :
+            softlimit = hardlimit = None
+            
+            limitby = options["limitby"]
+            if limitby :
+                limitby = limitby.strip().lower()
+            if limitby :
+                if limitby not in ('quota', 'balance', 'noquota', \
+                                            'noprint', 'nochange') :
+                    raise PyKotaCommandLineError, _("Invalid limitby value %s") % options["limitby"]
+                if limitby in ('noquota', 'nochange') :    
+                    options["noquota"] = 1
+                if (limitby in ('nochange', 'noprint')) and options["groups"] :    
+                    raise PyKotaCommandLineError, _("Invalid limitby value %s") % options["limitby"]
+            
+            used = options["used"]
+            if used :
+                used = used.strip()
+                try :
+                    int(used)
+                except ValueError :
+                    raise PyKotaCommandLineError, _("Invalid used value %s.") % used
+                    
+            increase = options["increase"]
+            if increase :
+                try :
+                    increase = int(increase.strip())
+                except ValueError :
+                    raise PyKotaCommandLineError, _("Invalid increase value %s.") % increase
+            
+            if not options["noquota"] :
+                if options["softlimit"] :
+                    try :
+                        softlimit = int(options["softlimit"].strip())
+                        if softlimit < 0 :
+                            raise ValueError
+                    except ValueError :    
+                        raise PyKotaCommandLineError, _("Invalid softlimit value %s.") % options["softlimit"]
+                if options["hardlimit"] :
+                    try :
+                        hardlimit = int(options["hardlimit"].strip())
+                        if hardlimit < 0 :
+                            raise ValueError
+                    except ValueError :    
+                        raise PyKotaCommandLineError, _("Invalid hardlimit value %s.") % options["hardlimit"]
+                if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :        
+                    # error, exchange them
+                    self.printInfo(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
+                    (softlimit, hardlimit) = (hardlimit, softlimit)
                 
-        increase = options["increase"]
-        if increase :
-            try :
-                increase = int(increase.strip())
-            except ValueError :
-                raise PyKotaCommandLineError, _("Invalid increase value %s.") % increase
-
-        if not options["noquota"] :
-            if options["softlimit"] :
+            overcharge = options["overcharge"]
+            if overcharge :
                 try :
-                    softlimit = int(options["softlimit"].strip())
-                    if softlimit < 0 :
-                        raise ValueError
+                    overcharge = float(overcharge.strip())
+                except (ValueError, AttributeError) :    
+                    raise PyKotaCommandLineError, _("Invalid overcharge value %s") % options["overcharge"]
+                    
+            balance = options["balance"]
+            if balance :
+                balance = balance.strip()
+                try :
+                    balancevalue = float(balance)
                 except ValueError :    
-                    raise PyKotaCommandLineError, _("Invalid softlimit value %s.") % options["softlimit"]
-            if options["hardlimit"] :
-                try :
-                    hardlimit = int(options["hardlimit"].strip())
-                    if hardlimit < 0 :
-                        raise ValueError
-                except ValueError :    
-                    raise PyKotaCommandLineError, _("Invalid hardlimit value %s.") % options["hardlimit"]
-            if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :        
-                # error, exchange them
-                self.printInfo(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
-                (softlimit, hardlimit) = (hardlimit, softlimit)
-            
-        overcharge = options["overcharge"]
-        if overcharge :
-            try :
-                overcharge = float(overcharge.strip())
-            except (ValueError, AttributeError) :    
-                raise PyKotaCommandLineError, _("Invalid overcharge value %s") % options["overcharge"]
-                
-        balance = options["balance"]
-        if balance :
-            balance = balance.strip()
-            try :
-                balancevalue = float(balance)
-            except ValueError :    
-                raise PyKotaCommandLineError, _("Invalid balance value %s") % options["balance"]
-            
-        if options["charge"] :
-            try :
-                charges = [float(part) for part in options["charge"].split(',', 1)]
-            except ValueError :    
-                raise PyKotaCommandLineError, _("Invalid charge amount value %s") % options["charge"]
-            else :    
-                if len(charges) > 2 :
-                    charges = charges[:2]
-                if len(charges) != 2 :
-                    charges = [charges[0], None]
-                    
-        if options["ingroups"] :    
-            groupnames = [gname.strip() for gname in options["ingroups"].split(',')]
-        else :    
-            groupnames = []
-            
-        rejectunknown = self.config.getRejectUnknown()    
-        printeradded = 0
-        printers = self.storage.getMatchingPrinters(options["printer"])
-        if not printers :
-            pname = options["printer"]
-            if options["add"] and pname :
-                if self.isValidName(pname) :
-                    printers = [ self.storage.addPrinter(pname) ]
-                    if printers[0].Exists :
-                        printeradded = 1
-                    else :    
-                        raise PyKotaToolError, _("Impossible to add printer %s") % pname
-                else :    
-                    raise PyKotaCommandLineError, _("Invalid printer name %s") % pname
-            else :
-                raise PyKotaCommandLineError, _("There's no printer matching %s") % pname
-        if not names :    
-            if options["delete"] :    
-                raise PyKotaCommandLineError, _("You have to pass user or group names on the command line")
-            else :
-                names = getattr(self.storage, "getAll%ssNames" % suffix)() # all users or groups
-                
-        printersgroups = []        
-        if options["pgroups"] :        
-            printersgroups = self.storage.getMatchingPrinters(options["pgroups"])
-            
-        if options["prototype"] :    
-            protoentry = getattr(self.storage, "get%s" % suffix)(options["prototype"])
-            if not protoentry.Exists :
-                raise PyKotaCommandLineError, _("Prototype object %s not found in Quota Storage.") % protoentry.Name
-            else :    
-                limitby = protoentry.LimitBy
-                balancevalue = protoentry.AccountBalance
-                if balancevalue is not None :
-                    balance = str(abs(balancevalue))
-                else :    
-                    balance = None
-                overcharge = getattr(protoentry, "OverCharge", None)
-            
-        sys.stdout.write(_("Managing print quotas... (this may take a lot of time)"))
-        sys.stdout.flush()
-        missingusers = {}
-        missinggroups = {}    
-        todelete = {}    
-        changed = {} # tracks changes made at the user/group level
-        for printer in printers :
-            for pgroup in printersgroups :
-                pgroup.addPrinterToGroup(printer)    
+                    raise PyKotaCommandLineError, _("Invalid balance value %s") % options["balance"]
                 
             if options["charge"] :
-                (perpage, perjob) = charges
-                printer.setPrices(perpage, perjob)    
+                try :
+                    charges = [float(part) for part in options["charge"].split(',', 1)]
+                except ValueError :    
+                    raise PyKotaCommandLineError, _("Invalid charge amount value %s") % options["charge"]
+                else :    
+                    if len(charges) > 2 :
+                        charges = charges[:2]
+                    if len(charges) != 2 :
+                        charges = [charges[0], None]
+                        
+            if options["ingroups"] :    
+                groupnames = [gname.strip() for gname in options["ingroups"].split(',')]
+            else :    
+                groupnames = []
                 
-            if options["prototype"] :
-                protoquota = getattr(self.storage, "get%sPQuota" % suffix)(protoentry, printer)
-                if not protoquota.Exists :
-                    self.printInfo(_("Prototype %s not found in Quota Storage for printer %s.") % (protoentry.Name, printer.Name))
+            rejectunknown = self.config.getRejectUnknown()    
+            printeradded = 0
+            printers = self.storage.getMatchingPrinters(options["printer"])
+            if not printers :
+                pname = options["printer"]
+                if options["add"] and pname :
+                    if self.isValidName(pname) :
+                        printers = [ self.storage.addPrinter(pname) ]
+                        if printers[0].Exists :
+                            printeradded = 1
+                        else :    
+                            raise PyKotaToolError, _("Impossible to add printer %s") % pname
+                    else :    
+                        raise PyKotaCommandLineError, _("Invalid printer name %s") % pname
+                else :
+                    raise PyKotaCommandLineError, _("There's no printer matching %s") % pname
+            if not names :    
+                names = getattr(self.storage, "getAll%ssNames" % suffix)() # all users or groups
+                    
+            printersgroups = []        
+            if options["pgroups"] :        
+                printersgroups = self.storage.getMatchingPrinters(options["pgroups"])
+                
+            if options["prototype"] :    
+                protoentry = getattr(self.storage, "get%s" % suffix)(options["prototype"])
+                if not protoentry.Exists :
+                    raise PyKotaCommandLineError, _("Prototype object %s not found in Quota Storage.") % protoentry.Name
                 else :    
-                    (softlimit, hardlimit) = (protoquota.SoftLimit, protoquota.HardLimit)
+                    limitby = protoentry.LimitBy
+                    balancevalue = protoentry.AccountBalance
+                    if balancevalue is not None :
+                        balance = str(abs(balancevalue))
+                    else :    
+                        balance = None
+                    overcharge = getattr(protoentry, "OverCharge", None)
+                
+            sys.stdout.write(_("Managing print quotas... (this may take a lot of time)"))
+            sys.stdout.flush()
+            missingusers = {}
+            missinggroups = {}    
+            changed = {} # tracks changes made at the user/group level
+            for printer in printers :
+                for pgroup in printersgroups :
+                    pgroup.addPrinterToGroup(printer)    
                     
-            if not options["noquota"] :    
-                if hardlimit is None :    
-                    hardlimit = softlimit
-                    if hardlimit is not None :
-                        self.printInfo(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer.Name))
-                if softlimit is None :    
-                    softlimit = hardlimit
-                    if softlimit is not None :
-                        self.printInfo(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer.Name))
+                if options["charge"] :
+                    (perpage, perjob) = charges
+                    printer.setPrices(perpage, perjob)    
+                    
+                if options["prototype"] :
+                    protoquota = getattr(self.storage, "get%sPQuota" % suffix)(protoentry, printer)
+                    if not protoquota.Exists :
+                        self.printInfo(_("Prototype %s not found in Quota Storage for printer %s.") % (protoentry.Name, printer.Name))
+                    else :    
+                        (softlimit, hardlimit) = (protoquota.SoftLimit, protoquota.HardLimit)
                         
-            if options["add"] :    
-                allentries = []    
-                for name in names :
-                    email = ""
-                    if not options["groups"] :
-                        splitname = name.split('/', 1)     # username/email
-                        if len(splitname) == 1 :
-                            splitname.append("")
-                        (name, email) = splitname
-                        if email and (email.count('@') != 1) :
-                            self.printInfo(_("Invalid email address %s") % email)
-                            email = ""
-                    entry = getattr(self.storage, "get%s" % suffix)(name)
-                    if email and not options["groups"] :
-                        entry.Email = email
-                    entrypquota = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
-                    allentries.append((entry, entrypquota))
-            else :   
-                allentries = getattr(self.storage, "getPrinter%ssAndQuotas" % suffix)(printer, names)
-                
-            # TODO : do this only once !!!    
-            allnames = [entry.Name for (entry, dummy) in allentries]
-            for name in names :    
-                if not self.matchString(name, allnames) :
-                    if options["groups"] :
-                        missinggroups[name] = 1
+                if not options["noquota"] :    
+                    if hardlimit is None :    
+                        hardlimit = softlimit
+                        if hardlimit is not None :
+                            self.printInfo(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer.Name))
+                    if softlimit is None :    
+                        softlimit = hardlimit
+                        if softlimit is not None :
+                            self.printInfo(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer.Name))
+                            
+                if options["add"] :    
+                    allentries = []    
+                    for name in names :
+                        email = ""
+                        if not options["groups"] :
+                            splitname = name.split('/', 1)     # username/email
+                            if len(splitname) == 1 :
+                                splitname.append("")
+                            (name, email) = splitname
+                            if email and (email.count('@') != 1) :
+                                self.printInfo(_("Invalid email address %s") % email)
+                                email = ""
+                        entry = getattr(self.storage, "get%s" % suffix)(name)
+                        if email and not options["groups"] :
+                            entry.Email = email
+                        entrypquota = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
+                        allentries.append((entry, entrypquota))
+                else :   
+                    allentries = getattr(self.storage, "getPrinter%ssAndQuotas" % suffix)(printer, names)
+                    
+                # TODO : do this only once !!!    
+                allnames = [entry.Name for (entry, dummy) in allentries]
+                for name in names :    
+                    if not self.matchString(name, allnames) :
+                        if options["groups"] :
+                            missinggroups[name] = 1
+                        else :    
+                            missingusers[name] = 1
+                    
+                for (entry, entrypquota) in allentries :
+                    if not changed.has_key(entry.Name) :
+                        changed[entry.Name] = {}
+                        if not options["groups"] :
+                            changed[entry.Name]["ingroups"] = []
+                            
+                    if not entry.Exists :        
+                        # not found
+                        if options["add"] :
+                            # In case we want to add something, it is crucial
+                            # that we DON'T check with the system accounts files
+                            # like /etc/passwd because users may be defined 
+                            # only remotely
+                            if self.isValidName(entry.Name) :
+                                reject = 0
+                                if rejectunknown :
+                                    if options["groups"] :
+                                        try :
+                                            grp.getgrnam(entry.Name)
+                                        except KeyError :    
+                                            self.printInfo(_("Unknown group %s") % entry.Name, "error")
+                                            reject = 1
+                                    else :    
+                                        try :
+                                            pwd.getpwnam(entry.Name)
+                                        except KeyError :    
+                                            self.printInfo(_("Unknown user %s") % entry.Name, "error")
+                                            reject = 1
+                                if not reject :        
+                                    entry = getattr(self.storage, "add%s" % suffix)(entry)
+                            else :    
+                                if options["groups"] :
+                                    self.printInfo(_("Invalid group name %s") % entry.Name)
+                                else :    
+                                    self.printInfo(_("Invalid user name %s") % entry.Name)
+                        else :
+                            if options["groups"] :
+                                missinggroups[entry.Name] = 1
+                            else :    
+                                missingusers[entry.Name] = 1
+                                    
+                    if entry.Exists and (not entrypquota.Exists) :
+                        # not found
+                        if options["add"] :
+                            entrypquota = getattr(self.storage, "add%sPQuota" % suffix)(entry, printer)
+                            
+                    if not entrypquota.Exists :     
+                        self.printInfo(_("Quota not found for object %s on printer %s.") % (entry.Name, printer.Name))
                     else :    
-                        missingusers[name] = 1
-                
-            for (entry, entrypquota) in allentries :
-                if not changed.has_key(entry.Name) :
-                    changed[entry.Name] = {}
-                    if not options["groups"] :
-                        changed[entry.Name]["ingroups"] = []
+                        if options["noquota"] or options["prototype"] \
+                           or ((softlimit is not None) and (hardlimit is not None)) :
+                            entrypquota.setLimits(softlimit, hardlimit)
+                        if increase :
+                           if (entrypquota.SoftLimit is None) \
+                               or (entrypquota.HardLimit is None) :
+                               self.printInfo(_("You can't increase limits by %s when no limit is set.") % increase, "error")
+                           else :
+                               newsoft = entrypquota.SoftLimit + increase         
+                               newhard = entrypquota.HardLimit + increase         
+                               if (newsoft >= 0) and (newhard >= 0) :
+                                   entrypquota.setLimits(newsoft, newhard)
+                               else :    
+                                   self.printInfo(_("You can't set negative limits."), "error")
+                        if limitby :
+                            if changed[entry.Name].get("limitby") is None :
+                                entry.setLimitBy(limitby)
+                                changed[entry.Name]["limitby"] = limitby
                         
-                if not entry.Exists :        
-                    # not found
-                    if options["add"] :
-                        # In case we want to add something, it is crucial
-                        # that we DON'T check with the system accounts files
-                        # like /etc/passwd because users may be defined 
-                        # only remotely
-                        if self.isValidName(entry.Name) :
-                            reject = 0
-                            if rejectunknown :
-                                if options["groups"] :
-                                    try :
-                                        grp.getgrnam(entry.Name)
-                                    except KeyError :    
-                                        self.printInfo(_("Unknown group %s") % entry.Name, "error")
-                                        reject = 1
-                                else :    
-                                    try :
-                                        pwd.getpwnam(entry.Name)
-                                    except KeyError :    
-                                        self.printInfo(_("Unknown user %s") % entry.Name, "error")
-                                        reject = 1
-                            if not reject :        
-                                entry = getattr(self.storage, "add%s" % suffix)(entry)
-                        else :    
-                            if options["groups"] :
-                                self.printInfo(_("Invalid group name %s") % entry.Name)
-                            else :    
-                                self.printInfo(_("Invalid user name %s") % entry.Name)
-                    else :
-                        if options["groups"] :
-                            missinggroups[entry.Name] = 1
-                        else :    
-                            missingusers[entry.Name] = 1
-                elif options["delete"] :                
-                    todelete[entry.Name] = entry
+                        if options["reset"] :
+                            entrypquota.reset()
+                            
+                        if options["hardreset"] :    
+                            entrypquota.hardreset()
+                            
+                        if not options["groups"] :
+                            if used :
+                                entrypquota.setUsage(used)
                                 
-                if entry.Exists and (not entrypquota.Exists) :
-                    # not found
-                    if options["add"] :
-                        entrypquota = getattr(self.storage, "add%sPQuota" % suffix)(entry, printer)
-                        
-                if not entrypquota.Exists :     
-                    self.printInfo(_("Quota not found for object %s on printer %s.") % (entry.Name, printer.Name))
-                else :    
-                    if options["noquota"] or options["prototype"] \
-                       or ((softlimit is not None) and (hardlimit is not None)) :
-                        entrypquota.setLimits(softlimit, hardlimit)
-                    if increase :
-                       if (entrypquota.SoftLimit is None) \
-                           or (entrypquota.HardLimit is None) :
-                           self.printInfo(_("You can't increase limits by %s when no limit is set.") % increase, "error")
-                       else :
-                           newsoft = entrypquota.SoftLimit + increase         
-                           newhard = entrypquota.HardLimit + increase         
-                           if (newsoft >= 0) and (newhard >= 0) :
-                               entrypquota.setLimits(newsoft, newhard)
-                           else :    
-                               self.printInfo(_("You can't set negative limits."), "error")
-                    if limitby :
-                        if changed[entry.Name].get("limitby") is None :
-                            entry.setLimitBy(limitby)
-                            changed[entry.Name]["limitby"] = limitby
-                    
-                    if options["reset"] :
-                        entrypquota.reset()
-                        
-                    if options["hardreset"] :    
-                        entrypquota.hardreset()
-                        
-                    if not options["groups"] :
-                        if used :
-                            entrypquota.setUsage(used)
+                            if overcharge is not None :    
+                                if changed[entry.Name].get("overcharge") is None :
+                                    entry.setOverChargeFactor(overcharge)
+                                    changed[entry.Name]["overcharge"] = overcharge
+                                    
+                            if balance :
+                                if changed[entry.Name].get("balance") is None :
+                                    if balance.startswith("+") or balance.startswith("-") :
+                                        newbalance = float(entry.AccountBalance or 0.0) + balancevalue
+                                        newlifetimepaid = float(entry.LifeTimePaid or 0.0) + balancevalue
+                                        entry.setAccountBalance(newbalance, newlifetimepaid, options["comment"])
+                                    else :
+                                        diff = balancevalue - float(entry.AccountBalance or 0.0)
+                                        newlifetimepaid = float(entry.LifeTimePaid or 0.0) + diff
+                                        entry.setAccountBalance(balancevalue, newlifetimepaid, options["comment"])
+                                    changed[entry.Name]["balance"] = balance
+                                    
+                            for groupname in groupnames :        
+                                # not executed if option --ingroups is not used
+                                if groupname not in changed[entry.Name]["ingroups"] :
+                                    group = self.storage.getGroup(groupname)
+                                    if group.Exists :
+                                        self.storage.addUserToGroup(entry, group)
+                                        changed[entry.Name]["ingroups"].append(groupname)
+                                    else :
+                                        self.printInfo(_("Group %s not found in the PyKota Storage.") % groupname)
                             
-                        if overcharge is not None :    
-                            if changed[entry.Name].get("overcharge") is None :
-                                entry.setOverChargeFactor(overcharge)
-                                changed[entry.Name]["overcharge"] = overcharge
-                                
-                        if balance :
-                            if changed[entry.Name].get("balance") is None :
-                                if balance.startswith("+") or balance.startswith("-") :
-                                    newbalance = float(entry.AccountBalance or 0.0) + balancevalue
-                                    newlifetimepaid = float(entry.LifeTimePaid or 0.0) + balancevalue
-                                    entry.setAccountBalance(newbalance, newlifetimepaid, options["comment"])
-                                else :
-                                    diff = balancevalue - float(entry.AccountBalance or 0.0)
-                                    newlifetimepaid = float(entry.LifeTimePaid or 0.0) + diff
-                                    entry.setAccountBalance(balancevalue, newlifetimepaid, options["comment"])
-                                changed[entry.Name]["balance"] = balance
-                                
-                        for groupname in groupnames :        
-                            # not executed if option --ingroups is not used
-                            if groupname not in changed[entry.Name]["ingroups"] :
-                                group = self.storage.getGroup(groupname)
-                                if group.Exists :
-                                    self.storage.addUserToGroup(entry, group)
-                                    changed[entry.Name]["ingroups"].append(groupname)
-                                else :
-                                    self.printInfo(_("Group %s not found in the PyKota Storage.") % groupname)
-                        
-        # Now outputs the list of nonexistent users and groups                
-        for name in missingusers.keys() :
-            self.printInfo(_("Nonexistent user %s or missing print quota entry.") % name, level="warn")
-        for name in missinggroups.keys() :
-            self.printInfo(_("Nonexistent group %s or missing print quota entry.") % name, level="warn")
-        
-        # Now delete what has to be deleted                
-        for (name, entry) in todelete.items() :                
-            entry.delete()
-        sys.stdout.write("\nDone.\n")    
+            # Now outputs the list of nonexistent users and groups                
+            for name in missingusers.keys() :
+                self.printInfo(_("Nonexistent user %s or missing print quota entry.") % name, level="warn")
+            for name in missinggroups.keys() :
+                self.printInfo(_("Nonexistent group %s or missing print quota entry.") % name, level="warn")
+            
+            sys.stdout.write("\nDone.\n")    
                      
 if __name__ == "__main__" : 
