- Timestamp:
- 10/26/08 20:39:19 (16 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/branches/1.26_fixes/pykota/storage.py
r3133 r3444 14 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 # GNU General Public License for more details. 16 # 16 # 17 17 # You should have received a copy of the GNU General Public License 18 18 # along with this program; if not, write to the Free Software … … 37 37 return self.message 38 38 __str__ = __repr__ 39 40 39 40 41 41 class StorageObject : 42 42 """Object present in the database.""" … … 48 48 self.isDirty = False 49 49 self.Exists = False 50 50 51 51 def setDescription(self, description=None) : 52 52 """Sets the object's description.""" 53 53 if description is not None : 54 54 self.Description = str(description) 55 self.isDirty = True 56 57 def save(self) : 55 self.isDirty = True 56 57 def save(self) : 58 58 """Saves the object to the database.""" 59 59 if self.isDirty : 60 60 getattr(self.parent, "save%s" % self.__class__.__name__[7:])(self) 61 61 self.isDirty = False 62 63 64 class StorageUser(StorageObject) : 62 63 64 class StorageUser(StorageObject) : 65 65 """User class.""" 66 66 def __init__(self, parent, name) : … … 74 74 self.Payments = [] # TODO : maybe handle this smartly for SQL, for now just don't retrieve them 75 75 self.PaymentsBacklog = [] 76 77 def consumeAccountBalance(self, amount) : 76 77 def consumeAccountBalance(self, amount) : 78 78 """Consumes an amount of money from the user's account balance.""" 79 79 self.parent.decreaseUserAccountBalance(self, amount) 80 80 self.AccountBalance = float(self.AccountBalance or 0.0) - amount 81 81 82 82 def setAccountBalance(self, balance, lifetimepaid, comment="") : 83 83 """Sets the user's account balance in case he pays more money.""" … … 88 88 self.PaymentsBacklog.append((diff, comment)) 89 89 self.isDirty = True 90 91 def save(self) : 90 91 def save(self) : 92 92 """Saves an user and flush its payments backlog.""" 93 93 for (value, comment) in self.PaymentsBacklog : 94 94 self.parent.writeNewPayment(self, value, comment) 95 self.PaymentsBacklog = [] 96 StorageObject.save(self) 97 98 def setLimitBy(self, limitby) : 95 self.PaymentsBacklog = [] 96 StorageObject.save(self) 97 98 def setLimitBy(self, limitby) : 99 99 """Sets the user's limiting factor.""" 100 100 try : 101 101 limitby = limitby.lower() 102 except AttributeError : 102 except AttributeError : 103 103 limitby = "quota" 104 104 if limitby in ["quota", "balance", \ … … 106 106 self.LimitBy = limitby 107 107 self.isDirty = True 108 109 def setOverChargeFactor(self, factor) : 108 109 def setOverChargeFactor(self, factor) : 110 110 """Sets the user's overcharging coefficient.""" 111 111 self.OverCharge = factor 112 112 self.isDirty = True 113 114 def setEmail(self, email) : 113 114 def setEmail(self, email) : 115 115 """Sets the user's email address.""" 116 116 self.Email = email 117 117 self.isDirty = True 118 119 def delete(self) : 118 119 def delete(self) : 120 120 """Deletes an user from the database.""" 121 121 self.parent.deleteUser(self) … … 126 126 self.parent.flushEntry("USERPQUOTAS", "%s@%s" % (v.User.Name, v.Printer.Name)) 127 127 self.Exists = False 128 self.isDirty = False 129 128 self.isDirty = False 129 130 130 def refund(self, amount, reason) : 131 131 """Refunds a number of credits to an user.""" 132 132 self.consumeAccountBalance(-amount) 133 133 self.parent.writeNewPayment(self, -amount, reason) 134 135 136 class StorageGroup(StorageObject) : 134 135 136 class StorageGroup(StorageObject) : 137 137 """User class.""" 138 138 def __init__(self, parent, name) : … … 142 142 self.AccountBalance = None 143 143 self.LifeTimePaid = None 144 145 def setLimitBy(self, limitby) : 144 145 def setLimitBy(self, limitby) : 146 146 """Sets the user's limiting factor.""" 147 147 try : 148 148 limitby = limitby.lower() 149 except AttributeError : 149 except AttributeError : 150 150 limitby = "quota" 151 151 if limitby in ["quota", "balance", "noquota"] : 152 152 self.LimitBy = limitby 153 153 self.isDirty = True 154 154 155 155 def addUserToGroup(self, user) : 156 156 """Adds an user to an users group.""" 157 157 self.parent.addUserToGroup(user, self) 158 158 159 159 def delUserFromGroup(self, user) : 160 160 """Removes an user from an users group.""" 161 161 self.parent.delUserFromGroup(user, self) 162 163 def delete(self) : 162 163 def delete(self) : 164 164 """Deletes a group from the database.""" 165 165 self.parent.deleteGroup(self) … … 170 170 self.parent.flushEntry("GROUPPQUOTAS", "%s@%s" % (v.Group.Name, v.Printer.Name)) 171 171 self.Exists = False 172 self.isDirty = False 173 174 172 self.isDirty = False 173 174 175 175 class StoragePrinter(StorageObject) : 176 176 """Printer class.""" … … 182 182 self.MaxJobSize = None 183 183 self.PassThrough = None 184 185 def __getattr__(self, name) : 184 185 def __getattr__(self, name) : 186 186 """Delays data retrieval until it's really needed.""" 187 if name == "LastJob" : 187 if name == "LastJob" : 188 188 self.LastJob = self.parent.getPrinterLastJob(self) 189 189 self.parent.tool.logdebug("Lazy retrieval of last job for printer %s" % self.Name) 190 190 return self.LastJob 191 elif name == "Coefficients" : 191 elif name == "Coefficients" : 192 192 self.Coefficients = self.parent.tool.config.getPrinterCoefficients(self.Name) 193 193 self.parent.tool.logdebug("Lazy retrieval of coefficients for printer %s : %s" % (self.Name, self.Coefficients)) … … 195 195 else : 196 196 raise AttributeError, name 197 197 198 198 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) : 199 199 """Adds a job to the printer's history.""" 200 200 self.parent.writeJobNew(self, user, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options, clienthost, jobsizebytes, jobmd5sum, jobpages, jobbilling, precomputedsize, precomputedprice) 201 201 # TODO : update LastJob object ? Probably not needed. 202 203 def addPrinterToGroup(self, printer) : 202 203 def addPrinterToGroup(self, printer) : 204 204 """Adds a printer to a printer group.""" 205 205 if (printer not in self.parent.getParentPrinters(self)) and (printer.ident != self.ident) : 206 206 self.parent.writePrinterToGroup(self, printer) 207 207 # TODO : reset cached value for printer parents, or add new parent to cached value 208 209 def delPrinterFromGroup(self, printer) : 208 209 def delPrinterFromGroup(self, printer) : 210 210 """Deletes a printer from a printer group.""" 211 211 self.parent.removePrinterFromGroup(self, printer) 212 212 # TODO : reset cached value for printer parents, or add new parent to cached value 213 214 def setPrices(self, priceperpage = None, priceperjob = None) : 213 214 def setPrices(self, priceperpage = None, priceperjob = None) : 215 215 """Sets the printer's prices.""" 216 216 if priceperpage is None : 217 217 priceperpage = self.PricePerPage or 0.0 218 else : 218 else : 219 219 self.PricePerPage = float(priceperpage) 220 if priceperjob is None : 220 if priceperjob is None : 221 221 priceperjob = self.PricePerJob or 0.0 222 else : 222 else : 223 223 self.PricePerJob = float(priceperjob) 224 self.isDirty = True 225 224 self.isDirty = True 225 226 226 def setPassThrough(self, passthrough) : 227 227 """Sets the printer's passthrough mode.""" 228 228 self.PassThrough = passthrough 229 229 self.isDirty = True 230 230 231 231 def setMaxJobSize(self, maxjobsize) : 232 232 """Sets the printer's maximal job size.""" 233 233 self.MaxJobSize = maxjobsize 234 234 self.isDirty = True 235 236 def delete(self) : 235 236 def delete(self) : 237 237 """Deletes a printer from the database.""" 238 238 self.parent.deletePrinter(self) … … 246 246 self.parent.flushEntry("GROUPPQUOTAS", "%s@%s" % (v.Group.Name, v.Printer.Name)) 247 247 self.Exists = False 248 self.isDirty = False 249 250 248 self.isDirty = False 249 250 251 251 class StorageUserPQuota(StorageObject) : 252 252 """User Print Quota class.""" … … 262 262 self.WarnCount = None 263 263 self.MaxJobSize = None 264 265 def __getattr__(self, name) : 264 265 def __getattr__(self, name) : 266 266 """Delays data retrieval until it's really needed.""" 267 if name == "ParentPrintersUserPQuota" : 267 if name == "ParentPrintersUserPQuota" : 268 268 self.ParentPrintersUserPQuota = (self.User.Exists and self.Printer.Exists and self.parent.getParentPrintersUserPQuota(self)) or [] 269 269 return self.ParentPrintersUserPQuota 270 270 else : 271 271 raise AttributeError, name 272 273 def setDateLimit(self, datelimit) : 272 273 def setDateLimit(self, datelimit) : 274 274 """Sets the date limit for this quota.""" 275 275 datelimit = DateTime.ISO.ParseDateTime(str(datelimit)[:19]) … … 277 277 self.parent.writeUserPQuotaDateLimit(self, date) 278 278 self.DateLimit = date 279 280 def setLimits(self, softlimit, hardlimit) : 279 280 def setLimits(self, softlimit, hardlimit) : 281 281 """Sets the soft and hard limit for this quota.""" 282 282 self.SoftLimit = softlimit … … 285 285 self.WarnCount = 0 286 286 self.isDirty = True 287 287 288 288 def setUsage(self, used) : 289 289 """Sets the PageCounter and LifePageCounter to used, or if used is + or - prefixed, changes the values of {Life,}PageCounter by that amount.""" … … 302 302 self.parent.increaseUserPQuotaWarnCount(self) 303 303 self.WarnCount = (self.WarnCount or 0) + 1 304 304 305 305 def resetDenyBannerCounter(self) : 306 306 """Resets the deny banner counter for this user quota.""" 307 307 self.parent.writeUserPQuotaWarnCount(self, 0) 308 308 self.WarnCount = 0 309 310 def reset(self) : 309 310 def reset(self) : 311 311 """Resets page counter to 0.""" 312 312 self.PageCounter = 0 313 313 self.DateLimit = None 314 314 self.isDirty = True 315 316 def hardreset(self) : 315 316 def hardreset(self) : 317 317 """Resets actual and life time page counters to 0.""" 318 318 self.PageCounter = self.LifePageCounter = 0 319 319 self.DateLimit = None 320 320 self.isDirty = True 321 322 def computeJobPrice(self, jobsize, inkusage=[]) : 321 322 def computeJobPrice(self, jobsize, inkusage=[]) : 323 323 """Computes the job price as the sum of all parent printers' prices + current printer's ones.""" 324 totalprice = 0.0 324 totalprice = 0.0 325 325 if jobsize : 326 326 if self.User.OverCharge != 0.0 : # optimization, but TODO : beware of rounding errors … … 330 330 if not inkusage : 331 331 totalprice += (jobsize * pageprice) 332 else : 332 else : 333 333 for pageindex in range(jobsize) : 334 334 try : 335 335 usage = inkusage[pageindex] 336 except IndexError : 336 except IndexError : 337 337 self.parent.tool.logdebug("No ink usage information. Using base cost of %f credits for page %i." % (pageprice, pageindex+1)) 338 338 totalprice += pageprice 339 else : 339 else : 340 340 coefficients = self.Printer.Coefficients 341 341 for (ink, value) in usage.items() : … … 346 346 totalprice += inkprice 347 347 if self.User.OverCharge != 1.0 : # TODO : beware of rounding errors 348 overcharged = totalprice * self.User.OverCharge 348 overcharged = totalprice * self.User.OverCharge 349 349 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)) 350 350 return overcharged 351 else : 351 else : 352 352 return totalprice 353 353 354 354 def increasePagesUsage(self, jobsize, inkusage=[]) : 355 355 """Increase the value of used pages and money.""" … … 363 363 upq.LifePageCounter = int(upq.LifePageCounter or 0) + jobsize 364 364 return jobprice 365 366 def delete(self) : 365 366 def delete(self) : 367 367 """Deletes an user print quota entry from the database.""" 368 368 self.parent.deleteUserPQuota(self) … … 371 371 self.Exists = False 372 372 self.isDirty = False 373 374 def refund(self, nbpages) : 373 374 def refund(self, nbpages) : 375 375 """Refunds a number of pages to an user on a particular printer.""" 376 376 self.parent.increaseUserPQuotaPagesCounters(self, -nbpages) 377 377 self.PageCounter = int(self.PageCounter or 0) - nbpages 378 378 self.LifePageCounter = int(self.LifePageCounter or 0) - nbpages 379 380 379 380 381 381 class StorageGroupPQuota(StorageObject) : 382 382 """Group Print Quota class.""" … … 391 391 self.DateLimit = None 392 392 self.MaxJobSize = None 393 394 def __getattr__(self, name) : 393 394 def __getattr__(self, name) : 395 395 """Delays data retrieval until it's really needed.""" 396 if name == "ParentPrintersGroupPQuota" : 396 if name == "ParentPrintersGroupPQuota" : 397 397 self.ParentPrintersGroupPQuota = (self.Group.Exists and self.Printer.Exists and self.parent.getParentPrintersGroupPQuota(self)) or [] 398 398 return self.ParentPrintersGroupPQuota 399 399 else : 400 400 raise AttributeError, name 401 402 def reset(self) : 401 402 def reset(self) : 403 403 """Resets page counter to 0.""" 404 404 for user in self.parent.getGroupMembers(self.Group) : … … 409 409 self.DateLimit = None 410 410 self.isDirty = True 411 412 def hardreset(self) : 411 412 def hardreset(self) : 413 413 """Resets actual and life time page counters to 0.""" 414 414 for user in self.parent.getGroupMembers(self.Group) : … … 419 419 self.DateLimit = None 420 420 self.isDirty = True 421 422 def setDateLimit(self, datelimit) : 421 422 def setDateLimit(self, datelimit) : 423 423 """Sets the date limit for this quota.""" 424 424 datelimit = DateTime.ISO.ParseDateTime(str(datelimit)[:19]) … … 431 431 self.parent.writeGroupPQuotaDateLimit(self, date) 432 432 self.DateLimit = date 433 434 def setLimits(self, softlimit, hardlimit) : 433 434 def setLimits(self, softlimit, hardlimit) : 435 435 """Sets the soft and hard limit for this quota.""" 436 436 self.SoftLimit = softlimit … … 438 438 self.DateLimit = None 439 439 self.isDirty = True 440 441 def delete(self) : 440 441 def delete(self) : 442 442 """Deletes a group print quota entry from the database.""" 443 443 self.parent.deleteGroupPQuota(self) … … 446 446 self.Exists = False 447 447 self.isDirty = False 448 449 448 449 450 450 class StorageJob(StorageObject) : 451 451 """Printer's Job class.""" … … 471 471 self.PrecomputedJobSize = None 472 472 self.PrecomputedJobPrice = None 473 474 def __getattr__(self, name) : 473 474 def __getattr__(self, name) : 475 475 """Delays data retrieval until it's really needed.""" 476 if name == "User" : 476 if name == "User" : 477 477 self.User = self.parent.getUser(self.UserName) 478 478 return self.User 479 elif name == "Printer" : 479 elif name == "Printer" : 480 480 self.Printer = self.parent.getPrinter(self.PrinterName) 481 481 return self.Printer 482 482 else : 483 483 raise AttributeError, name 484 485 def refund(self, reason) : 484 485 def refund(self, reason) : 486 486 """Refund a particular print job.""" 487 487 if (not self.JobSize) or (self.JobAction in ("DENY", "CANCEL", "REFUND")) : 488 488 return 489 489 try : 490 loginname = os.getlogin() 491 except OSError : 492 import pwd 493 loginname = pwd.getpwuid(os.getuid()).pw_name 490 494 basereason = _("Refunded %i pages and %.3f credits by %s (%s) on %s") \ 491 495 % (self.JobSize, 492 496 self.JobPrice, 493 497 self.parent.tool.originalUserName, 494 os.getlogin(),498 loginname, 495 499 str(DateTime.now())[:19]) 496 if reason : 500 if reason : 497 501 reason = "%s : %s" % (basereason, reason) 498 else : 502 else : 499 503 reason = basereason 500 self.parent.tool.logdebug("Refunding job %s..." % self.ident) 504 self.parent.tool.logdebug("Refunding job %s..." % self.ident) 501 505 self.parent.beginTransaction() 502 506 try : … … 504 508 bcode = self.parent.getBillingCode(self.JobBillingCode) 505 509 bcode.refund(self.JobSize, self.JobPrice) 506 510 507 511 if self.User.Exists : 508 512 self.User.refund(self.JobPrice, reason) 509 if self.Printer.Exists : 510 upq = self.parent.getUserPQuota(self.User, self.Printer) 513 if self.Printer.Exists : 514 upq = self.parent.getUserPQuota(self.User, self.Printer) 511 515 if upq.Exists : 512 516 upq.refund(self.JobSize) 513 517 self.parent.refundJob(self.ident) 514 except : 518 except : 515 519 self.parent.rollbackTransaction() 516 520 self.parent.tool.logdebug("Error while refunding job %s." % self.ident) 517 521 raise 518 else : 522 else : 519 523 self.parent.commitTransaction() 520 524 self.parent.tool.logdebug("Job %s refunded." % self.ident) 521 522 525 526 523 527 class StorageLastJob(StorageJob) : 524 528 """Printer's Last Job class.""" … … 527 531 self.PrinterName = printer.Name # not needed 528 532 self.Printer = printer 529 530 533 534 531 535 class StorageBillingCode(StorageObject) : 532 536 """Billing code class.""" … … 536 540 self.PageCounter = None 537 541 self.Balance = None 538 539 def delete(self) : 542 543 def delete(self) : 540 544 """Deletes the billing code from the database.""" 541 545 self.parent.deleteBillingCode(self) … … 543 547 self.isDirty = False 544 548 self.Exists = False 545 546 def reset(self, balance=0.0, pagecounter=0) : 549 550 def reset(self, balance=0.0, pagecounter=0) : 547 551 """Resets the pagecounter and balance for this billing code.""" 548 552 self.Balance = balance 549 553 self.PageCounter = pagecounter 550 554 self.isDirty = True 551 555 552 556 def consume(self, pages, price) : 553 557 """Consumes some pages and credits for this billing code.""" … … 556 560 self.PageCounter += pages 557 561 self.Balance -= price 558 562 559 563 def refund(self, pages, price) : 560 564 """Refunds a particular billing code.""" 561 565 self.consume(-pages, -price) 562 563 566 567 564 568 class BaseStorage : 565 569 def __init__(self, pykotatool) : … … 582 586 "LASTJOBS" : {}, \ 583 587 "BILLINGCODES" : {} } 584 585 def close(self) : 588 589 def close(self) : 586 590 """Must be overriden in children classes.""" 587 591 raise RuntimeError, "BaseStorage.close() must be overriden !" 588 589 def __del__(self) : 592 593 def __del__(self) : 590 594 """Ensures that the database connection is closed.""" 591 595 self.close() 592 596 593 597 def getFromCache(self, cachetype, key) : 594 598 """Tries to extract something from the cache.""" … … 597 601 if entry is not None : 598 602 self.tool.logdebug("Cache hit (%s->%s)" % (cachetype, key)) 599 else : 603 else : 600 604 self.tool.logdebug("Cache miss (%s->%s)" % (cachetype, key)) 601 return entry 602 603 def cacheEntry(self, cachetype, key, value) : 605 return entry 606 607 def cacheEntry(self, cachetype, key, value) : 604 608 """Puts an entry in the cache.""" 605 609 if self.usecache and getattr(value, "Exists", 0) : 606 610 self.caches[cachetype][key] = value 607 611 self.tool.logdebug("Cache store (%s->%s)" % (cachetype, key)) 608 609 def flushEntry(self, cachetype, key) : 612 613 def flushEntry(self, cachetype, key) : 610 614 """Removes an entry from the cache.""" 611 615 if self.usecache : 612 616 try : 613 617 del self.caches[cachetype][key] 614 except KeyError : 618 except KeyError : 615 619 pass 616 else : 620 else : 617 621 self.tool.logdebug("Cache flush (%s->%s)" % (cachetype, key)) 618 619 def getUser(self, username) : 622 623 def getUser(self, username) : 620 624 """Returns the user from cache.""" 621 625 user = self.getFromCache("USERS", username) … … 623 627 user = self.getUserFromBackend(username) 624 628 self.cacheEntry("USERS", username, user) 625 return user 626 627 def getGroup(self, groupname) : 629 return user 630 631 def getGroup(self, groupname) : 628 632 """Returns the group from cache.""" 629 633 group = self.getFromCache("GROUPS", groupname) … … 631 635 group = self.getGroupFromBackend(groupname) 632 636 self.cacheEntry("GROUPS", groupname, group) 633 return group 634 635 def getPrinter(self, printername) : 637 return group 638 639 def getPrinter(self, printername) : 636 640 """Returns the printer from cache.""" 637 641 printer = self.getFromCache("PRINTERS", printername) … … 639 643 printer = self.getPrinterFromBackend(printername) 640 644 self.cacheEntry("PRINTERS", printername, printer) 641 return printer 642 643 def getUserPQuota(self, user, printer) : 645 return printer 646 647 def getUserPQuota(self, user, printer) : 644 648 """Returns the user quota information from cache.""" 645 649 useratprinter = "%s@%s" % (user.Name, printer.Name) … … 648 652 upquota = self.getUserPQuotaFromBackend(user, printer) 649 653 self.cacheEntry("USERPQUOTAS", useratprinter, upquota) 650 return upquota 651 652 def getGroupPQuota(self, group, printer) : 654 return upquota 655 656 def getGroupPQuota(self, group, printer) : 653 657 """Returns the group quota information from cache.""" 654 658 groupatprinter = "%s@%s" % (group.Name, printer.Name) … … 657 661 gpquota = self.getGroupPQuotaFromBackend(group, printer) 658 662 self.cacheEntry("GROUPPQUOTAS", groupatprinter, gpquota) 659 return gpquota 660 661 def getPrinterLastJob(self, printer) : 663 return gpquota 664 665 def getPrinterLastJob(self, printer) : 662 666 """Extracts last job information for a given printer from cache.""" 663 667 lastjob = self.getFromCache("LASTJOBS", printer.Name) … … 665 669 lastjob = self.getPrinterLastJobFromBackend(printer) 666 670 self.cacheEntry("LASTJOBS", printer.Name, lastjob) 667 return lastjob 668 669 def getBillingCode(self, label) : 671 return lastjob 672 673 def getBillingCode(self, label) : 670 674 """Returns the user from cache.""" 671 675 code = self.getFromCache("BILLINGCODES", label) … … 674 678 self.cacheEntry("BILLINGCODES", label, code) 675 679 return code 676 677 def getParentPrinters(self, printer) : 680 681 def getParentPrinters(self, printer) : 678 682 """Extracts parent printers information for a given printer from cache.""" 679 683 if self.usecache : … … 684 688 else : 685 689 self.tool.logdebug("Cache hit (%s->Parents)" % printer.Name) 686 else : 690 else : 687 691 printer.Parents = self.getParentPrintersFromBackend(printer) 688 for parent in printer.Parents[:] : 692 for parent in printer.Parents[:] : 689 693 printer.Parents.extend(self.getParentPrinters(parent)) 690 uniquedic = {} 694 uniquedic = {} 691 695 for parent in printer.Parents : 692 696 uniquedic[parent.Name] = parent 693 printer.Parents = uniquedic.values() 697 printer.Parents = uniquedic.values() 694 698 return printer.Parents 695 696 def getGroupMembers(self, group) : 699 700 def getGroupMembers(self, group) : 697 701 """Returns the group's members list from in-group cache.""" 698 702 if self.usecache : … … 703 707 else : 704 708 self.tool.logdebug("Cache hit (%s->Members)" % group.Name) 705 else : 709 else : 706 710 group.Members = self.getGroupMembersFromBackend(group) 707 return group.Members 708 709 def getUserGroups(self, user) : 711 return group.Members 712 713 def getUserGroups(self, user) : 710 714 """Returns the user's groups list from in-user cache.""" 711 715 if self.usecache : … … 716 720 else : 717 721 self.tool.logdebug("Cache hit (%s->Groups)" % user.Name) 718 else : 722 else : 719 723 user.Groups = self.getUserGroupsFromBackend(user) 720 return user.Groups 721 722 def getParentPrintersUserPQuota(self, userpquota) : 724 return user.Groups 725 726 def getParentPrintersUserPQuota(self, userpquota) : 723 727 """Returns all user print quota on the printer and all its parents recursively.""" 724 728 upquotas = [ ] … … 727 731 if upq.Exists : 728 732 upquotas.append(upq) 729 return upquotas 730 731 def getParentPrintersGroupPQuota(self, grouppquota) : 733 return upquotas 734 735 def getParentPrintersGroupPQuota(self, grouppquota) : 732 736 """Returns all group print quota on the printer and all its parents recursively.""" 733 737 gpquotas = [ ] … … 736 740 if gpq.Exists : 737 741 gpquotas.append(gpq) 738 return gpquotas 739 742 return gpquotas 743 740 744 def databaseToUserCharset(self, text) : 741 745 """Converts from database format (UTF-8) to user's charset.""" 742 746 return self.tool.UTF8ToUserCharset(text) 743 747 744 748 def userCharsetToDatabase(self, text) : 745 749 """Converts from user's charset to database format (UTF-8).""" 746 750 return self.tool.userCharsetToUTF8(text) 747 748 def cleanDates(self, startdate, enddate) : 751 752 def cleanDates(self, startdate, enddate) : 749 753 """Clean the dates to create a correct filter.""" 750 if startdate : 754 if startdate : 751 755 startdate = startdate.strip().lower() 752 if enddate : 756 if enddate : 753 757 enddate = enddate.strip().lower() 754 if (not startdate) and (not enddate) : 758 if (not startdate) and (not enddate) : 755 759 return (None, None) 756 757 now = DateTime.now() 760 761 now = DateTime.now() 758 762 nameddates = ('yesterday', 'today', 'now', 'tomorrow') 759 datedict = { "start" : startdate, "end" : enddate } 763 datedict = { "start" : startdate, "end" : enddate } 760 764 for limit in datedict.keys() : 761 765 dateval = datedict[limit] … … 765 769 try : 766 770 offset = int(dateval[len(name):]) 767 except : 771 except : 768 772 offset = 0 769 dateval = dateval[:len(name)] 773 dateval = dateval[:len(name)] 770 774 if limit == "start" : 771 775 if dateval == "yesterday" : … … 787 791 dateval = (now + 1 + offset).Format("%Y%m%d235959") 788 792 break 789 793 790 794 if not dateval.isdigit() : 791 795 dateval = None 792 else : 796 else : 793 797 lgdateval = len(dateval) 794 798 if lgdateval == 4 : 795 if limit == "start" : 799 if limit == "start" : 796 800 dateval = "%s0101 00:00:00" % dateval 797 else : 801 else : 798 802 dateval = "%s1231 23:59:59" % dateval 799 803 elif lgdateval == 6 : 800 if limit == "start" : 804 if limit == "start" : 801 805 dateval = "%s01 00:00:00" % dateval 802 else : 806 else : 803 807 mxdate = DateTime.ISO.ParseDateTime("%s01 00:00:00" % dateval) 804 808 dateval = "%s%02i 23:59:59" % (dateval, mxdate.days_in_month) 805 809 elif lgdateval == 8 : 806 if limit == "start" : 810 if limit == "start" : 807 811 dateval = "%s 00:00:00" % dateval 808 else : 812 else : 809 813 dateval = "%s 23:59:59" % dateval 810 814 elif lgdateval == 10 : 811 if limit == "start" : 815 if limit == "start" : 812 816 dateval = "%s %s:00:00" % (dateval[:8], dateval[8:]) 813 else : 817 else : 814 818 dateval = "%s %s:59:59" % (dateval[:8], dateval[8:]) 815 819 elif lgdateval == 12 : 816 if limit == "start" : 820 if limit == "start" : 817 821 dateval = "%s %s:%s:00" % (dateval[:8], dateval[8:10], dateval[10:]) 818 else : 822 else : 819 823 dateval = "%s %s:%s:59" % (dateval[:8], dateval[8:10], dateval[10:]) 820 elif lgdateval == 14 : 824 elif lgdateval == 14 : 821 825 dateval = "%s %s:%s:%s" % (dateval[:8], dateval[8:10], dateval[10:12], dateval[12:]) 822 else : 826 else : 823 827 dateval = None 824 try : 828 try : 825 829 DateTime.ISO.ParseDateTime(dateval[:19]) 826 except : 830 except : 827 831 dateval = None 828 datedict[limit] = dateval 832 datedict[limit] = dateval 829 833 (start, end) = (datedict["start"], datedict["end"]) 830 834 if start and end and (start > end) : 831 835 (start, end) = (end, start) 832 try : 836 try : 833 837 if len(start) == 17 : 834 838 start = "%s-%s-%s %s" % (start[0:4], start[4:6], start[6:8], start[9:]) 835 except TypeError : 839 except TypeError : 836 840 pass 837 838 try : 841 842 try : 839 843 if len(end) == 17 : 840 844 end = "%s-%s-%s %s" % (end[0:4], end[4:6], end[6:8], end[9:]) 841 except TypeError : 845 except TypeError : 842 846 pass 843 844 return (start, end) 845 847 848 return (start, end) 849 846 850 def openConnection(pykotatool) : 847 851 """Returns a connection handle to the appropriate database.""" … … 849 853 backend = backendinfo["storagebackend"] 850 854 try : 851 storagebackend = imp.load_source("storagebackend", 855 storagebackend = imp.load_source("storagebackend", 852 856 os.path.join(os.path.dirname(__file__), 853 857 "storages", … … 855 859 except ImportError : 856 860 raise PyKotaStorageError, _("Unsupported quota storage backend %s") % backend 857 else : 861 else : 858 862 host = backendinfo["storageserver"] 859 863 database = backendinfo["storagename"]