#! /usr/bin/env python # -*- coding: ISO-8859-15 -*- # PyKota Print Job Refund Manager # # PyKota - Print Quotas for CUPS and LPRng # # (c) 2003, 2004, 2005, 2006 Jerome Alet # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # $Id$ # # import sys from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_ __doc__ = N_("""pkrefund v%(__version__)s (c) %(__years__)s %(__author__)s Refunds jobs. command line usage : pkrefund [options] [filterexpr] options : -v | --version Prints pkrefund's version number then exits. -h | --help Prints this message then exits. -f | --force Doesn't ask for confirmation before refunding jobs. -r | --reason txt Sets textual information to explain the refunding. Use the filter expressions to extract only parts of the datas. Allowed filters are of the form : key=value Allowed keys for now are : username User's name printername Printer's name hostname Client's hostname jobid Job's Id billingcode Job's billing code start Job's date of printing end Job's date of printing Contrary to other PyKota management tools, wildcard characters are not expanded, so you can't use them. Examples : $ pkrefund jobid=503 This will refund all jobs which Id is 503. BEWARE : installing CUPS afresh will reset the first job id at 1. So you probably want to use a more precise filter as explained below $ pkrefund --reason "Hardware problem" jobid=503 start=today-7 Refunds all jobs which id is 503 but which were printed during the past week. The reason will be marked as being an hardware problem. $ pkrefund --force username=jerome printername=HP2100 Refunds all jobs printed by user jerome on printer HP2100. No confirmation will be asked. $ pkrefund --force printername=HP2100 start=200602 end=yesterday Refunds all jobs printed on printer HP2100 between February 1st 2006 and yesterday. No confirmation will be asked. """) class PkRefund(PyKotaTool) : """A class for refund manager.""" validfilterkeys = [ "username", "printername", "hostname", "jobid", "billingcode", "start", "end", ] def main(self, arguments, options, restricted=1) : """Print Quota Data Dumper.""" if restricted and not self.config.isAdmin : raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command.")) extractonly = {} for filterexp in arguments : if filterexp.strip() : try : (filterkey, filtervalue) = [part.strip() for part in filterexp.split("=")] filterkey = filterkey.lower() if filterkey not in self.validfilterkeys : raise ValueError except ValueError : raise PyKotaCommandLineError, _("Invalid filter value [%s], see help.") % filterexp else : extractonly.update({ filterkey : filtervalue }) username = extractonly.get("username") if username : user = self.storage.getUser(username) else : user = None printername = extractonly.get("printername") if printername : printer = self.storage.getPrinter(printername) else : printer = None start = extractonly.get("start") end = extractonly.get("end") (start, end) = self.storage.cleanDates(start, end) jobs = self.storage.retrieveHistory(user=user, printer=printer, hostname=extractonly.get("hostname"), billingcode=extractonly.get("billingcode"), jobid=extractonly.get("jobid"), start=start, end=end, limit=0) nbjobs = 0 nbpages = 0 nbcredits = 0.0 reason = (options.get("reason") or "").strip() for job in jobs : if job.JobSize and (job.JobAction not in ("DENY", "CANCEL", "REFUND")) : if options["force"] : nbpages += job.JobSize nbcredits += job.JobPrice job.refund(reason) nbjobs += 1 else : print _("Date : %s") % str(job.JobDate)[:19] print _("JobId : %s") % job.JobId print _("Username : %s") % job.User.Name print _("Printername : %s") % job.Printer.Name print _("Billing code : %s") % job.JobBillingCode print _("Pages : %i") % job.JobSize print _("Credits : %.3f") % job.JobPrice print _("Title : %s") % job.JobTitle while True : answer = raw_input("\t%s ? " % _("Refund (Y/N)")).strip().upper() if answer == _("Y") : nbpages += job.JobSize nbcredits += job.JobPrice job.refund(reason) nbjobs += 1 break elif answer == _("N") : break print print _("Refunded %i jobs, %i pages and %.3f credits") % (nbjobs, nbpages, nbcredits) if __name__ == "__main__" : retcode = 0 try : short_options = "vhfr" long_options = ["help", "version", "force", "reason="] # Initializes the command line tool refundmanager = PkRefund(doc=__doc__) refundmanager.deferredInit() # parse and checks the command line (options, args) = refundmanager.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1) # sets long options options["help"] = options["h"] or options["help"] options["version"] = options["v"] or options["version"] options["force"] = options["f"] or options["force"] options["reason"] = options["r"] or options["reason"] if options["help"] : refundmanager.display_usage_and_quit() elif options["version"] : refundmanager.display_version_and_quit() else : retcode = refundmanager.main(args, options) except KeyboardInterrupt : sys.stderr.write("\nInterrupted with Ctrl+C !\n") retcode = -3 except PyKotaCommandLineError, msg : sys.stderr.write("%s : %s\n" % (sys.argv[0], msg)) retcode = -2 except SystemExit : pass except : try : refundmanager.crashed("pkrefund failed") except : crashed("pkrefund failed") retcode = -1 try : refundmanager.storage.close() except (TypeError, NameError, AttributeError) : pass sys.exit(retcode)