Index: /pykota/branches/1.26_fixes/pykota/storage.py
===================================================================
--- /pykota/branches/1.26_fixes/pykota/storage.py (revision 3133)
+++ /pykota/branches/1.26_fixes/pykota/storage.py (revision 3444)
@@ -14,5 +14,5 @@
 # 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, write to the Free Software
@@ -37,6 +37,6 @@
         return self.message
     __str__ = __repr__
-        
-        
+
+
 class StorageObject :
     """Object present in the database."""
@@ -48,19 +48,19 @@
         self.isDirty = False
         self.Exists = False
-        
+
     def setDescription(self, description=None) :
         """Sets the object's description."""
         if description is not None :
             self.Description = str(description)
-            self.isDirty = True    
-            
-    def save(self) :        
+            self.isDirty = True
+
+    def save(self) :
         """Saves the object to the database."""
         if self.isDirty :
             getattr(self.parent, "save%s" % self.__class__.__name__[7:])(self)
             self.isDirty = False
-            
-        
-class StorageUser(StorageObject) :        
+
+
+class StorageUser(StorageObject) :
     """User class."""
     def __init__(self, parent, name) :
@@ -74,10 +74,10 @@
         self.Payments = [] # TODO : maybe handle this smartly for SQL, for now just don't retrieve them
         self.PaymentsBacklog = []
-        
-    def consumeAccountBalance(self, amount) :     
+
+    def consumeAccountBalance(self, amount) :
         """Consumes an amount of money from the user's account balance."""
         self.parent.decreaseUserAccountBalance(self, amount)
         self.AccountBalance = float(self.AccountBalance or 0.0) - amount
-        
+
     def setAccountBalance(self, balance, lifetimepaid, comment="") :
         """Sets the user's account balance in case he pays more money."""
@@ -88,17 +88,17 @@
             self.PaymentsBacklog.append((diff, comment))
         self.isDirty = True
-        
-    def save(self) :    
+
+    def save(self) :
         """Saves an user and flush its payments backlog."""
         for (value, comment) in self.PaymentsBacklog :
             self.parent.writeNewPayment(self, value, comment)
-        self.PaymentsBacklog = []    
-        StorageObject.save(self)    
-        
-    def setLimitBy(self, limitby) :    
+        self.PaymentsBacklog = []
+        StorageObject.save(self)
+
+    def setLimitBy(self, limitby) :
         """Sets the user's limiting factor."""
         try :
             limitby = limitby.lower()
-        except AttributeError :    
+        except AttributeError :
             limitby = "quota"
         if limitby in ["quota", "balance", \
@@ -106,16 +106,16 @@
             self.LimitBy = limitby
             self.isDirty = True
-        
-    def setOverChargeFactor(self, factor) :    
+
+    def setOverChargeFactor(self, factor) :
         """Sets the user's overcharging coefficient."""
         self.OverCharge = factor
         self.isDirty = True
-        
-    def setEmail(self, email) :    
+
+    def setEmail(self, email) :
         """Sets the user's email address."""
         self.Email = email
         self.isDirty = True
-        
-    def delete(self) :    
+
+    def delete(self) :
         """Deletes an user from the database."""
         self.parent.deleteUser(self)
@@ -126,13 +126,13 @@
                     self.parent.flushEntry("USERPQUOTAS", "%s@%s" % (v.User.Name, v.Printer.Name))
         self.Exists = False
-        self.isDirty = False            
-        
+        self.isDirty = False
+
     def refund(self, amount, reason) :
         """Refunds a number of credits to an user."""
         self.consumeAccountBalance(-amount)
         self.parent.writeNewPayment(self, -amount, reason)
-        
-        
-class StorageGroup(StorageObject) :        
+
+
+class StorageGroup(StorageObject) :
     """User class."""
     def __init__(self, parent, name) :
@@ -142,24 +142,24 @@
         self.AccountBalance = None
         self.LifeTimePaid = None
-        
-    def setLimitBy(self, limitby) :    
+
+    def setLimitBy(self, limitby) :
         """Sets the user's limiting factor."""
         try :
             limitby = limitby.lower()
-        except AttributeError :    
+        except AttributeError :
             limitby = "quota"
         if limitby in ["quota", "balance", "noquota"] :
             self.LimitBy = limitby
             self.isDirty = True
-        
+
     def addUserToGroup(self, user) :
         """Adds an user to an users group."""
         self.parent.addUserToGroup(user, self)
-        
+
     def delUserFromGroup(self, user) :
         """Removes an user from an users group."""
         self.parent.delUserFromGroup(user, self)
-        
-    def delete(self) :    
+
+    def delete(self) :
         """Deletes a group from the database."""
         self.parent.deleteGroup(self)
@@ -170,7 +170,7 @@
                     self.parent.flushEntry("GROUPPQUOTAS", "%s@%s" % (v.Group.Name, v.Printer.Name))
         self.Exists = False
-        self.isDirty = False            
-        
-        
+        self.isDirty = False
+
+
 class StoragePrinter(StorageObject) :
     """Printer class."""
@@ -182,12 +182,12 @@
         self.MaxJobSize = None
         self.PassThrough = None
-        
-    def __getattr__(self, name) :    
+
+    def __getattr__(self, name) :
         """Delays data retrieval until it's really needed."""
-        if name == "LastJob" : 
+        if name == "LastJob" :
             self.LastJob = self.parent.getPrinterLastJob(self)
             self.parent.tool.logdebug("Lazy retrieval of last job for printer %s" % self.Name)
             return self.LastJob
-        elif name == "Coefficients" :    
+        elif name == "Coefficients" :
             self.Coefficients = self.parent.tool.config.getPrinterCoefficients(self.Name)
             self.parent.tool.logdebug("Lazy retrieval of coefficients for printer %s : %s" % (self.Name, self.Coefficients))
@@ -195,44 +195,44 @@
         else :
             raise AttributeError, name
-            
+
     def addJobToHistory(self, jobid, user, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None, clienthost=None, jobsizebytes=None, jobmd5sum=None, jobpages=None, jobbilling=None, precomputedsize=None, precomputedprice=None) :
         """Adds a job to the printer's history."""
         self.parent.writeJobNew(self, user, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options, clienthost, jobsizebytes, jobmd5sum, jobpages, jobbilling, precomputedsize, precomputedprice)
         # TODO : update LastJob object ? Probably not needed.
-        
-    def addPrinterToGroup(self, printer) :    
+
+    def addPrinterToGroup(self, printer) :
         """Adds a printer to a printer group."""
         if (printer not in self.parent.getParentPrinters(self)) and (printer.ident != self.ident) :
             self.parent.writePrinterToGroup(self, printer)
             # TODO : reset cached value for printer parents, or add new parent to cached value
-            
-    def delPrinterFromGroup(self, printer) :    
+
+    def delPrinterFromGroup(self, printer) :
         """Deletes a printer from a printer group."""
         self.parent.removePrinterFromGroup(self, printer)
         # TODO : reset cached value for printer parents, or add new parent to cached value
-        
-    def setPrices(self, priceperpage = None, priceperjob = None) :    
+
+    def setPrices(self, priceperpage = None, priceperjob = None) :
         """Sets the printer's prices."""
         if priceperpage is None :
             priceperpage = self.PricePerPage or 0.0
-        else :    
+        else :
             self.PricePerPage = float(priceperpage)
-        if priceperjob is None :    
+        if priceperjob is None :
             priceperjob = self.PricePerJob or 0.0
-        else :    
+        else :
             self.PricePerJob = float(priceperjob)
-        self.isDirty = True    
-        
+        self.isDirty = True
+
     def setPassThrough(self, passthrough) :
         """Sets the printer's passthrough mode."""
         self.PassThrough = passthrough
         self.isDirty = True
-        
+
     def setMaxJobSize(self, maxjobsize) :
         """Sets the printer's maximal job size."""
         self.MaxJobSize = maxjobsize
         self.isDirty = True
-        
-    def delete(self) :    
+
+    def delete(self) :
         """Deletes a printer from the database."""
         self.parent.deletePrinter(self)
@@ -246,7 +246,7 @@
                     self.parent.flushEntry("GROUPPQUOTAS", "%s@%s" % (v.Group.Name, v.Printer.Name))
         self.Exists = False
-        self.isDirty = False            
-        
-        
+        self.isDirty = False
+
+
 class StorageUserPQuota(StorageObject) :
     """User Print Quota class."""
@@ -262,14 +262,14 @@
         self.WarnCount = None
         self.MaxJobSize = None
-        
-    def __getattr__(self, name) :    
+
+    def __getattr__(self, name) :
         """Delays data retrieval until it's really needed."""
-        if name == "ParentPrintersUserPQuota" : 
+        if name == "ParentPrintersUserPQuota" :
             self.ParentPrintersUserPQuota = (self.User.Exists and self.Printer.Exists and self.parent.getParentPrintersUserPQuota(self)) or []
             return self.ParentPrintersUserPQuota
         else :
             raise AttributeError, name
-        
-    def setDateLimit(self, datelimit) :    
+
+    def setDateLimit(self, datelimit) :
         """Sets the date limit for this quota."""
         datelimit = DateTime.ISO.ParseDateTime(str(datelimit)[:19])
@@ -277,6 +277,6 @@
         self.parent.writeUserPQuotaDateLimit(self, date)
         self.DateLimit = date
-        
-    def setLimits(self, softlimit, hardlimit) :    
+
+    def setLimits(self, softlimit, hardlimit) :
         """Sets the soft and hard limit for this quota."""
         self.SoftLimit = softlimit
@@ -285,5 +285,5 @@
         self.WarnCount = 0
         self.isDirty = True
-        
+
     def setUsage(self, used) :
         """Sets the PageCounter and LifePageCounter to used, or if used is + or - prefixed, changes the values of {Life,}PageCounter by that amount."""
@@ -302,25 +302,25 @@
         self.parent.increaseUserPQuotaWarnCount(self)
         self.WarnCount = (self.WarnCount or 0) + 1
-        
+
     def resetDenyBannerCounter(self) :
         """Resets the deny banner counter for this user quota."""
         self.parent.writeUserPQuotaWarnCount(self, 0)
         self.WarnCount = 0
-        
-    def reset(self) :    
+
+    def reset(self) :
         """Resets page counter to 0."""
         self.PageCounter = 0
         self.DateLimit = None
         self.isDirty = True
-        
-    def hardreset(self) :    
+
+    def hardreset(self) :
         """Resets actual and life time page counters to 0."""
         self.PageCounter = self.LifePageCounter = 0
         self.DateLimit = None
         self.isDirty = True
-        
-    def computeJobPrice(self, jobsize, inkusage=[]) :    
+
+    def computeJobPrice(self, jobsize, inkusage=[]) :
         """Computes the job price as the sum of all parent printers' prices + current printer's ones."""
-        totalprice = 0.0    
+        totalprice = 0.0
         if jobsize :
             if self.User.OverCharge != 0.0 :    # optimization, but TODO : beware of rounding errors
@@ -330,12 +330,12 @@
                     if not inkusage :
                         totalprice += (jobsize * pageprice)
-                    else :    
+                    else :
                         for pageindex in range(jobsize) :
                             try :
                                 usage = inkusage[pageindex]
-                            except IndexError :    
+                            except IndexError :
                                 self.parent.tool.logdebug("No ink usage information. Using base cost of %f credits for page %i." % (pageprice, pageindex+1))
                                 totalprice += pageprice
-                            else :    
+                            else :
                                 coefficients = self.Printer.Coefficients
                                 for (ink, value) in usage.items() :
@@ -346,10 +346,10 @@
                                     totalprice += inkprice
         if self.User.OverCharge != 1.0 : # TODO : beware of rounding errors
-            overcharged = totalprice * self.User.OverCharge        
+            overcharged = totalprice * self.User.OverCharge
             self.parent.tool.logdebug("Overcharging %s by a factor of %s ===> User %s will be charged for %s credits." % (totalprice, self.User.OverCharge, self.User.Name, overcharged))
             return overcharged
-        else :    
+        else :
             return totalprice
-            
+
     def increasePagesUsage(self, jobsize, inkusage=[]) :
         """Increase the value of used pages and money."""
@@ -363,6 +363,6 @@
                 upq.LifePageCounter = int(upq.LifePageCounter or 0) + jobsize
         return jobprice
-        
-    def delete(self) :    
+
+    def delete(self) :
         """Deletes an user print quota entry from the database."""
         self.parent.deleteUserPQuota(self)
@@ -371,12 +371,12 @@
         self.Exists = False
         self.isDirty = False
-        
-    def refund(self, nbpages) :    
+
+    def refund(self, nbpages) :
         """Refunds a number of pages to an user on a particular printer."""
         self.parent.increaseUserPQuotaPagesCounters(self, -nbpages)
         self.PageCounter = int(self.PageCounter or 0) - nbpages
         self.LifePageCounter = int(self.LifePageCounter or 0) - nbpages
-        
-        
+
+
 class StorageGroupPQuota(StorageObject) :
     """Group Print Quota class."""
@@ -391,14 +391,14 @@
         self.DateLimit = None
         self.MaxJobSize = None
-        
-    def __getattr__(self, name) :    
+
+    def __getattr__(self, name) :
         """Delays data retrieval until it's really needed."""
-        if name == "ParentPrintersGroupPQuota" : 
+        if name == "ParentPrintersGroupPQuota" :
             self.ParentPrintersGroupPQuota = (self.Group.Exists and self.Printer.Exists and self.parent.getParentPrintersGroupPQuota(self)) or []
             return self.ParentPrintersGroupPQuota
         else :
             raise AttributeError, name
-        
-    def reset(self) :    
+
+    def reset(self) :
         """Resets page counter to 0."""
         for user in self.parent.getGroupMembers(self.Group) :
@@ -409,6 +409,6 @@
         self.DateLimit = None
         self.isDirty = True
-        
-    def hardreset(self) :    
+
+    def hardreset(self) :
         """Resets actual and life time page counters to 0."""
         for user in self.parent.getGroupMembers(self.Group) :
@@ -419,6 +419,6 @@
         self.DateLimit = None
         self.isDirty = True
-        
-    def setDateLimit(self, datelimit) :    
+
+    def setDateLimit(self, datelimit) :
         """Sets the date limit for this quota."""
         datelimit = DateTime.ISO.ParseDateTime(str(datelimit)[:19])
@@ -431,6 +431,6 @@
         self.parent.writeGroupPQuotaDateLimit(self, date)
         self.DateLimit = date
-        
-    def setLimits(self, softlimit, hardlimit) :    
+
+    def setLimits(self, softlimit, hardlimit) :
         """Sets the soft and hard limit for this quota."""
         self.SoftLimit = softlimit
@@ -438,6 +438,6 @@
         self.DateLimit = None
         self.isDirty = True
-        
-    def delete(self) :    
+
+    def delete(self) :
         """Deletes a group print quota entry from the database."""
         self.parent.deleteGroupPQuota(self)
@@ -446,6 +446,6 @@
         self.Exists = False
         self.isDirty = False
-        
-        
+
+
 class StorageJob(StorageObject) :
     """Printer's Job class."""
@@ -471,32 +471,36 @@
         self.PrecomputedJobSize = None
         self.PrecomputedJobPrice = None
-        
-    def __getattr__(self, name) :    
+
+    def __getattr__(self, name) :
         """Delays data retrieval until it's really needed."""
-        if name == "User" : 
+        if name == "User" :
             self.User = self.parent.getUser(self.UserName)
             return self.User
-        elif name == "Printer" :    
+        elif name == "Printer" :
             self.Printer = self.parent.getPrinter(self.PrinterName)
             return self.Printer
         else :
             raise AttributeError, name
-            
-    def refund(self, reason) :        
+
+    def refund(self, reason) :
         """Refund a particular print job."""
         if (not self.JobSize) or (self.JobAction in ("DENY", "CANCEL", "REFUND")) :
             return
-            
+        try :
+            loginname = os.getlogin()
+        except OSError :
+            import pwd
+            loginname = pwd.getpwuid(os.getuid()).pw_name
         basereason = _("Refunded %i pages and %.3f credits by %s (%s) on %s") \
                         % (self.JobSize,
                            self.JobPrice,
                            self.parent.tool.originalUserName,
-                           os.getlogin(),
+                           loginname,
                            str(DateTime.now())[:19])
-        if reason :                                               
+        if reason :
             reason = "%s : %s" % (basereason, reason)
-        else :    
+        else :
             reason = basereason
-        self.parent.tool.logdebug("Refunding job %s..." % self.ident)    
+        self.parent.tool.logdebug("Refunding job %s..." % self.ident)
         self.parent.beginTransaction()
         try :
@@ -504,21 +508,21 @@
                 bcode = self.parent.getBillingCode(self.JobBillingCode)
                 bcode.refund(self.JobSize, self.JobPrice)
-                
+
             if self.User.Exists :
                 self.User.refund(self.JobPrice, reason)
-                if self.Printer.Exists :    
-                    upq = self.parent.getUserPQuota(self.User, self.Printer)    
+                if self.Printer.Exists :
+                    upq = self.parent.getUserPQuota(self.User, self.Printer)
                     if upq.Exists :
                         upq.refund(self.JobSize)
             self.parent.refundJob(self.ident)
-        except :        
+        except :
             self.parent.rollbackTransaction()
             self.parent.tool.logdebug("Error while refunding job %s." % self.ident)
             raise
-        else :    
+        else :
             self.parent.commitTransaction()
             self.parent.tool.logdebug("Job %s refunded." % self.ident)
-        
-        
+
+
 class StorageLastJob(StorageJob) :
     """Printer's Last Job class."""
@@ -527,6 +531,6 @@
         self.PrinterName = printer.Name # not needed
         self.Printer = printer
-        
-        
+
+
 class StorageBillingCode(StorageObject) :
     """Billing code class."""
@@ -536,6 +540,6 @@
         self.PageCounter = None
         self.Balance = None
-        
-    def delete(self) :    
+
+    def delete(self) :
         """Deletes the billing code from the database."""
         self.parent.deleteBillingCode(self)
@@ -543,11 +547,11 @@
         self.isDirty = False
         self.Exists = False
-        
-    def reset(self, balance=0.0, pagecounter=0) :    
+
+    def reset(self, balance=0.0, pagecounter=0) :
         """Resets the pagecounter and balance for this billing code."""
         self.Balance = balance
         self.PageCounter = pagecounter
         self.isDirty = True
-        
+
     def consume(self, pages, price) :
         """Consumes some pages and credits for this billing code."""
@@ -556,10 +560,10 @@
             self.PageCounter += pages
             self.Balance -= price
-           
+
     def refund(self, pages, price) :
         """Refunds a particular billing code."""
         self.consume(-pages, -price)
-        
-        
+
+
 class BaseStorage :
     def __init__(self, pykotatool) :
@@ -582,13 +586,13 @@
                             "LASTJOBS" : {}, \
                             "BILLINGCODES" : {} }
-        
-    def close(self) :    
+
+    def close(self) :
         """Must be overriden in children classes."""
         raise RuntimeError, "BaseStorage.close() must be overriden !"
-        
-    def __del__(self) :        
+
+    def __del__(self) :
         """Ensures that the database connection is closed."""
         self.close()
-        
+
     def getFromCache(self, cachetype, key) :
         """Tries to extract something from the cache."""
@@ -597,25 +601,25 @@
             if entry is not None :
                 self.tool.logdebug("Cache hit (%s->%s)" % (cachetype, key))
-            else :    
+            else :
                 self.tool.logdebug("Cache miss (%s->%s)" % (cachetype, key))
-            return entry    
-            
-    def cacheEntry(self, cachetype, key, value) :        
+            return entry
+
+    def cacheEntry(self, cachetype, key, value) :
         """Puts an entry in the cache."""
         if self.usecache and getattr(value, "Exists", 0) :
             self.caches[cachetype][key] = value
             self.tool.logdebug("Cache store (%s->%s)" % (cachetype, key))
-            
-    def flushEntry(self, cachetype, key) :        
+
+    def flushEntry(self, cachetype, key) :
         """Removes an entry from the cache."""
         if self.usecache :
             try :
                 del self.caches[cachetype][key]
-            except KeyError :    
+            except KeyError :
                 pass
-            else :    
+            else :
                 self.tool.logdebug("Cache flush (%s->%s)" % (cachetype, key))
-            
-    def getUser(self, username) :        
+
+    def getUser(self, username) :
         """Returns the user from cache."""
         user = self.getFromCache("USERS", username)
@@ -623,7 +627,7 @@
             user = self.getUserFromBackend(username)
             self.cacheEntry("USERS", username, user)
-        return user    
-        
-    def getGroup(self, groupname) :        
+        return user
+
+    def getGroup(self, groupname) :
         """Returns the group from cache."""
         group = self.getFromCache("GROUPS", groupname)
@@ -631,7 +635,7 @@
             group = self.getGroupFromBackend(groupname)
             self.cacheEntry("GROUPS", groupname, group)
-        return group    
-        
-    def getPrinter(self, printername) :        
+        return group
+
+    def getPrinter(self, printername) :
         """Returns the printer from cache."""
         printer = self.getFromCache("PRINTERS", printername)
@@ -639,7 +643,7 @@
             printer = self.getPrinterFromBackend(printername)
             self.cacheEntry("PRINTERS", printername, printer)
-        return printer    
-        
-    def getUserPQuota(self, user, printer) :        
+        return printer
+
+    def getUserPQuota(self, user, printer) :
         """Returns the user quota information from cache."""
         useratprinter = "%s@%s" % (user.Name, printer.Name)
@@ -648,7 +652,7 @@
             upquota = self.getUserPQuotaFromBackend(user, printer)
             self.cacheEntry("USERPQUOTAS", useratprinter, upquota)
-        return upquota    
-        
-    def getGroupPQuota(self, group, printer) :        
+        return upquota
+
+    def getGroupPQuota(self, group, printer) :
         """Returns the group quota information from cache."""
         groupatprinter = "%s@%s" % (group.Name, printer.Name)
@@ -657,7 +661,7 @@
             gpquota = self.getGroupPQuotaFromBackend(group, printer)
             self.cacheEntry("GROUPPQUOTAS", groupatprinter, gpquota)
-        return gpquota    
-        
-    def getPrinterLastJob(self, printer) :        
+        return gpquota
+
+    def getPrinterLastJob(self, printer) :
         """Extracts last job information for a given printer from cache."""
         lastjob = self.getFromCache("LASTJOBS", printer.Name)
@@ -665,7 +669,7 @@
             lastjob = self.getPrinterLastJobFromBackend(printer)
             self.cacheEntry("LASTJOBS", printer.Name, lastjob)
-        return lastjob    
-        
-    def getBillingCode(self, label) :        
+        return lastjob
+
+    def getBillingCode(self, label) :
         """Returns the user from cache."""
         code = self.getFromCache("BILLINGCODES", label)
@@ -674,6 +678,6 @@
             self.cacheEntry("BILLINGCODES", label, code)
         return code
-        
-    def getParentPrinters(self, printer) :    
+
+    def getParentPrinters(self, printer) :
         """Extracts parent printers information for a given printer from cache."""
         if self.usecache :
@@ -684,15 +688,15 @@
             else :
                 self.tool.logdebug("Cache hit (%s->Parents)" % printer.Name)
-        else :        
+        else :
             printer.Parents = self.getParentPrintersFromBackend(printer)
-        for parent in printer.Parents[:] :    
+        for parent in printer.Parents[:] :
             printer.Parents.extend(self.getParentPrinters(parent))
-        uniquedic = {}    
+        uniquedic = {}
         for parent in printer.Parents :
             uniquedic[parent.Name] = parent
-        printer.Parents = uniquedic.values()    
+        printer.Parents = uniquedic.values()
         return printer.Parents
-        
-    def getGroupMembers(self, group) :        
+
+    def getGroupMembers(self, group) :
         """Returns the group's members list from in-group cache."""
         if self.usecache :
@@ -703,9 +707,9 @@
             else :
                 self.tool.logdebug("Cache hit (%s->Members)" % group.Name)
-        else :        
+        else :
             group.Members = self.getGroupMembersFromBackend(group)
-        return group.Members    
-        
-    def getUserGroups(self, user) :        
+        return group.Members
+
+    def getUserGroups(self, user) :
         """Returns the user's groups list from in-user cache."""
         if self.usecache :
@@ -716,9 +720,9 @@
             else :
                 self.tool.logdebug("Cache hit (%s->Groups)" % user.Name)
-        else :        
+        else :
             user.Groups = self.getUserGroupsFromBackend(user)
-        return user.Groups   
-        
-    def getParentPrintersUserPQuota(self, userpquota) :     
+        return user.Groups
+
+    def getParentPrintersUserPQuota(self, userpquota) :
         """Returns all user print quota on the printer and all its parents recursively."""
         upquotas = [ ]
@@ -727,7 +731,7 @@
             if upq.Exists :
                 upquotas.append(upq)
-        return upquotas        
-        
-    def getParentPrintersGroupPQuota(self, grouppquota) :     
+        return upquotas
+
+    def getParentPrintersGroupPQuota(self, grouppquota) :
         """Returns all group print quota on the printer and all its parents recursively."""
         gpquotas = [ ]
@@ -736,26 +740,26 @@
             if gpq.Exists :
                 gpquotas.append(gpq)
-        return gpquotas        
-        
+        return gpquotas
+
     def databaseToUserCharset(self, text) :
         """Converts from database format (UTF-8) to user's charset."""
         return self.tool.UTF8ToUserCharset(text)
-        
+
     def userCharsetToDatabase(self, text) :
         """Converts from user's charset to database format (UTF-8)."""
         return self.tool.userCharsetToUTF8(text)
-        
-    def cleanDates(self, startdate, enddate) :    
+
+    def cleanDates(self, startdate, enddate) :
         """Clean the dates to create a correct filter."""
-        if startdate :    
+        if startdate :
             startdate = startdate.strip().lower()
-        if enddate :    
+        if enddate :
             enddate = enddate.strip().lower()
-        if (not startdate) and (not enddate) :    
+        if (not startdate) and (not enddate) :
             return (None, None)
-            
-        now = DateTime.now()    
+
+        now = DateTime.now()
         nameddates = ('yesterday', 'today', 'now', 'tomorrow')
-        datedict = { "start" : startdate, "end" : enddate }    
+        datedict = { "start" : startdate, "end" : enddate }
         for limit in datedict.keys() :
             dateval = datedict[limit]
@@ -765,7 +769,7 @@
                         try :
                             offset = int(dateval[len(name):])
-                        except :    
+                        except :
                             offset = 0
-                        dateval = dateval[:len(name)]    
+                        dateval = dateval[:len(name)]
                         if limit == "start" :
                             if dateval == "yesterday" :
@@ -787,61 +791,61 @@
                                 dateval = (now + 1 + offset).Format("%Y%m%d235959")
                         break
-                        
+
                 if not dateval.isdigit() :
                     dateval = None
-                else :    
+                else :
                     lgdateval = len(dateval)
                     if lgdateval == 4 :
-                        if limit == "start" : 
+                        if limit == "start" :
                             dateval = "%s0101 00:00:00" % dateval
-                        else :  
+                        else :
                             dateval = "%s1231 23:59:59" % dateval
                     elif lgdateval == 6 :
-                        if limit == "start" : 
+                        if limit == "start" :
                             dateval = "%s01 00:00:00" % dateval
-                        else :  
+                        else :
                             mxdate = DateTime.ISO.ParseDateTime("%s01 00:00:00" % dateval)
                             dateval = "%s%02i 23:59:59" % (dateval, mxdate.days_in_month)
                     elif lgdateval == 8 :
-                        if limit == "start" : 
+                        if limit == "start" :
                             dateval = "%s 00:00:00" % dateval
-                        else :  
+                        else :
                             dateval = "%s 23:59:59" % dateval
                     elif lgdateval == 10 :
-                        if limit == "start" : 
+                        if limit == "start" :
                             dateval = "%s %s:00:00" % (dateval[:8], dateval[8:])
-                        else :  
+                        else :
                             dateval = "%s %s:59:59" % (dateval[:8], dateval[8:])
                     elif lgdateval == 12 :
-                        if limit == "start" : 
+                        if limit == "start" :
                             dateval = "%s %s:%s:00" % (dateval[:8], dateval[8:10], dateval[10:])
-                        else :  
+                        else :
                             dateval = "%s %s:%s:59" % (dateval[:8], dateval[8:10], dateval[10:])
-                    elif lgdateval == 14 :        
+                    elif lgdateval == 14 :
                         dateval = "%s %s:%s:%s" % (dateval[:8], dateval[8:10], dateval[10:12], dateval[12:])
-                    else :    
+                    else :
                         dateval = None
-                    try :    
+                    try :
                         DateTime.ISO.ParseDateTime(dateval[:19])
-                    except :    
+                    except :
                         dateval = None
-                datedict[limit] = dateval    
+                datedict[limit] = dateval
         (start, end) = (datedict["start"], datedict["end"])
         if start and end and (start > end) :
             (start, end) = (end, start)
-        try :    
+        try :
             if len(start) == 17 :
                 start = "%s-%s-%s %s" % (start[0:4], start[4:6], start[6:8], start[9:])
-        except TypeError :        
+        except TypeError :
             pass
-            
-        try :    
+
+        try :
             if len(end) == 17 :
                 end = "%s-%s-%s %s" % (end[0:4], end[4:6], end[6:8], end[9:])
-        except TypeError :        
+        except TypeError :
             pass
-            
-        return (start, end)    
-        
+
+        return (start, end)
+
 def openConnection(pykotatool) :
     """Returns a connection handle to the appropriate database."""
@@ -849,5 +853,5 @@
     backend = backendinfo["storagebackend"]
     try :
-        storagebackend = imp.load_source("storagebackend", 
+        storagebackend = imp.load_source("storagebackend",
                                          os.path.join(os.path.dirname(__file__),
                                                       "storages",
@@ -855,5 +859,5 @@
     except ImportError :
         raise PyKotaStorageError, _("Unsupported quota storage backend %s") % backend
-    else :    
+    else :
         host = backendinfo["storageserver"]
         database = backendinfo["storagename"]
