root / pykota / trunk / bin / pkprinters @ 2686

Revision 2686, 14.5 kB (checked in by jerome, 18 years ago)

Modified pkprinters to improve speed just like I did for pkbcodes earlier.
edpykota had to be modified as well to use the new printer API.
The time spent to modify printers has been almost halved.

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