root / pykota / trunk / bin / pkprinters @ 2581

Revision 2512, 12.8 kB (checked in by jerome, 19 years ago)

Ensure that human made errors (like incorrect command line options)
don't produce a traceback anymore. No need to frighten users with
such complete tracebacks and email reporting each time they mistype
some command.
Makes pykosd check more carefully the values of its command line options.

  • 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 Printers Manager
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003, 2004, 2005 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 os
28import sys
29import pwd
30
31from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
32
33__doc__ = N_("""pkprinters v%(__version__)s (c) %(__years__)s %(__author__)s
34
35A Printers Manager for PyKota.
36
37command line usage :
38
39  pkprinters [options] printer1 printer2 printer3 ... printerN
40
41options :
42
43  -v | --version       Prints pkprinters's version number then exits.
44  -h | --help          Prints this message then exits.
45 
46  -a | --add           Adds printers if they don't exist on the Quota
47                       Storage Server. If they exist, they are modified
48                       unless -s|--skipexisting is also used.
49                       
50  -d | --delete        Deletes printers from the quota storage.
51 
52  -D | --description d Adds a textual description to printers.
53                       
54  -c | --charge p[,j]  Sets the price per page and per job to charge.
55                       Job price is optional.
56                       If both are to be set, separate them with a comma.
57                       Floating point and negative values are allowed.
58 
59  -g | --groups pg1[,pg2...] Adds or Remove the printer(s) to the printer
60                       groups pg1, pg2, etc... which must already exist.
61                       A printer group is just like a normal printer,
62                       only that it is usually unknown from the printing
63                       system. Create printer groups exactly the same
64                       way that you create printers, then add other
65                       printers to them with this option.
66                       Accounting is done on a printer and on all
67                       the printer groups it belongs to, quota checking
68                       is done on a printer and on all the printer groups
69                       it belongs to.
70                       If the --remove option below is not used, the
71                       default action is to add printers to the specified
72                       printer groups.
73                       
74  -l | --list          List informations about the printer(s) and the
75                       printers groups it is a member of.
76                       
77  -r | --remove        In combination with the --groups option above,                       
78                       remove printers from the specified printers groups.
79                       
80  -s | --skipexisting  In combination with the --add option above, tells
81                       pkprinters to not modify existing printers.
82                       
83  -m | --maxjobsize s  Sets the maximum job size allowed on the printer
84                       to s pages.
85                       
86  -p | --passthrough   Activate passthrough mode for the printer. In this
87                       mode, users are allowed to print without any impact
88                       on their quota or account balance.
89                       
90  -n | --nopassthrough Deactivate passthrough mode for the printer.
91                       Without -p or -n, printers are created in
92                       normal mode, i.e. no passthrough.
93 
94  printer1 through printerN can contain wildcards if the --add option
95  is not set.
96 
97examples :                             
98
99  $ pkprinters --add -D "HP Printer" --charge 0.05,0.1 hp2100 hp2200 hp8000
100 
101  Will create three printers named hp2100, hp2200 and hp8000.
102  Their price per page will be set at 0.05 unit, and their price
103  per job will be set at 0.1 unit. Units are in your own currency,
104  or whatever you want them to mean.
105  All of their descriptions will be set to the string "HP Printer".
106  If any of these printers already exists, it will also be modified
107  unless the -s|--skipexisting command line option is also used.
108           
109  $ pkprinters --delete "*"
110 
111  This will completely delete all printers and associated quota information,
112  as well as their job history. USE WITH CARE !
113 
114  $ pkprinters --groups Laser,HP "hp*"
115 
116  This will put all printers which name matches "hp*" into printers groups
117  Laser and HP, which MUST already exist.
118 
119  $ pkprinters --groups LexMark --remove hp2200
120 
121  This will remove the hp2200 printer from the LexMark printer group.
122""")
123       
124class PKPrinters(PyKotaTool) :       
125    """A class for a printers manager."""
126    def main(self, names, options) :
127        """Manage printers."""
128        if (not self.config.isAdmin) and (not options["list"]) :
129            raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
130           
131        if options["list"] and not names :
132            names = ["*"]
133           
134        if options["groups"] :       
135            printersgroups = self.storage.getMatchingPrinters(options["groups"])
136            if not printersgroups :
137                raise PyKotaCommandLineError, _("There's no printer matching %s") % " ".join(options["groups"].split(','))
138           
139        if options["charge"] :
140            try :
141                charges = [float(part) for part in options["charge"].split(',', 1)]
142            except ValueError :   
143                raise PyKotaCommandLineError, _("Invalid charge amount value %s") % options["charge"]
144            else :   
145                if len(charges) > 2 :
146                    charges = charges[:2]
147                if len(charges) != 2 :
148                    charges = [charges[0], None]
149                (perpage, perjob) = charges
150               
151        if options["maxjobsize"] :       
152            try :
153                maxjobsize = int(options["maxjobsize"])
154                if maxjobsize < 0 :
155                    raise ValueError
156            except ValueError :   
157                raise PyKotaCommandLineError, _("Invalid maximum job size value %s") % options["maxjobsize"]
158        else :       
159            maxjobsize = None
160               
161               
162        if options["add"] :   
163            printers = []
164            for pname in names :
165                printer = self.storage.getPrinter(pname)
166                if printer.Exists :
167                    if options["skipexisting"] :
168                        self.printInfo(_("Printer %s already exists, skipping.") % printer.Name)
169                    else :   
170                        self.printInfo(_("Printer %s already exists, will be modified.") % printer.Name)
171                        printers.append(printer)
172                else :
173                    if self.isValidName(pname) :
174                        printer = self.storage.addPrinter(pname)
175                        if not printer.Exists :
176                            raise PyKotaToolError, _("Impossible to add printer %s") % pname
177                        else :   
178                            printers.append(printer)
179                    else :   
180                        raise PyKotaCommandLineError, _("Invalid printer name %s") % pname
181        else :       
182            printers = self.storage.getMatchingPrinters(",".join(names))
183            if not printers :
184                raise PyKotaCommandLineError, _("There's no printer matching %s") % " ".join(names)
185                   
186        for printer in printers :       
187            if options["delete"] :
188                printer.delete()
189            elif options["list"] :   
190                parents = ", ".join([p.Name for p in self.storage.getParentPrinters(printer)])
191                if parents : 
192                    parents = "%s %s" % (_("in"), parents)
193                print "%s [%s] (%s + #*%s)" % \
194                      (printer.Name, printer.Description, printer.PricePerJob, \
195                       printer.PricePerPage)
196                print "    %s" % (_("Passthrough mode : %s") % ((printer.PassThrough and _("ON")) or _("OFF")))
197                print "    %s" % (_("Maximum job size : %s") % ((printer.MaxJobSize and (_("%s pages") % printer.MaxJobSize)) or _("Unlimited")))
198                if parents :       
199                    print "    %s" % parents
200            else :   
201                if options["charge"] :
202                    printer.setPrices(perpage, perjob)   
203                if options["description"] is not None :
204                    printer.setDescription(options["description"].strip())
205                if options["nopassthrough"] and printer.PassThrough :   
206                    self.storage.setPrinterPassThroughMode(printer, 0)
207                if options["passthrough"] and not printer.PassThrough :   
208                    self.storage.setPrinterPassThroughMode(printer, 1)
209                if (maxjobsize is not None) and (printer.MaxJobSize != maxjobsize) :   
210                    self.storage.setPrinterMaxJobSize(printer, maxjobsize)
211                if options["groups"] :   
212                    for pgroup in printersgroups :
213                        if options["remove"] :
214                            pgroup.delPrinterFromGroup(printer)
215                        else :
216                            pgroup.addPrinterToGroup(printer)   
217                     
218if __name__ == "__main__" : 
219    retcode = 0
220    try :
221        short_options = "hvac:D:dg:lrsnpm:"
222        long_options = ["help", "version", "add", "charge=", "description=", \
223                        "delete", "groups=", "list", "remove", \
224                        "skipexisting", "passthrough", "nopassthrough", \
225                        "maxjobsize="]
226       
227        # Initializes the command line tool
228        manager = PKPrinters(doc=__doc__)
229        manager.deferredInit()
230       
231        # parse and checks the command line
232        (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
233       
234        # sets long options
235        options["help"] = options["h"] or options["help"]
236        options["version"] = options["v"] or options["version"]
237        options["add"] = options["a"] or options["add"]
238        options["charge"] = options["c"] or options["charge"]
239        options["description"] = options["D"] or options["description"]
240        options["delete"] = options["d"] or options["delete"] 
241        options["groups"] = options["g"] or options["groups"]
242        options["list"] = options["l"] or options["list"]
243        options["remove"] = options["r"] or options["remove"]
244        options["skipexisting"] = options["s"] or options["skipexisting"]
245        options["maxjobsize"] = options["m"] or options["maxjobsize"]
246        options["passthrough"] = options["p"] or options["passthrough"]
247        options["nopassthrough"] = options["n"] or options["nopassthrough"]
248       
249        if options["help"] :
250            manager.display_usage_and_quit()
251        elif options["version"] :
252            manager.display_version_and_quit()
253        elif (options["delete"] and (options["add"] or options["groups"] or options["charge"] or options["remove"] or options["description"])) \
254           or (options["skipexisting"] and not options["add"]) \
255           or (options["list"] and (options["add"] or options["delete"] or options["groups"] or options["charge"] or options["remove"] or options["description"])) \
256           or (options["passthrough"] and options["nopassthrough"]) :
257            raise PyKotaCommandLineError, _("incompatible options, see help.")
258        elif options["remove"] and not options["groups"] :   
259            raise PyKotaCommandLineError, _("You have to pass printer groups names on the command line")
260        elif (not args) and (not options["list"]) :   
261            raise PyKotaCommandLineError, _("You have to pass printer names on the command line")
262        else :
263            retcode = manager.main(args, options)
264    except KeyboardInterrupt :       
265        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
266    except PyKotaCommandLineError, msg :   
267        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
268    except SystemExit :       
269        pass
270    except :
271        try :
272            manager.crashed("pkprinters failed")
273        except :   
274            crashed("pkprinters failed")
275        retcode = -1
276
277    try :
278        manager.storage.close()
279    except (TypeError, NameError, AttributeError) :   
280        pass
281       
282    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.