root / pykota / trunk / bin / edpykota @ 2937

Revision 2829, 17.6 kB (checked in by jerome, 18 years ago)

Did a pass with pylint.

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