root / pykota / trunk / bin / edpykota @ 2712

Revision 2712, 15.7 kB (checked in by jerome, 19 years ago)

First pass of code removal.

  • 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 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
29import pwd
30import grp
31from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
32from pykota.config import PyKotaConfigError
33from pykota.storage import PyKotaStorageError
34
35__doc__ = N_("""edpykota v%(__version__)s (c) %(__years__)s %(__author__)s
36
37A Print Quota editor for PyKota.
38
39command line usage :
40
41  edpykota [options] user1 user2 ... userN
42 
43  edpykota [options] group1 group2 ... groupN
44
45options :
46
47  -v | --version       Prints edpykota's version number then exits.
48  -h | --help          Prints this message then exits.
49 
50  -a | --add           Adds users or groups print quota entries if
51                       they don't exist in database.
52                       
53  -d | --delete        Deletes users or groups print quota entries.
54                       Users or groups are never deleted, you have
55                       to use the pkusers command to delete them.
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  -n | --noquota       Sets both soft and hard limits to None for users
68                       or groups print quota entries.
69 
70  -r | --reset         Resets the actual page counter for the user
71                       or group to zero on the specified printers.
72                       The life time page counter is kept unchanged.
73                       
74  -R | --hardreset     Resets the actual and life time page counters
75                       for the user or group to zero on the specified
76                       printers. This is a shortcut for '--used 0'.
77                       
78  -S | --softlimit sl  Sets the quota soft limit to sl pages.                       
79 
80  -H | --hardlimit hl  Sets the quota hard limit to hl pages.
81 
82  -I | --increase v    Increase existing Soft and Hard limits by the value
83                       of v. You can prefix v with + or -, if no sign is
84                       used, + is assumed.
85
86  -U | --used u        Sets the page counters for the user u pages on
87                       the selected printers. Doesn't work for groups, since
88                       their page counters are the sum of all their members'
89                       page counters.
90                       Useful for migrating users from a different system
91                       where they have already used some pages. Actual
92                       and Life Time page counters may be increased or decreased
93                       if u is prefixed with + or -.
94                       WARNING : BOTH page counters are modified in all cases,
95                       so be careful.
96                       NB : if u equals '0', then the action taken is
97                       the same as if --hardreset was used.
98
99  user1 through userN and group1 through groupN can use wildcards
100  if the --add option is not set.
101 
102examples :                             
103
104  $ edpykota --add john paul george ringo
105 
106  This will create print quota entries for users john, paul, george
107  and ringo on all printers. These print quota entries will have no
108  limit set.
109 
110  $ edpykota --printer lp -S 50 -H 60 jerome
111 
112  This will set jerome's print quota on the lp printer to a soft limit
113  of 50 pages, and a hard limit of 60 pages. Both user jerome and
114  printer lp have been previously created with the pkusers and pkprinters
115  commands, respectively.
116
117  $ edpykota -g -S 500 -H 550 financial support           
118 
119  This will set print quota soft limit to 500 pages and hard limit
120  to 550 pages for groups financial and support on all printers.
121 
122  $ edpykota --reset jerome "jo*"
123 
124  This will reset jerome's page counter to zero on all printers, as
125  well as every user whose name begins with 'jo'.
126  Their life time page counter on each printer will be kept unchanged.
127  You can also reset the life time page counters by using the
128  --hardreset | -R command line option.
129 
130  $ edpykota --printer hpcolor --noquota jerome
131 
132  This will tell PyKota to not limit jerome when printing on the
133  hpcolor printer. All his jobs will be allowed on this printer, but
134  accounting of the pages he prints will still be kept.
135  Print Quotas for jerome on other printers are unchanged.
136 
137  $ edpykota --delete --printer "HP*,XER*" jerome rachel
138 
139  This will delete users jerome and rachel's print quota
140  entries on all printers which name begin with 'HP' or
141  'XER'. The jobs printed by these users on these printers
142  will be deleted from the history.
143""") 
144       
145class EdPyKota(PyKotaTool) :       
146    """A class for edpykota."""
147    def main(self, names, options) :
148        """Edit user or group quotas."""
149        if not self.config.isAdmin :
150            raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
151       
152        suffix = (options["groups"] and "Group") or "User"       
153       
154        if options["delete"] :   
155            self.display("%s...\n" % _("Processing"))
156            todelete = getattr(self.storage, "getMatching%ss" % suffix)(",".join(names))
157            nbtotal = len(todelete)
158            for i in range(nbtotal) :
159                todelete[i].delete()
160                percent = 100.0 * float(i) / float(nbtotal)
161                self.display("\r%.02f%%" % percent)
162            self.display("\r100.00%%\r        ")
163            self.display("\r%s\n" % _("Done."))
164        else :
165            softlimit = hardlimit = None
166           
167            used = options["used"]
168            if used :
169                used = used.strip()
170                try :
171                    int(used)
172                except ValueError :
173                    raise PyKotaCommandLineError, _("Invalid used value %s.") % used
174                   
175            increase = options["increase"]
176            if increase :
177                try :
178                    increase = int(increase.strip())
179                except ValueError :
180                    raise PyKotaCommandLineError, _("Invalid increase value %s.") % increase
181           
182            if not options["noquota"] :
183                if options["softlimit"] :
184                    try :
185                        softlimit = int(options["softlimit"].strip())
186                        if softlimit < 0 :
187                            raise ValueError
188                    except ValueError :   
189                        raise PyKotaCommandLineError, _("Invalid softlimit value %s.") % options["softlimit"]
190                if options["hardlimit"] :
191                    try :
192                        hardlimit = int(options["hardlimit"].strip())
193                        if hardlimit < 0 :
194                            raise ValueError
195                    except ValueError :   
196                        raise PyKotaCommandLineError, _("Invalid hardlimit value %s.") % options["hardlimit"]
197                if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :       
198                    # error, exchange them
199                    self.printInfo(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
200                    (softlimit, hardlimit) = (hardlimit, softlimit)
201               
202            sys.stdout.write(_("Managing print quotas... (this may take a lot of time)"))
203            sys.stdout.flush()
204            missingusers = {}
205            missinggroups = {}   
206            changed = {} # tracks changes made at the user/group level
207            for printer in printers :
208                if not options["noquota"] :   
209                    if hardlimit is None :   
210                        hardlimit = softlimit
211                        if hardlimit is not None :
212                            self.printInfo(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer.Name))
213                    if softlimit is None :   
214                        softlimit = hardlimit
215                        if softlimit is not None :
216                            self.printInfo(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer.Name))
217                           
218                if options["add"] :   
219                    allentries = []   
220                    for name in names :
221                        email = ""
222                        if not options["groups"] :
223                            splitname = name.split('/', 1)     # username/email
224                            if len(splitname) == 1 :
225                                splitname.append("")
226                            (name, email) = splitname
227                            if email and (email.count('@') != 1) :
228                                self.printInfo(_("Invalid email address %s") % email)
229                                email = ""
230                        entry = getattr(self.storage, "get%s" % suffix)(name)
231                        if email and not options["groups"] :
232                            entry.Email = email
233                        entrypquota = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
234                        allentries.append((entry, entrypquota))
235                else :   
236                    allentries = getattr(self.storage, "getPrinter%ssAndQuotas" % suffix)(printer, names)
237                   
238                for (entry, entrypquota) in allentries :
239                    if not changed.has_key(entry.Name) :
240                        changed[entry.Name] = {}
241                        if not options["groups"] :
242                            changed[entry.Name]["ingroups"] = []
243                           
244                    if entry.Exists and (not entrypquota.Exists) :
245                        # not found
246                        if options["add"] :
247                            entrypquota = getattr(self.storage, "add%sPQuota" % suffix)(entry, printer)
248                           
249                    if not entrypquota.Exists :     
250                        self.printInfo(_("Quota not found for object %s on printer %s.") % (entry.Name, printer.Name))
251                    else :   
252                        if options["noquota"] \
253                           or ((softlimit is not None) and (hardlimit is not None)) :
254                            entrypquota.setLimits(softlimit, hardlimit)
255                           
256                        if increase :
257                           if (entrypquota.SoftLimit is None) \
258                               or (entrypquota.HardLimit is None) :
259                               self.printInfo(_("You can't increase limits by %s when no limit is set.") % increase, "error")
260                           else :
261                               newsoft = entrypquota.SoftLimit + increase         
262                               newhard = entrypquota.HardLimit + increase         
263                               if (newsoft >= 0) and (newhard >= 0) :
264                                   entrypquota.setLimits(newsoft, newhard)
265                               else :   
266                                   self.printInfo(_("You can't set negative limits."), "error")
267                       
268                        if options["reset"] :
269                            entrypquota.reset()
270                           
271                        if options["hardreset"] :   
272                            entrypquota.hardreset()
273                           
274                        if not options["groups"] :
275                            if used :
276                                entrypquota.setUsage(used)
277                               
278            sys.stdout.write("\nDone.\n")   
279                     
280if __name__ == "__main__" : 
281    retcode = 0
282    try :
283        raise PyKotaCommandLineError, "This version is not stable, download an earlier one. Operation aborted."
284        defaults = { \
285                     "printer" : "*", \
286                   }
287        short_options = "vhdnagrP:S:H:G:RU:I:"
288        long_options = ["help", "version", \
289                        "delete", \
290                        "noquota", "add", \
291                        "groups", "reset", "hardreset", \
292                        "printer=", "softlimit=", "hardlimit=", \
293                        "increase=", "used="]
294       
295        # Initializes the command line tool
296        manager = EdPyKota(doc=__doc__)
297        manager.deferredInit()
298       
299        # parse and checks the command line
300        (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
301       
302        # sets long options
303        options["help"] = options["h"] or options["help"]
304        options["version"] = options["v"] or options["version"]
305        options["add"] = options["a"] or options["add"]
306        options["groups"] = options["g"] or options["groups"]
307        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
308        options["softlimit"] = options["S"] or options["softlimit"]
309        options["hardlimit"] = options["H"] or options["hardlimit"] 
310        options["reset"] = options["r"] or options["reset"] 
311        options["noquota"] = options["n"] or options["noquota"]
312        options["delete"] = options["d"] or options["delete"] 
313        options["hardreset"] = options["R"] or options["hardreset"] 
314        options["used"] = options["U"] or options["used"]
315        options["increase"] = options["I"] or options["increase"]
316       
317        if options["help"] :
318            manager.display_usage_and_quit()
319        elif options["version"] :
320            manager.display_version_and_quit()
321        elif options["add"] and options["delete"] :   
322            raise PyKotaCommandLineError, _("incompatible options, see help.")
323        elif options["noquota"] and (options["hardlimit"] or options["softlimit"]) :
324            raise PyKotaCommandLineError, _("incompatible options, see help.")
325        elif options["groups"] and options["used"] :
326            raise PyKotaCommandLineError, _("incompatible options, see help.")
327        elif options["delete"] and not args :
328            raise PyKotaCommandLineError, _("You have to pass user or group names on the command line")
329        else :
330            retcode = manager.main(args, options)
331    except KeyboardInterrupt :       
332        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
333        retcode = -3
334    except PyKotaCommandLineError, msg :     
335        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
336        retcode = -2
337    except SystemExit :       
338        pass
339    except :
340        try :
341            manager.crashed("edpykota failed")
342        except :   
343            crashed("edpykota failed")
344        retcode = -1
345
346    try :
347        manager.storage.close()
348    except (TypeError, NameError, AttributeError) :   
349        pass
350       
351    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.