Index: pykota/trunk/bin/pkusers
===================================================================
--- pykota/trunk/bin/pkusers (revision 3411)
+++ pykota/trunk/bin/pkusers (revision 3413)
@@ -9,10 +9,10 @@
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
@@ -40,6 +40,6 @@
 
   pkusers [options] user1 user2 user3 ... userN
-  
-or :  
+
+or :
 
   pkusers --groups [options] group1 group2 group3 ... groupN
@@ -49,9 +49,9 @@
   -v | --version       Prints pkusers's version number then exits.
   -h | --help          Prints this message then exits.
-  
+
   -a | --add           Adds users if they don't exist on the database.
                        If they exist, they are modified unless
                        -s|--skipexisting is also used.
-                       
+
   -d | --delete        Deletes users from the quota storage.
 
@@ -62,9 +62,9 @@
 
   -D | --description d Adds a textual description to users or groups.
-                       
+
   -g | --groups        Edit users groups instead of users.
-                          
-  -o | --overcharge f  Sets the overcharging factor applied to the user 
-                       when computing the cost of a print job. Positive or 
+
+  -o | --overcharge f  Sets the overcharging factor applied to the user
+                       when computing the cost of a print job. Positive or
                        negative floating point values are allowed,
                        this allows you to do some really creative
@@ -74,25 +74,25 @@
                        cost of the job for a particular user.
                        Only users have such a coefficient.
-  
+
   -i | --ingroups g1[,g2...]  Puts the users into each of the groups
                               listed, separated by commas. The groups
                               must already exist in the Quota Storage.
-                       
+
   -L | --list          Lists users or groups.
-  
-  -l | --limitby l     Choose if the user/group is limited in printing                     
+
+  -l | --limitby l     Choose if the user/group is limited in printing
                        by its account balance or by its page quota.
                        The default value is 'quota'. Allowed values
-                       are 'quota' 'balance' 'noquota' 'noprint' 
+                       are 'quota' 'balance' 'noquota' 'noprint'
                        and 'nochange' :
-                       
+
                          - quota : limit by number of pages per printer.
                          - balance : limit by number of credits in account.
                          - noquota : no limit, accounting still done.
-                         - nochange : no limit, accounting not done. 
-                         - noprint : printing is denied. 
+                         - nochange : no limit, accounting not done.
+                         - noprint : printing is denied.
                        NB : nochange and noprint are not supported for groups.
-                       
-  -b | --balance b     Sets the user's account balance to b.                     
+
+  -b | --balance b     Sets the user's account balance to b.
                        Account balance may be increase or decreased
                        if b is prefixed with + or -.
@@ -102,59 +102,59 @@
                        Groups don't have a real balance, but the
                        sum of their users' account balance.
-                       
+
   -C | --comment txt   Defines some informational text to be associated
                        with a change to an user's account balance.
                        Only meaningful if -b | --balance is also used.
-                       
-                       
-  -r | --remove        In combination with the --ingroups option above,                       
+
+
+  -r | --remove        In combination with the --ingroups option above,
                        remove users from the specified users groups.
-                       
+
   -s | --skipexisting  In combination with the --add option above, tells
                        pkusers to not modify existing users.
-                       
+
   user1 through userN and group1 through groupN can use wildcards
   if the --add option is not set.
-  
-examples :                              
+
+examples :
 
   $ pkusers --add john paul george ringo/ringo@example.com
-  
+
   This will add users john, paul, george and ringo to the quota
-  database. User ringo's email address will also be set to 
+  database. User ringo's email address will also be set to
   'ringo@example.com'
-  
+
   $ pkusers --ingroups coders,it jerome
-  
+
   User jerome is put into the groups "coders" and "it" which must
   already exist in the quota database.
-            
+
   $ pkusers --limitby balance jerome
-  
+
   This will tell PyKota to limit jerome by his account's balance
   when printing.
-  
+
   $ pkusers --balance +10.0 --comment "He paid with his blood !" jerome
-  
+
   This will increase jerome's account balance by 10.0 (in your
   own currency). You can decrease the account balance with a
   dash prefix, and set it to a fixed amount with no prefix.
   A comment will be stored for this balance change.
-  
+
   $ pkusers --delete jerome rachel
-  
+
   This will completely delete jerome and rachel from the quota
   database. All their quotas and jobs will be deleted too.
-  
+
   $ pkusers --overcharge 2.5 poorstudent
-  
+
   This will overcharge the poorstudent user by a factor of 2.5.
-  
+
   $ pkusers --overcharge -1 jerome
-  
+
   User jerome will actually earn money whenever he prints.
-  
+
   $ pkusers --overcharge 0 boss
-  
+
   User boss can print at will, it won't cost him anything because the
   cost of each print job will be multiplied by zero before charging
@@ -165,6 +165,6 @@
   This will set the email address for each user to username@example.com
 """)
-        
-class PKUsers(PyKotaTool) :        
+
+class PKUsers(PyKotaTool) :
     """A class for a users and users groups manager."""
     def modifyEntry(self, entry, groups, limitby, description, overcharge=None, balance=None, balancevalue=None, comment=None, email=None) :
@@ -172,5 +172,5 @@
         if description is not None : # NB : "" is allowed !
             entry.setDescription(description)
-        if limitby :    
+        if limitby :
             entry.setLimitBy(limitby)
         if not groups :
@@ -181,5 +181,5 @@
                     raise PyKotaCommandLineError, _("Invalid email address %s") % email
                 entry.setEmail(email)
-            if overcharge is not None : # NB : 0 is allowed !     
+            if overcharge is not None : # NB : 0 is allowed !
                 entry.setOverChargeFactor(overcharge)
             if balance :
@@ -192,6 +192,6 @@
                     newlifetimepaid = float(entry.LifeTimePaid or 0.0) + diff
                     entry.setAccountBalance(balancevalue, newlifetimepaid, comment)
-                    
-    def manageUsersGroups(self, ugroups, user, remove) :        
+
+    def manageUsersGroups(self, ugroups, user, remove) :
         """Manage user group membership."""
         for ugroup in ugroups :
@@ -200,13 +200,13 @@
             else :
                 ugroup.addUserToGroup(user)
-                
+
     def main(self, names, options) :
         """Manage users or groups."""
         names = self.sanitizeNames(options, names)
-        suffix = (options["groups"] and "Group") or "User"        
-        
+        suffix = (options["groups"] and "Group") or "User"
+
         if not options["list"] :
             percent = Percent(self)
-            
+
         if not options["add"] :
             if not options["list"] :
@@ -219,7 +219,7 @@
                     percent.display("\n")
                 raise PyKotaCommandLineError, _("There's no %s matching %s") % (_(suffix.lower()), " ".join(names))
-            if not options["list"] :    
+            if not options["list"] :
                 percent.setSize(len(entries))
-                
+
         if options["list"] :
             if suffix == "User" :
@@ -229,14 +229,14 @@
                     email = entry.Email
                     if not email :
-                        if maildomain :     
+                        if maildomain :
                             email = "%s@%s" % (entry.Name, maildomain)
-                        elif smtpserver :    
+                        elif smtpserver :
                             email = "%s@%s" % (entry.Name, smtpserver)
-                        else :    
+                        else :
                             email = "%s@%s" % (entry.Name, "localhost")
                     msg = "%s - <%s>" % (entry.Name, email)
                     if entry.Description :
                         msg += " - %s" % entry.Description
-                    print msg    
+                    print msg
                     print "    %s" % (_("Limited by : %s") % entry.LimitBy)
                     print "    %s" % (_("Account balance : %.2f") % (entry.AccountBalance or 0.0))
@@ -244,15 +244,15 @@
                     print "    %s" % (_("Overcharging factor : %.2f") % entry.OverCharge)
                     print
-            else :    
+            else :
                 for entry in entries :
                     msg = "%s" % entry.Name
                     if entry.Description :
                         msg += " - %s" % entry.Description
-                    print msg    
+                    print msg
                     print "    %s" % (_("Limited by : %s") % entry.LimitBy)
                     print "    %s" % (_("Group balance : %.2f") % (entry.AccountBalance or 0.0))
                     print "    %s" % (_("Total paid so far : %.2f") % (entry.LifeTimePaid or 0.0))
                     print
-        elif options["delete"] :    
+        elif options["delete"] :
             percent.display("\n%s..." % _("Deletion"))
             getattr(self.storage, "deleteMany%ss" % suffix)(entries)
@@ -266,14 +266,14 @@
                                             'noprint', 'nochange') :
                     raise PyKotaCommandLineError, _("Invalid limitby value %s") % options["limitby"]
-                if (limitby in ('nochange', 'noprint')) and options["groups"] :    
+                if (limitby in ('nochange', 'noprint')) and options["groups"] :
                     raise PyKotaCommandLineError, _("Invalid limitby value %s") % options["limitby"]
-                
+
             overcharge = options["overcharge"]
             if overcharge :
                 try :
                     overcharge = float(overcharge.strip())
-                except (ValueError, AttributeError) :    
+                except (ValueError, AttributeError) :
                     raise PyKotaCommandLineError, _("Invalid overcharge value %s") % options["overcharge"]
-                    
+
             balance = options["balance"]
             if balance :
@@ -281,33 +281,33 @@
                 try :
                     balancevalue = float(balance)
-                except ValueError :    
+                except ValueError :
                     raise PyKotaCommandLineError, _("Invalid balance value %s") % options["balance"]
-            else :    
+            else :
                 balancevalue = None
-                
+
             if options["ingroups"] :
                 usersgroups = self.storage.getMatchingGroups(options["ingroups"])
                 if not usersgroups :
                     raise PyKotaCommandLineError, _("There's no users group matching %s") % " ".join(options["ingroups"].split(','))
-            else :         
+            else :
                 usersgroups = []
-                    
+
             description = options["description"]
             if description :
                 description = description.strip()
-                
+
             comment = options["comment"]
             if comment :
                 comment = comment.strip()
-            email = options["email"]    
+            email = options["email"]
             if email :
                 email = email.strip()
-            skipexisting = options["skipexisting"]    
+            skipexisting = options["skipexisting"]
             groups = options["groups"]
             remove = options["remove"]
             self.storage.beginTransaction()
-            try :    
-                if options["add"] :    
-                    rejectunknown = self.config.getRejectUnknown()    
+            try :
+                if options["add"] :
+                    rejectunknown = self.config.getRejectUnknown()
                     percent.display("%s...\n" % _("Creation"))
                     percent.setSize(len(names))
@@ -325,19 +325,19 @@
                                     try :
                                         grp.getgrnam(ename)
-                                    except KeyError :    
+                                    except KeyError :
                                         self.printInfo(_("Unknown group %s") % ename, "error")
                                         reject = 1
-                                else :    
+                                else :
                                     try :
                                         pwd.getpwnam(ename)
-                                    except KeyError :    
+                                    except KeyError :
                                         self.printInfo(_("Unknown user %s") % ename, "error")
                                         reject = 1
-                            if not reject :        
+                            if not reject :
                                 entry = globals()["Storage%s" % suffix](self.storage, ename)
                                 if groups :
                                     self.modifyEntry(entry, groups, limitby, \
                                                      description)
-                                else :    
+                                else :
                                     self.modifyEntry(entry, groups, limitby, \
                                                      description, overcharge,\
@@ -348,5 +348,5 @@
                                     if skipexisting :
                                         self.logdebug(_("%s %s already exists, skipping.") % (_(suffix), ename))
-                                    else :    
+                                    else :
                                         self.logdebug(_("%s %s already exists, will be modified.") % (_(suffix), ename))
                                         if groups :
@@ -373,21 +373,21 @@
                         if groups :
                             self.modifyEntry(entry, groups, limitby, description)
-                        else :    
+                        else :
                             self.modifyEntry(entry, groups, limitby, description, \
                                              overcharge, balance, balancevalue, \
                                              comment, email)
-                            self.manageUsersGroups(usersgroups, entry, remove)                
-                        entry.save()    
+                            self.manageUsersGroups(usersgroups, entry, remove)
+                        entry.save()
                         percent.oneMore()
-            except :                    
+            except :
                 self.storage.rollbackTransaction()
                 raise
-            else :    
+            else :
                 self.storage.commitTransaction()
-                
+
         if not options["list"] :
             percent.done()
-                     
-if __name__ == "__main__" : 
+
+if __name__ == "__main__" :
     retcode = 0
     try :
@@ -401,13 +401,13 @@
                         "ingroups=", "limitby=", "balance=", "comment=", \
                        ]
-                        
-        
+
+
         # Initializes the command line tool
         manager = PKUsers(doc=__doc__)
         manager.deferredInit()
-        
+
         # parse and checks the command line
         (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
-        
+
         # sets long options
         options["help"] = options["h"] or options["help"]
@@ -415,5 +415,5 @@
         options["add"] = options["a"] or options["add"]
         options["description"] = options["D"] or options["description"]
-        options["delete"] = options["d"] or options["delete"] 
+        options["delete"] = options["d"] or options["delete"]
         options["groups"] = options["g"] or options["groups"]
         options["list"] = options["L"] or options["list"]
@@ -421,10 +421,10 @@
         options["skipexisting"] = options["s"] or options["skipexisting"]
         options["limitby"] = options["l"] or options["limitby"]
-        options["balance"] = options["b"] or options["balance"] 
+        options["balance"] = options["b"] or options["balance"]
         options["ingroups"] = options["i"] or options["ingroups"]
         options["overcharge"] = options["o"] or options["overcharge"]
         options["comment"] = options["C"] or options["comment"] or defaults["comment"]
         options["email"] = options["e"] or options["email"]
-        
+
         if options["help"] :
             manager.display_usage_and_quit()
@@ -436,5 +436,5 @@
            or (options["groups"] and (options["balance"] or options["ingroups"] or options["overcharge"])) :
             raise PyKotaCommandLineError, _("incompatible options, see help.")
-        elif options["remove"] and not options["ingroups"] :    
+        elif options["remove"] and not options["ingroups"] :
             raise PyKotaCommandLineError, _("You have to pass user groups names on the command line")
         elif (not args) and (options["add"] or options["delete"]) :
@@ -442,16 +442,16 @@
         else :
             retcode = manager.main(args, options)
-    except KeyboardInterrupt :        
+    except KeyboardInterrupt :
         logerr("\nInterrupted with Ctrl+C !\n")
         retcode = -3
-    except PyKotaCommandLineError, msg :    
+    except PyKotaCommandLineError, msg :
         logerr("%s : %s\n" % (sys.argv[0], msg))
         retcode = -2
-    except SystemExit :        
+    except SystemExit :
         pass
     except :
         try :
             manager.crashed("pkusers failed")
-        except :    
+        except :
             crashed("pkusers failed")
         retcode = -1
@@ -459,6 +459,6 @@
     try :
         manager.storage.close()
-    except (TypeError, NameError, AttributeError) :    
+    except (TypeError, NameError, AttributeError) :
         pass
-        
-    sys.exit(retcode)    
+
+    sys.exit(retcode)
