root / pykota / trunk / bin / pkprinters @ 2657

Revision 2657, 13.6 kB (checked in by jerome, 18 years ago)

Huge speed improvements when using the --delete command line option for pkprinters, pkbcodes and edpykota.

  • 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, 2006 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["delete"] :   
132            self.display("Processing...\n")
133            todelete = self.storage.getMatchingPrinters(",".join(names))
134            nbtotal = len(todelete)
135            for i in range(nbtotal) :
136                todelete[i].delete()
137                percent = 100.0 * float(i) / float(nbtotal)
138                self.display("\r%.02f%%" % percent)
139            self.display("\r100.00%%\r        ")
140            self.display("\r%s\n" % _("Done."))
141        else :
142            if options["list"] and not names :
143                names = ["*"]
144               
145            if options["groups"] :       
146                printersgroups = self.storage.getMatchingPrinters(options["groups"])
147                if not printersgroups :
148                    raise PyKotaCommandLineError, _("There's no printer matching %s") % " ".join(options["groups"].split(','))
149               
150            if options["charge"] :
151                try :
152                    charges = [float(part) for part in options["charge"].split(',', 1)]
153                except ValueError :   
154                    raise PyKotaCommandLineError, _("Invalid charge amount value %s") % options["charge"]
155                else :   
156                    if len(charges) > 2 :
157                        charges = charges[:2]
158                    if len(charges) != 2 :
159                        charges = [charges[0], None]
160                    (perpage, perjob) = charges
161                   
162            if options["maxjobsize"] :       
163                try :
164                    maxjobsize = int(options["maxjobsize"])
165                    if maxjobsize < 0 :
166                        raise ValueError
167                except ValueError :   
168                    raise PyKotaCommandLineError, _("Invalid maximum job size value %s") % options["maxjobsize"]
169            else :       
170                maxjobsize = None
171                   
172                   
173            if options["add"] :   
174                printers = []
175                for pname in names :
176                    printer = self.storage.getPrinter(pname)
177                    if printer.Exists :
178                        if options["skipexisting"] :
179                            self.printInfo(_("Printer %s already exists, skipping.") % printer.Name)
180                        else :   
181                            self.printInfo(_("Printer %s already exists, will be modified.") % printer.Name)
182                            printers.append(printer)
183                    else :
184                        if self.isValidName(pname) :
185                            printer = self.storage.addPrinter(pname)
186                            if not printer.Exists :
187                                raise PyKotaToolError, _("Impossible to add printer %s") % pname
188                            else :   
189                                printers.append(printer)
190                        else :   
191                            raise PyKotaCommandLineError, _("Invalid printer name %s") % pname
192            else :       
193                printers = self.storage.getMatchingPrinters(",".join(names))
194                if not printers :
195                    raise PyKotaCommandLineError, _("There's no printer matching %s") % " ".join(names)
196                       
197            for printer in printers :       
198                if options["list"] :   
199                    parents = ", ".join([p.Name for p in self.storage.getParentPrinters(printer)])
200                    if parents : 
201                        parents = "%s %s" % (_("in"), parents)
202                    print "%s [%s] (%s + #*%s)" % \
203                          (printer.Name, printer.Description, printer.PricePerJob, \
204                           printer.PricePerPage)
205                    print "    %s" % (_("Passthrough mode : %s") % ((printer.PassThrough and _("ON")) or _("OFF")))
206                    print "    %s" % (_("Maximum job size : %s") % ((printer.MaxJobSize and (_("%s pages") % printer.MaxJobSize)) or _("Unlimited")))
207                    if parents :       
208                        print "    %s" % parents
209                else :   
210                    if options["charge"] :
211                        printer.setPrices(perpage, perjob)   
212                    if options["description"] is not None :
213                        printer.setDescription(options["description"].strip())
214                    if options["nopassthrough"] and printer.PassThrough :   
215                        self.storage.setPrinterPassThroughMode(printer, 0)
216                    if options["passthrough"] and not printer.PassThrough :   
217                        self.storage.setPrinterPassThroughMode(printer, 1)
218                    if (maxjobsize is not None) and (printer.MaxJobSize != maxjobsize) :   
219                        self.storage.setPrinterMaxJobSize(printer, maxjobsize)
220                    if options["groups"] :   
221                        for pgroup in printersgroups :
222                            if options["remove"] :
223                                pgroup.delPrinterFromGroup(printer)
224                            else :
225                                pgroup.addPrinterToGroup(printer)   
226                     
227if __name__ == "__main__" : 
228    retcode = 0
229    try :
230        short_options = "hvac:D:dg:lrsnpm:"
231        long_options = ["help", "version", "add", "charge=", "description=", \
232                        "delete", "groups=", "list", "remove", \
233                        "skipexisting", "passthrough", "nopassthrough", \
234                        "maxjobsize="]
235       
236        # Initializes the command line tool
237        manager = PKPrinters(doc=__doc__)
238        manager.deferredInit()
239       
240        # parse and checks the command line
241        (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
242       
243        # sets long options
244        options["help"] = options["h"] or options["help"]
245        options["version"] = options["v"] or options["version"]
246        options["add"] = options["a"] or options["add"]
247        options["charge"] = options["c"] or options["charge"]
248        options["description"] = options["D"] or options["description"]
249        options["delete"] = options["d"] or options["delete"] 
250        options["groups"] = options["g"] or options["groups"]
251        options["list"] = options["l"] or options["list"]
252        options["remove"] = options["r"] or options["remove"]
253        options["skipexisting"] = options["s"] or options["skipexisting"]
254        options["maxjobsize"] = options["m"] or options["maxjobsize"]
255        options["passthrough"] = options["p"] or options["passthrough"]
256        options["nopassthrough"] = options["n"] or options["nopassthrough"]
257       
258        if options["help"] :
259            manager.display_usage_and_quit()
260        elif options["version"] :
261            manager.display_version_and_quit()
262        elif (options["delete"] and (options["add"] or options["groups"] or options["charge"] or options["remove"] or options["description"])) \
263           or (options["skipexisting"] and not options["add"]) \
264           or (options["list"] and (options["add"] or options["delete"] or options["groups"] or options["charge"] or options["remove"] or options["description"])) \
265           or (options["passthrough"] and options["nopassthrough"]) :
266            raise PyKotaCommandLineError, _("incompatible options, see help.")
267        elif options["remove"] and not options["groups"] :   
268            raise PyKotaCommandLineError, _("You have to pass printer groups names on the command line")
269        elif (not args) and (not options["list"]) :   
270            raise PyKotaCommandLineError, _("You have to pass printer names on the command line")
271        else :
272            retcode = manager.main(args, options)
273    except KeyboardInterrupt :       
274        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
275        retcode = -3
276    except PyKotaCommandLineError, msg :   
277        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
278        retcode = -2
279    except SystemExit :       
280        pass
281    except :
282        try :
283            manager.crashed("pkprinters failed")
284        except :   
285            crashed("pkprinters failed")
286        retcode = -1
287
288    try :
289        manager.storage.close()
290    except (TypeError, NameError, AttributeError) :   
291        pass
292       
293    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.