root / pykota / trunk / bin / pkprinters @ 2725

Revision 2725, 14.6 kB (checked in by jerome, 19 years ago)

Doesn't list anymore entries which don't exist.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[1330]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#
[2622]8# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
[1330]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
[2303]21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
[1330]22#
23# $Id$
24#
[2028]25#
[1330]26
[1821]27import os
[1330]28import sys
[1821]29import pwd
[1330]30
[2512]31from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
[1330]32
[2344]33__doc__ = N_("""pkprinters v%(__version__)s (c) %(__years__)s %(__author__)s
[2267]34
[1330]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 
[1331]46  -a | --add           Adds printers if they don't exist on the Quota
[1453]47                       Storage Server. If they exist, they are modified
48                       unless -s|--skipexisting is also used.
[1330]49                       
[1331]50  -d | --delete        Deletes printers from the quota storage.
[1582]51 
[1853]52  -D | --description d Adds a textual description to printers.
[1330]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 
[1332]59  -g | --groups pg1[,pg2...] Adds or Remove the printer(s) to the printer
60                       groups pg1, pg2, etc... which must already exist.
[1330]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.
[1332]70                       If the --remove option below is not used, the
71                       default action is to add printers to the specified
72                       printer groups.
73                       
[1437]74  -l | --list          List informations about the printer(s) and the
75                       printers groups it is a member of.
76                       
[1332]77  -r | --remove        In combination with the --groups option above,                       
78                       remove printers from the specified printers groups.
[1453]79                       
80  -s | --skipexisting  In combination with the --add option above, tells
81                       pkprinters to not modify existing printers.
[2465]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.
[1330]93 
94  printer1 through printerN can contain wildcards if the --add option
95  is not set.
96 
97examples :                             
98
[1582]99  $ pkprinters --add -D "HP Printer" --charge 0.05,0.1 hp2100 hp2200 hp8000
[1330]100 
[1452]101  Will create three printers named hp2100, hp2200 and hp8000.
[1330]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.
[1582]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.
[1330]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 
[1332]119  $ pkprinters --groups LexMark --remove hp2200
120 
121  This will remove the hp2200 printer from the LexMark printer group.
[2344]122""")
[1330]123       
124class PKPrinters(PyKotaTool) :       
[2336]125    """A class for a printers manager."""
[1330]126    def main(self, names, options) :
127        """Manage printers."""
[1821]128        if (not self.config.isAdmin) and (not options["list"]) :
[2512]129            raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
[1821]130           
[2657]131        if options["delete"] :   
[2674]132            self.display("%s...\n" % _("Deletion"))
[2657]133            todelete = self.storage.getMatchingPrinters(",".join(names))
134            nbtotal = len(todelete)
135            for i in range(nbtotal) :
[2723]136                entry = todelete[i]
137                if entry.Exists :
138                    entry.delete()
[2657]139                percent = 100.0 * float(i) / float(nbtotal)
140                self.display("\r%.02f%%" % percent)
141        else :
[2674]142            if options["add"] :   
143                self.display("%s...\n" % _("Creation"))
144                printers = []
145                nbtotal = len(names)
146                for i in range(nbtotal) :
147                    pname = names[i]
148                    printer = self.storage.getPrinter(pname)
149                    if printer.Exists :
150                        if options["skipexisting"] :
151                            self.printInfo(_("Printer %s already exists, skipping.") % printer.Name)
152                        else :   
153                            self.printInfo(_("Printer %s already exists, will be modified.") % printer.Name)
154                            printers.append(printer)
155                    else :
156                        if self.isValidName(pname) :
157                            printer = self.storage.addPrinter(pname)
158                            if not printer.Exists :
159                                raise PyKotaToolError, _("Impossible to add printer %s") % pname
160                            else :   
161                                printers.append(printer)
162                        else :   
163                            raise PyKotaCommandLineError, _("Invalid printer name %s") % pname
164                    percent = 100.0 * float(i) / float(nbtotal)
165                    self.display("\r%.02f%%" % percent)
166                self.display("\r100.00%%\r        \r%s\n" % _("Done."))
167            else :       
168                if not names :
169                    names = ["*"]
170                printers = self.storage.getMatchingPrinters(",".join(names))
171                if not printers :
172                    raise PyKotaCommandLineError, _("There's no printer matching %s") % " ".join(names)
173                       
[2686]174            if options["list"] :
175                for printer in printers :
[2725]176                    if printer.Exists :
177                        parents = ", ".join([p.Name for p in self.storage.getParentPrinters(printer)])
178                        print "%s [%s] (%s + #*%s)" % \
179                              (printer.Name, printer.Description, printer.PricePerJob, \
180                               printer.PricePerPage)
181                        print "    %s" % (_("Passthrough mode : %s") % ((printer.PassThrough and _("ON")) or _("OFF")))
182                        print "    %s" % (_("Maximum job size : %s") % ((printer.MaxJobSize and (_("%s pages") % printer.MaxJobSize)) or _("Unlimited")))
183                        if parents : 
184                            print "    %s %s" % (_("in"), parents)
185                        print   
[2686]186            else :
187                self.display("%s...\n" % _("Modification"))
188               
189                if options["groups"] :       
190                    printersgroups = self.storage.getMatchingPrinters(options["groups"])
191                    if not printersgroups :
192                        raise PyKotaCommandLineError, _("There's no printer matching %s") % " ".join(options["groups"].split(','))
193                else :         
194                    printersgroups = []
195                       
196                if options["charge"] :
197                    try :
198                        charges = [float(part) for part in options["charge"].split(',', 1)]
199                    except ValueError :   
200                        raise PyKotaCommandLineError, _("Invalid charge amount value %s") % options["charge"]
201                    else :   
202                        if len(charges) > 2 :
203                            charges = charges[:2]
204                        if len(charges) != 2 :
205                            charges = [charges[0], None]
206                        (perpage, perjob) = charges
207                       
208                if options["maxjobsize"] :       
209                    try :
210                        maxjobsize = int(options["maxjobsize"])
211                        if maxjobsize < 0 :
212                            raise ValueError
213                    except ValueError :   
214                        raise PyKotaCommandLineError, _("Invalid maximum job size value %s") % options["maxjobsize"]
215                else :       
216                    maxjobsize = None
217                       
[2716]218                description = options["description"]
219                if description :
220                    description = description.strip()
221                   
[2686]222                nopassthrough = options["nopassthrough"]   
223                passthrough = options["passthrough"]
224                nbtotal = len(printers)
225                for i in range(nbtotal) :       
226                    printer = printers[i]
[2657]227                    if options["charge"] :
228                        printer.setPrices(perpage, perjob)   
[2686]229                    if description is not None :        # NB : "" is allowed !
230                        printer.setDescription(description)
231                    if nopassthrough and printer.PassThrough :   
232                        printer.setPassThrough(False)
233                    if passthrough and not printer.PassThrough :   
234                        printer.setPassThrough(True)
[2657]235                    if (maxjobsize is not None) and (printer.MaxJobSize != maxjobsize) :   
[2686]236                        printer.setMaxJobSize(maxjobsize)
237                    printer.save()   
238                    for pgroup in printersgroups :
239                        if options["remove"] :
240                            pgroup.delPrinterFromGroup(printer)
241                        else :
242                            pgroup.addPrinterToGroup(printer)   
[2674]243                    percent = 100.0 * float(i) / float(nbtotal)
244                    self.display("\r%.02f%%" % percent)
245                               
246        if not options["list"] :               
247            self.display("\r100.00%%\r        \r%s\n" % _("Done."))
[1330]248                     
249if __name__ == "__main__" : 
250    retcode = 0
251    try :
[2465]252        short_options = "hvac:D:dg:lrsnpm:"
253        long_options = ["help", "version", "add", "charge=", "description=", \
254                        "delete", "groups=", "list", "remove", \
255                        "skipexisting", "passthrough", "nopassthrough", \
256                        "maxjobsize="]
[1330]257       
258        # Initializes the command line tool
259        manager = PKPrinters(doc=__doc__)
[2210]260        manager.deferredInit()
[1330]261       
262        # parse and checks the command line
263        (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
264       
265        # sets long options
266        options["help"] = options["h"] or options["help"]
267        options["version"] = options["v"] or options["version"]
268        options["add"] = options["a"] or options["add"]
269        options["charge"] = options["c"] or options["charge"]
[1582]270        options["description"] = options["D"] or options["description"]
[1330]271        options["delete"] = options["d"] or options["delete"] 
272        options["groups"] = options["g"] or options["groups"]
[1437]273        options["list"] = options["l"] or options["list"]
[1332]274        options["remove"] = options["r"] or options["remove"]
[1453]275        options["skipexisting"] = options["s"] or options["skipexisting"]
[2465]276        options["maxjobsize"] = options["m"] or options["maxjobsize"]
277        options["passthrough"] = options["p"] or options["passthrough"]
278        options["nopassthrough"] = options["n"] or options["nopassthrough"]
[1330]279       
280        if options["help"] :
281            manager.display_usage_and_quit()
282        elif options["version"] :
283            manager.display_version_and_quit()
[1582]284        elif (options["delete"] and (options["add"] or options["groups"] or options["charge"] or options["remove"] or options["description"])) \
[1453]285           or (options["skipexisting"] and not options["add"]) \
[2465]286           or (options["list"] and (options["add"] or options["delete"] or options["groups"] or options["charge"] or options["remove"] or options["description"])) \
287           or (options["passthrough"] and options["nopassthrough"]) :
[2512]288            raise PyKotaCommandLineError, _("incompatible options, see help.")
[1332]289        elif options["remove"] and not options["groups"] :   
[2512]290            raise PyKotaCommandLineError, _("You have to pass printer groups names on the command line")
[1437]291        elif (not args) and (not options["list"]) :   
[2512]292            raise PyKotaCommandLineError, _("You have to pass printer names on the command line")
[1330]293        else :
294            retcode = manager.main(args, options)
[2216]295    except KeyboardInterrupt :       
296        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
[2609]297        retcode = -3
[2512]298    except PyKotaCommandLineError, msg :   
299        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
[2609]300        retcode = -2
[1526]301    except SystemExit :       
302        pass
[1517]303    except :
304        try :
305            manager.crashed("pkprinters failed")
306        except :   
[1546]307            crashed("pkprinters failed")
[1330]308        retcode = -1
309
310    try :
311        manager.storage.close()
312    except (TypeError, NameError, AttributeError) :   
313        pass
314       
315    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.