root / pykota / trunk / bin / pykotme @ 3335

Revision 3295, 6.7 kB (checked in by jerome, 17 years ago)

Made the CGI scripts work again.
Moved even more functions to the utils module.
Removed the cgifuncs module, moved (and changed) content into utils.
If no output encoding defined, use UTF-8 : when wget is used to try
the CGI scripts, it doesn't set by default the accepted charset and
language headers.

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