root / pykota / trunk / bin / pykotme @ 3245

Revision 3245, 6.8 kB (checked in by jerome, 17 years ago)

Now the pykotme command line tool computes size and price based on the preaccounter
define for each printer instead of always using the internal page counter.
IMPORTANT : pykotme.cgi still uses the old behavior.

  • Property svn:eol-style set to native
  • 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 Quota Quote sender
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003, 2004, 2005, 2006, 2007 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
28import os
29import pwd
30
31from pykota.tool import PyKotaTool, PyKotaCommandLineError, crashed, N_
32from pykota.accounter import openAccounter
33   
34
35__doc__ = N_("""pykotme v%(__version__)s (c) %(__years__)s %(__author__)s
36
37Gives print quotes to users.
38
39command line usage :
40
41  pykotme  [options]  [files]
42
43options :
44
45  -v | --version       Prints pykotme's version number then exits.
46  -h | --help          Prints this message then exits.
47 
48  -P | --printer p     Gives a quote for this printer only. Actually p can
49                       use wildcards characters to select only
50                       some printers. The default value is *, meaning
51                       all printers.
52                       You can specify several names or wildcards,
53                       by separating them with commas.
54 
55examples :                             
56
57  $ pykotme --printer apple file1.ps file2.ps
58 
59  This will give a print quote to the current user. The quote will show
60  the price and size of a job consisting in file1.ps and file2.ps
61  which would be sent to the apple printer.
62 
63  $ pykotme --printer apple,hplaser <file1.ps
64 
65  This will give a print quote to the current user. The quote will show
66  the price and size of a job consisting in file1.ps as read from
67  standard input, which would be sent to the apple or hplaser
68  printer.
69
70  $ pykotme
71 
72  This will give a quote for a job consisting of what is on standard
73  input. The quote will list the job size, and the price the job
74  would cost on each printer.
75""")
76       
77       
78class PyKotMe(PyKotaTool) :       
79    """A class for pykotme."""
80    def main(self, files, options) :
81        """Gives print quotes."""
82        if (not sys.stdin.isatty()) and ("-" not in files) :
83            files.append("-")
84           
85        printers = self.storage.getMatchingPrinters(options["printer"])
86        if not printers :
87            raise PyKotaCommandLineError, _("There's no printer matching %s") % options["printer"]
88           
89        username = pwd.getpwuid(os.getuid())[0]
90        user = self.storage.getUser(username)
91        if user.Exists and user.LimitBy and (user.LimitBy.lower() == "balance"):
92            print _("Your account balance : %.2f") % (user.AccountBalance or 0.0)
93           
94        if user.Exists :
95            sizeprinted = False
96            done = {}
97            for printer in printers :
98                # Now fake some values. TODO : improve API to not need this anymore   
99                self.PrinterName = printer.Name
100                self.JobSizeBytes = 1
101                self.preaccounter = openAccounter(self, ispreaccounter=1)
102                key = self.preaccounter.name + self.preaccounter.arguments
103                if not done.has_key(key) :
104                    totalsize = 0   
105                    inkusage = []
106                    for filename in files :   
107                        self.DataFile = filename
108                        self.preaccounter.beginJob(None)
109                        self.preaccounter.endJob(None)
110                        totalsize += self.preaccounter.getJobSize(None)
111                        inkusage.extend(self.preaccounter.inkUsage)
112                    done[key] = (totalsize, inkusage)   
113                (totalsize, inkusage) = done[key]   
114                if not sizeprinted :   
115                    print _("Job size : %i pages") % totalsize   
116                    sizeprinted = True
117                userpquota = self.storage.getUserPQuota(user, printer)
118                if userpquota.Exists :
119                    if printer.MaxJobSize and (totalsize > printer.MaxJobSize) :
120                        print _("You are not allowed to print so many pages on printer %s at this time.") % printer.Name
121                    else :   
122                        cost = userpquota.computeJobPrice(totalsize, inkusage)
123                        msg = _("Cost on printer %s : %.2f") % (printer.Name, cost)
124                        if printer.PassThrough :
125                            msg = "%s (%s)" % (msg, _("won't be charged, printer is in passthrough mode"))
126                        elif user.LimitBy == "nochange" :   
127                            msg = "%s (%s)" % (msg, _("won't be charged, your account is immutable"))
128                        print msg   
129            if user.LimitBy == "noprint" :
130                print _("Your account settings forbid you to print at this time.")
131           
132if __name__ == "__main__" : 
133    retcode = 0
134    try :
135        defaults = { \
136                     "printer" : "*", \
137                   }
138        short_options = "vhP:"
139        long_options = ["help", "version", "printer="]
140       
141        # Initializes the command line tool
142        sender = PyKotMe(doc=__doc__)
143        sender.deferredInit()
144       
145        # parse and checks the command line
146        (options, args) = sender.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
147       
148        # sets long options
149        options["help"] = options["h"] or options["help"]
150        options["version"] = options["v"] or options["version"]
151        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
152       
153        if options["help"] :
154            sender.display_usage_and_quit()
155        elif options["version"] :
156            sender.display_version_and_quit()
157        else :
158            retcode = sender.main(args, options)
159    except KeyboardInterrupt :       
160        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
161        retcode = -3
162    except PyKotaCommandLineError, msg :   
163        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
164        retcode = -2
165    except SystemExit :       
166        pass
167    except :
168        try :
169            sender.crashed("pykotme failed")
170        except :   
171            crashed("pykotme failed")
172        retcode = -1
173
174    try :
175        sender.storage.close()
176    except (TypeError, NameError, AttributeError) :   
177        pass
178       
179    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.