root / pykota / trunk / bin / edpykota @ 2789

Revision 2789, 17.7 kB (checked in by jerome, 18 years ago)

Modified a translatable message.

  • 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/python
2# -*- coding: ISO-8859-15 -*-
3
4# PyKota Print Quota Editor
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 sys
28import os
29
30from pykota.tool import Percent, PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
31from pykota.config import PyKotaConfigError
32from pykota.storage import PyKotaStorageError, StorageUserPQuota, StorageGroupPQuota
33
34__doc__ = N_("""edpykota v%(__version__)s (c) %(__years__)s %(__author__)s
35
36A Print Quota editor for PyKota.
37
38command line usage :
39
40  edpykota [options] user1 user2 ... userN
41 
42  edpykota [options] group1 group2 ... groupN
43
44options :
45
46  -v | --version       Prints edpykota's version number then exits.
47  -h | --help          Prints this message then exits.
48 
49  -a | --add           Adds users or groups print quota entries if
50                       they don't exist in database.
51                       
52  -d | --delete        Deletes users or groups print quota entries.
53                       Users or groups are never deleted, you have
54                       to use the pkusers command to delete them.
55                       The history will be purge from all matching
56                       jobs, unless -g | --groups is used.
57 
58  -P | --printer p     Edit quotas on printer p only. Actually p can
59                       use wildcards characters to select only
60                       some printers. The default value is *, meaning
61                       all printers.
62                       You can specify several names or wildcards,
63                       by separating them with commas.
64 
65  -g | --groups        Edit groups print quota entries instead of
66                       users print quota entries.
67                         
68  -L | --list          Lists users or groups print quota entries.
69 
70  -n | --noquota       Sets both soft and hard limits to None for users
71                       or groups print quota entries.
72 
73  -r | --reset         Resets the actual page counter for the user
74                       or group to zero on the specified printers.
75                       The life time page counter is kept unchanged.
76                       
77  -R | --hardreset     Resets the actual and life time page counters
78                       for the user or group to zero on the specified
79                       printers. This is a shortcut for '--used 0'.
80                       
81  -s | --skipexisting  In combination with the --add option above, tells
82                       edpykota to not modify existing print quota entries.
83                       
84  -S | --softlimit sl  Sets the quota soft limit to sl pages.                       
85 
86  -H | --hardlimit hl  Sets the quota hard limit to hl pages.
87 
88  -I | --increase v    Increase existing Soft and Hard limits by the value
89                       of v. You can prefix v with + or -, if no sign is
90                       used, + is assumed.
91
92  -U | --used u        Sets the page counters for the user u pages on
93                       the selected printers. Doesn't work for groups, since
94                       their page counters are the sum of all their members'
95                       page counters.
96                       Useful for migrating users from a different system
97                       where they have already used some pages. Actual
98                       and Life Time page counters may be increased or decreased
99                       if u is prefixed with + or -.
100                       WARNING : BOTH page counters are modified in all cases,
101                       so be careful.
102                       NB : if u equals '0', then the action taken is
103                       the same as if --hardreset was used.
104
105  user1 through userN and group1 through groupN can use wildcards
106  if the --add option is not set.
107 
108examples :                             
109
110  $ edpykota --add john paul george ringo
111 
112  This will create print quota entries for users john, paul, george
113  and ringo on all printers. These print quota entries will have no
114  limit set.
115 
116  $ edpykota --printer lp -S 50 -H 60 jerome
117 
118  This will set jerome's print quota on the lp printer to a soft limit
119  of 50 pages, and a hard limit of 60 pages. Both user jerome and
120  printer lp have been previously created with the pkusers and pkprinters
121  commands, respectively.
122
123  $ edpykota -g -S 500 -H 550 financial support           
124 
125  This will set print quota soft limit to 500 pages and hard limit
126  to 550 pages for groups financial and support on all printers.
127 
128  $ edpykota --reset jerome "jo*"
129 
130  This will reset jerome's page counter to zero on all printers, as
131  well as every user whose name begins with 'jo'.
132  Their life time page counter on each printer will be kept unchanged.
133  You can also reset the life time page counters by using the
134  --hardreset | -R command line option.
135 
136  $ edpykota --printer hpcolor --noquota jerome
137 
138  This will tell PyKota to not limit jerome when printing on the
139  hpcolor printer. All his jobs will be allowed on this printer, but
140  accounting of the pages he prints will still be kept.
141  Print Quotas for jerome on other printers are unchanged.
142 
143  $ edpykota --delete --printer "HP*,XER*" jerome rachel
144 
145  This will delete users jerome and rachel's print quota
146  entries on all printers which name begin with 'HP' or
147  'XER'. The jobs printed by these users on these printers
148  will be deleted from the history.
149""") 
150       
151class EdPyKota(PyKotaTool) :       
152    """A class for edpykota."""
153    def modifyPQEntry(self, pqkey, pqentry, noquota, softlimit, hardlimit, increase, reset, hardreset, suffix, used) :
154        """Modifies a print quota entry."""
155        if noquota or ((softlimit is not None) and (hardlimit is not None)) :
156            pqentry.setLimits(softlimit, hardlimit)
157        if increase :
158            newsoft = (pqentry.SoftLimit or 0) + increase         
159            newhard = (pqentry.HardLimit or 0) + increase         
160            if (newsoft >= 0) and (newhard >= 0) :
161                pqentry.setLimits(newsoft, newhard)
162            else :   
163                self.printInfo(_("You can't set negative limits for %s") % pqkey, "error")
164        if reset :
165            pqentry.reset()
166        if hardreset :   
167            pqentry.hardreset()
168        if suffix == "User" :
169            if used :
170                pqentry.setUsage(used)
171   
172    def main(self, names, options) :
173        """Edit user or group quotas."""
174        names = self.sanitizeNames(options, names)
175        suffix = (options["groups"] and "Group") or "User"       
176        printernames = options["printer"].split(",")
177           
178        if not options["list"] :
179            percent = Percent(self)
180            percent.display("%s..." % _("Extracting datas"))
181        printers = self.storage.getMatchingPrinters(options["printer"])
182        entries = getattr(self.storage, "getMatching%ss" % suffix)(",".join(names))
183        if not options["list"] :
184            percent.setSize(len(printers) * len(entries))
185       
186        if options["list"] :
187            for printer in printers :
188                for entry in entries :
189                    pqentry = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
190                    if pqentry.Exists :
191                        print "%s@%s" % (entry.Name, printer.Name)
192                        print "    %s" % (_("Page counter : %s") % pqentry.PageCounter)
193                        print "    %s" % (_("Lifetime page counter : %s") % pqentry.LifePageCounter)
194                        print "    %s" % (_("Soft limit : %s") % pqentry.SoftLimit)
195                        print "    %s" % (_("Hard limit : %s") % pqentry.HardLimit)
196                        print "    %s" % (_("Date limit : %s") % pqentry.DateLimit)
197                        print "    %s (Not supported yet)" % (_("Maximum job size : %s") % ((pqentry.MaxJobSize and (_("%s pages") % pqentry.MaxJobSize)) or _("Unlimited")))
198                        if hasattr(pqentry, "WarnCount") :
199                            print "    %s" % (_("Warning banners printed : %s") % pqentry.WarnCount)
200                        print
201        elif options["delete"] :   
202            percent.display("\n%s..." % _("Deletion"))
203            getattr(self.storage, "deleteMany%sPQuotas" % suffix)(printers, entries)
204            percent.display("\n")
205        else :
206            skipexisting = options["skipexisting"]
207            used = options["used"]
208            if used :
209                used = used.strip()
210                try :
211                    int(used)
212                except ValueError :
213                    raise PyKotaCommandLineError, _("Invalid used value %s.") % used
214                   
215            increase = options["increase"]
216            if increase :
217                try :
218                    increase = int(increase.strip())
219                except ValueError :
220                    raise PyKotaCommandLineError, _("Invalid increase value %s.") % increase
221           
222            noquota = options["noquota"]
223            reset = options["reset"]       
224            hardreset = options["hardreset"]
225            softlimit = hardlimit = None
226            if not noquota :
227                if options["softlimit"] :
228                    try :
229                        softlimit = int(options["softlimit"].strip())
230                        if softlimit < 0 :
231                            raise ValueError
232                    except ValueError :   
233                        raise PyKotaCommandLineError, _("Invalid softlimit value %s.") % options["softlimit"]
234                if options["hardlimit"] :
235                    try :
236                        hardlimit = int(options["hardlimit"].strip())
237                        if hardlimit < 0 :
238                            raise ValueError
239                    except ValueError :   
240                        raise PyKotaCommandLineError, _("Invalid hardlimit value %s.") % options["hardlimit"]
241                if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :       
242                    # error, exchange them
243                    self.printInfo(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
244                    (softlimit, hardlimit) = (hardlimit, softlimit)
245                if hardlimit is None :   
246                    hardlimit = softlimit
247                    if hardlimit is not None :
248                        self.printInfo(_("Undefined hard limit set to soft limit (%s).") % str(hardlimit))
249                if softlimit is None :   
250                    softlimit = hardlimit
251                    if softlimit is not None :
252                        self.printInfo(_("Undefined soft limit set to hard limit (%s).") % str(softlimit))
253                       
254            self.storage.beginTransaction()           
255            try :
256                if options["add"] :
257                    percent.display("\n%s...\n" % _("Creation"))
258                    dicnames = {}
259                    for m in entries :
260                        dicnames[m.Name] = None
261                    for name in names :
262                        if not dicnames.has_key(name) :
263                            self.printInfo(_("Impossible to create print quota entries if the user or group object '%s' doesn't already exist. Please use pkusers to create it first.") % name, "warn")
264                           
265                    factory = globals()["Storage%sPQuota" % suffix]
266                    for printer in printers :
267                        pname = printer.Name
268                        for entry in entries :
269                            ename = entry.Name
270                            pqkey = "%s@%s" % (ename, pname)
271                            pqentry = factory(self.storage, entry, printer)
272                            self.modifyPQEntry(pqkey, pqentry, noquota, \
273                                                        softlimit, hardlimit, \
274                                                        increase, reset, \
275                                                        hardreset, suffix, used)
276                            oldpqentry = getattr(self.storage, "add%sPQuota" % suffix)(pqentry)
277                            if oldpqentry is not None :   
278                                if skipexisting :
279                                    self.logdebug("%s print quota entry %s@%s already exists, skipping." % (suffix, ename, pname))
280                                else :   
281                                    self.logdebug("%s print quota entry %s@%s already exists, will be modified." % (suffix, ename, pname))
282                                    self.modifyPQEntry(pqkey, oldpqentry, noquota, \
283                                                        softlimit, hardlimit, \
284                                                        increase, reset, \
285                                                        hardreset, suffix, used)
286                                    oldpqentry.save()                   
287                            percent.oneMore()
288                else :       
289                    percent.display("\n%s...\n" % _("Modification"))
290                    for printer in printers :
291                        for entry in entries :
292                            pqkey = "%s@%s" % (entry.Name, printer.Name)
293                            pqentry = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
294                            if pqentry.Exists :     
295                                self.modifyPQEntry(pqkey, pqentry, noquota, \
296                                                    softlimit, hardlimit, \
297                                                    increase, reset, \
298                                                    hardreset, suffix, used)
299                                pqentry.save()       
300                            percent.oneMore()
301            except :                   
302                self.storage.rollbackTransaction()
303                raise
304            else :   
305                self.storage.commitTransaction()
306                           
307        if not options["list"] :
308            percent.done()
309           
310if __name__ == "__main__" : 
311    retcode = 0
312    try :
313        defaults = { \
314                     "printer" : "*", \
315                   }
316        short_options = "vhdnagrLP:S:H:G:RU:I:s"
317        long_options = ["help", "version", \
318                        "delete", "list", \
319                        "noquota", "add", \
320                        "groups", "reset", "hardreset", \
321                        "printer=", "softlimit=", "hardlimit=", \
322                        "increase=", "used=", "skipexisting"]
323       
324        # Initializes the command line tool
325        manager = EdPyKota(doc=__doc__)
326        manager.deferredInit()
327       
328        # parse and checks the command line
329        (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
330       
331        # sets long options
332        options["help"] = options["h"] or options["help"]
333        options["version"] = options["v"] or options["version"]
334        options["add"] = options["a"] or options["add"]
335        options["groups"] = options["g"] or options["groups"]
336        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
337        options["softlimit"] = options["S"] or options["softlimit"]
338        options["hardlimit"] = options["H"] or options["hardlimit"] 
339        options["reset"] = options["r"] or options["reset"] 
340        options["noquota"] = options["n"] or options["noquota"]
341        options["delete"] = options["d"] or options["delete"] 
342        options["hardreset"] = options["R"] or options["hardreset"] 
343        options["used"] = options["U"] or options["used"]
344        options["increase"] = options["I"] or options["increase"]
345        options["list"] = options["L"] or options["list"]
346        options["skipexisting"] = options["s"] or options["skipexisting"]
347       
348        if options["help"] :
349            manager.display_usage_and_quit()
350        elif options["version"] :
351            manager.display_version_and_quit()
352        elif (options["add"] and options["delete"]) \
353             or (options["noquota"] and (options["hardlimit"] or options["softlimit"])) \
354             or (options["groups"] and options["used"]) \
355             or (options["skipexisting"] and not options["add"]) :
356            raise PyKotaCommandLineError, _("incompatible options, see help.")
357        elif options["delete"] and not args :
358            raise PyKotaCommandLineError, _("You have to pass user or group names on the command line")
359        else :
360            retcode = manager.main(args, options)
361    except KeyboardInterrupt :       
362        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
363        retcode = -3
364    except PyKotaCommandLineError, msg :     
365        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
366        retcode = -2
367    except SystemExit :       
368        pass
369    except :
370        try :
371            manager.crashed("edpykota failed")
372        except :   
373            crashed("edpykota failed")
374        retcode = -1
375
376    try :
377        manager.storage.close()
378    except (TypeError, NameError, AttributeError) :   
379        pass
380       
381    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.