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
RevLine 
[1057]1#! /usr/bin/env python
[3260]2# -*- coding: UTF-8 -*-
[1057]3#
[3260]4# PyKota : Print Quotas for CUPS
[1057]5#
[3275]6# (c) 2003, 2004, 2005, 2006, 2007, 2008 Jerome Alet <alet@librelogiciel.com>
[3260]7# This program is free software: you can redistribute it and/or modify
[1057]8# it under the terms of the GNU General Public License as published by
[3260]9# the Free Software Foundation, either version 3 of the License, or
[1057]10# (at your option) any later version.
[3260]11#
[1057]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
[3260]18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
[1057]19#
20# $Id$
21#
[2028]22#
[1057]23
24import sys
25import os
26import pwd
27
[3288]28from pykota.errors import PyKotaCommandLineError
29from pykota.tool import PyKotaTool, crashed, N_
[3245]30from pykota.accounter import openAccounter
[2352]31   
32
[2344]33__doc__ = N_("""pykotme v%(__version__)s (c) %(__years__)s %(__author__)s
[1057]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.
[1156]50                       You can specify several names or wildcards,
51                       by separating them with commas.
[1057]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.
[1156]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.
[1057]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.
[2344]73""")
[1057]74       
[1488]75       
[1057]76class PyKotMe(PyKotaTool) :       
77    """A class for pykotme."""
78    def main(self, files, options) :
79        """Gives print quotes."""
[1463]80        if (not sys.stdin.isatty()) and ("-" not in files) :
81            files.append("-")
[1099]82           
[2232]83        printers = self.storage.getMatchingPrinters(options["printer"])
84        if not printers :
[2512]85            raise PyKotaCommandLineError, _("There's no printer matching %s") % options["printer"]
[2232]86           
87        username = pwd.getpwuid(os.getuid())[0]
[1488]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           
[2232]92        if user.Exists :
[3245]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   
[2524]127            if user.LimitBy == "noprint" :
128                print _("Your account settings forbid you to print at this time.")
[1488]129           
[1057]130if __name__ == "__main__" : 
[1113]131    retcode = 0
[1057]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__)
[2210]141        sender.deferredInit()
[1057]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 :
[1113]156            retcode = sender.main(args, options)
[2216]157    except KeyboardInterrupt :       
158        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
[2609]159        retcode = -3
[2512]160    except PyKotaCommandLineError, msg :   
161        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
[2609]162        retcode = -2
[1526]163    except SystemExit :       
164        pass
[1517]165    except :
166        try :
167            sender.crashed("pykotme failed")
168        except :   
[1546]169            crashed("pykotme failed")
[1113]170        retcode = -1
[1057]171
[1113]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.