root / pykota / trunk / bin / pykotme @ 3288

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

Moved all exceptions definitions to a dedicated module.

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