root / pykota / trunk / bin / edpykota @ 3411

Revision 3411, 17.3 kB (checked in by jerome, 16 years ago)

Minor change to please emacs...

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