root / pykota / trunk / bin / pkrefund @ 3063

Revision 3063, 8.4 kB (checked in by jerome, 17 years ago)

Added the pkrefund command line tool.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3
4# PyKota Print Job Refund Manager
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22#
23# $Id$
24#
25#
26
27import sys
28
29from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_
30
31__doc__ = N_("""pkrefund v%(__version__)s (c) %(__years__)s %(__author__)s
32
33Refunds jobs.
34
35command line usage :
36
37  pkrefund [options] [filterexpr]
38
39options :
40
41  -v | --version       Prints pkrefund's version number then exits.
42  -h | --help          Prints this message then exits.
43 
44  -f | --force         Doesn't ask for confirmation before refunding jobs.
45  -r | --reason txt    Sets textual information to explain the refunding.
46
47  Use the filter expressions to extract only parts of the
48  datas. Allowed filters are of the form :
49               
50         key=value
51                         
52  Allowed keys for now are : 
53                       
54         username       User's name
55         printername    Printer's name
56         hostname       Client's hostname
57         jobid          Job's Id
58         billingcode    Job's billing code
59         start          Job's date of printing
60         end            Job's date of printing
61         
62  Contrary to other PyKota management tools, wildcard characters are not
63  expanded, so you can't use them.
64 
65Examples :
66
67  $ pkrefund jobid=503
68 
69  This will refund all jobs which Id is 503. BEWARE : installing CUPS
70  afresh will reset the first job id at 1. So you probably want to use
71  a more precise filter as explained below
72 
73  $ pkrefund --reason "Hardware problem" jobid=503 start=today-7
74 
75  Refunds all jobs which id is 503 but which were printed during the
76  past week. The reason will be marked as being an hardware problem.
77 
78  $ pkrefund --force username=jerome printername=HP2100
79 
80  Refunds all jobs printed by user jerome on printer HP2100. No
81  confirmation will be asked.
82 
83  $ pkrefund --force printername=HP2100 start=200602 end=yesterday
84 
85  Refunds all jobs printed on printer HP2100 between February 1st 2006
86  and yesterday. No confirmation will be asked.
87""")
88       
89class PkRefund(PyKotaTool) :       
90    """A class for refund manager."""
91    validfilterkeys = [ "username",
92                        "printername",
93                        "hostname",
94                        "jobid",
95                        "billingcode",
96                        "start",
97                        "end",
98                      ]
99    def main(self, arguments, options, restricted=1) :
100        """Print Quota Data Dumper."""
101        if restricted and not self.config.isAdmin :
102            raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
103           
104        extractonly = {}
105        for filterexp in arguments :
106            if filterexp.strip() :
107                try :
108                    (filterkey, filtervalue) = [part.strip() for part in filterexp.split("=")]
109                    filterkey = filterkey.lower()
110                    if filterkey not in self.validfilterkeys :
111                        raise ValueError               
112                except ValueError :   
113                    raise PyKotaCommandLineError, _("Invalid filter value [%s], see help.") % filterexp
114                else :   
115                    extractonly.update({ filterkey : filtervalue })
116           
117        username = extractonly.get("username")   
118        if username :
119            user = self.storage.getUser(username)
120        else :
121            user = None
122           
123        printername = extractonly.get("printername")   
124        if printername :
125            printer = self.storage.getPrinter(printername)
126        else :   
127            printer = None
128           
129        start = extractonly.get("start")
130        end = extractonly.get("end")
131        (start, end) = self.storage.cleanDates(start, end)
132       
133        jobs = self.storage.retrieveHistory(user=user,   
134                                            printer=printer, 
135                                            hostname=extractonly.get("hostname"),
136                                            billingcode=extractonly.get("billingcode"),
137                                            jobid=extractonly.get("jobid"),
138                                            start=start,
139                                            end=end,
140                                            limit=0)
141        nbjobs = 0                                   
142        nbpages = 0                                           
143        nbcredits = 0.0
144        reason = (options.get("reason") or "").strip()
145        for job in jobs :                                   
146            if job.JobSize and (job.JobAction not in ("DENY", "CANCEL", "REFUND")) :
147                if options["force"] :
148                    nbpages += job.JobSize
149                    nbcredits += job.JobPrice
150                    job.refund(reason)
151                    nbjobs += 1
152                else :   
153                    print _("Date : %s") % str(job.JobDate)[:19]
154                    print _("JobId : %s") % job.JobId
155                    print _("Username : %s") % job.User.Name
156                    print _("Printername : %s") % job.Printer.Name
157                    print _("Billing code : %s") % job.JobBillingCode
158                    print _("Pages : %i") % job.JobSize
159                    print _("Credits : %.3f") % job.JobPrice
160                    print _("Title : %s") % job.JobTitle
161                   
162                    while True :                             
163                        answer = raw_input("\t%s ? " % _("Refund (Y/N)")).strip().upper()
164                        if answer == _("Y") :
165                            nbpages += job.JobSize
166                            nbcredits += job.JobPrice
167                            job.refund(reason)
168                            nbjobs += 1
169                            break   
170                        elif answer == _("N") :   
171                            break
172                    print       
173        print _("Refunded %i jobs, %i pages and %.3f credits") % (nbjobs, nbpages, nbcredits)                                 
174                   
175           
176if __name__ == "__main__" : 
177    retcode = 0
178    try :
179        short_options = "vhfr"
180        long_options = ["help", "version", "force", "reason="]
181       
182        # Initializes the command line tool
183        refundmanager = PkRefund(doc=__doc__)
184        refundmanager.deferredInit()
185       
186        # parse and checks the command line
187        (options, args) = refundmanager.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
188       
189        # sets long options
190        options["help"] = options["h"] or options["help"]
191        options["version"] = options["v"] or options["version"]
192        options["force"] = options["f"] or options["force"]
193        options["reason"] = options["r"] or options["reason"]
194       
195        if options["help"] :
196            refundmanager.display_usage_and_quit()
197        elif options["version"] :
198            refundmanager.display_version_and_quit()
199        else :
200            retcode = refundmanager.main(args, options)
201    except KeyboardInterrupt :       
202        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
203        retcode = -3
204    except PyKotaCommandLineError, msg :   
205        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
206        retcode = -2
207    except SystemExit :       
208        pass
209    except :
210        try :
211            refundmanager.crashed("pkrefund failed")
212        except :   
213            crashed("pkrefund failed")
214        retcode = -1
215
216    try :
217        refundmanager.storage.close()
218    except (TypeError, NameError, AttributeError) :   
219        pass
220       
221    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.