root / pykota / trunk / bin / pykotme @ 3260

Revision 3260, 6.7 kB (checked in by jerome, 16 years ago)

Changed license to GNU GPL v3 or later.
Changed Python source encoding from ISO-8859-15 to UTF-8 (only ASCII
was used anyway).

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