root / pykota / trunk / bin / edpykota @ 907

Revision 907, 16.4 kB (checked in by jalet, 21 years ago)

Bug fix for edpykota --add with users who already had a quota on the printer.

  • 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
3# PyKota Print Quota Editor
4#
5# PyKota - Print Quotas for CUPS
6#
7# (c) 2003 Jerome Alet <alet@librelogiciel.com>
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21#
22# $Id$
23#
24# $Log$
25# Revision 1.34  2003/04/11 16:51:11  jalet
26# Bug fix for edpykota --add with users who already had a quota on the printer.
27#
28# Revision 1.33  2003/04/10 21:47:20  jalet
29# Job history added. Upgrade script neutralized for now !
30#
31# Revision 1.32  2003/04/08 21:31:39  jalet
32# (anything or 0) = anything !!! Go back to school Jerome !
33#
34# Revision 1.31  2003/04/08 21:13:44  jalet
35# Prepare --groups option to work.
36#
37# Revision 1.30  2003/04/08 21:10:18  jalet
38# Checks --groups option presence instead of --users because --users is the default.
39#
40# Revision 1.29  2003/04/05 09:28:56  jalet
41# Unnecessary message was logged
42#
43# Revision 1.28  2003/03/29 13:45:26  jalet
44# GPL paragraphs were incorrectly (from memory) copied into the sources.
45# Two README files were added.
46# Upgrade script for PostgreSQL pre 1.01 schema was added.
47#
48# Revision 1.27  2003/03/10 00:23:04  jalet
49# Bad english
50#
51# Revision 1.26  2003/03/10 00:11:27  jalet
52# Cleaner example.
53#
54# Revision 1.25  2003/03/09 23:56:21  jalet
55# Option noquota added to do accounting only.
56#
57# Revision 1.24  2003/02/27 23:48:41  jalet
58# Correctly maps PyKota's log levels to syslog log levels
59#
60# Revision 1.23  2003/02/27 22:55:20  jalet
61# WARN log priority doesn't exist.
62#
63# Revision 1.22  2003/02/27 09:37:02  jalet
64# Wildcards seem to work now
65#
66# Revision 1.21  2003/02/27 09:04:46  jalet
67# user and group names can be passed as wildcards if the --add option
68# is not set. The default is to act on all users or groups.
69#
70# Revision 1.20  2003/02/10 12:07:30  jalet
71# Now repykota should output the recorded total page number for each printer too.
72#
73# Revision 1.19  2003/02/09 13:40:29  jalet
74# typo
75#
76# Revision 1.18  2003/02/09 12:56:53  jalet
77# Internationalization begins...
78#
79# Revision 1.17  2003/02/08 22:47:23  jalet
80# Option --reset can now be used without having to use soft and hard limits
81# on the command line.
82#
83# Revision 1.16  2003/02/08 22:39:46  jalet
84# --reset command line option added
85#
86# Revision 1.15  2003/02/08 22:20:01  jalet
87# Clarification on why we don't check with /etc/passwd to see if the user
88# name is valid or not.
89#
90# Revision 1.14  2003/02/08 22:18:15  jalet
91# Now checks user and group names for validity before adding them
92#
93# Revision 1.13  2003/02/08 22:09:02  jalet
94# Only printer was added the first time.
95#
96# Revision 1.12  2003/02/08 21:44:49  jalet
97# Python 2.1 string module doesn't define ascii_letters
98#
99# Revision 1.11  2003/02/08 09:42:44  jalet
100# Better handle wrong or bad command line arguments
101#
102# Revision 1.10  2003/02/08 09:39:20  jalet
103# typos
104#
105# Revision 1.9  2003/02/08 09:38:06  jalet
106# Badly placed test
107#
108# Revision 1.8  2003/02/07 22:53:57  jalet
109# Checks if printer name is valid before adding it
110#
111# Revision 1.7  2003/02/07 22:17:58  jalet
112# Incomplete test
113#
114# Revision 1.6  2003/02/07 22:13:13  jalet
115# Perhaps edpykota is now able to add printers !!! Oh, stupid me !
116#
117# Revision 1.5  2003/02/06 14:49:04  jalet
118# edpykota should be ok now
119#
120# Revision 1.4  2003/02/06 14:28:59  jalet
121# edpykota should be ok, minus some typos
122#
123# Revision 1.3  2003/02/06 10:47:21  jalet
124# Documentation string and command line options didn't match.
125#
126# Revision 1.2  2003/02/06 10:39:23  jalet
127# Preliminary edpykota work.
128#
129# Revision 1.1  2003/02/05 21:41:09  jalet
130# Skeletons added for all command line tools
131#
132#
133#
134
135import sys
136
137from pykota import version
138from pykota.tool import PyKotaTool, PyKotaToolError
139
140__doc__ = """edpykota v%s (C) 2003 C@LL - Conseil Internet & Logiciels Libres
141A Print Quota editor for PyKota.
142
143command line usage :
144
145  edpykota [options] user1 user2 ... userN
146  edpykota [options] group1 group2 ... groupN
147
148options :
149
150  -v | --version       Prints edpykota's version number then exits.
151  -h | --help          Prints this message then exits.
152 
153  -a | --add           Adds users and/or printers if they don't
154                       exist on the Quota Storage Server.
155                       
156  -u | --users         Edit users print quotas, this is the default.
157 
158  -P | --printer p     Edit quotas on printer p only. Actually p can
159                       use wildcards characters to select only
160                       some printers. The default value is *, meaning
161                       all printers.
162 
163  -g | --groups        Edit groups print quotas instead of users.
164                         
165  -p | --prototype u|g Uses user u or group g as a prototype to set
166                       print quotas
167                       
168  -n | --noquota       Doesn't set a quota but only does accounting.
169 
170  -r | --reset         Resets the printed page counter for the user
171                       or group to zero. The life time page counter
172                       is kept unchanged.
173                       
174  -S | --softlimit sl  Sets the quota soft limit to sl pages.                       
175 
176  -H | --hardlimit hl  Sets the quota hard limit to hl pages.
177 
178  user1 through userN and group1 through groupN can use wildcards
179  if the --add option is not set.
180 
181examples :                             
182
183  $ edpykota -p jerome john paul george ringo
184 
185  This will set print quotas for the users john, paul, george and ringo
186  to the same values than user jerome. User jerome must exist.
187 
188  $ edpykota --printer lp -S 50 -H 60 jerome
189 
190  This will set jerome's print quota on the lp printer to a soft limit
191  of 50 pages, and a hard limit of 60 pages. If either user jerome or
192  printer lp doesn't exist on the Quota Storage Server then nothing is done.
193
194  $ edpykota --add --printer lp -S 50 -H 60 jerome
195 
196  Same as above, but if either user jerome or printer lp doesn't exist
197  on the Quota Storage Server they are automatically added.
198  WARNING : the CUPS PPD file for this printer must still be modified
199            manually, as well as pykota's configuration file for a
200            new printer to be managed successfully.
201           
202  $ edpykota -g -S 500 -H 550 financial support           
203 
204  This will set print quota soft limit to 500 pages and hard limit
205  to 550 pages for groups financial and support on all printers.
206 
207  $ edpykota --reset jerome "jo*"
208 
209  This will reset jerome's page counter to zero on all printers, as
210  well as every user whose name begins with 'jo'.
211  Their life time page counter on each printer will be kept unchanged.
212 
213  $ edpykota --printer hpcolor --noquota jerome
214 
215  This will tell PyKota to not limit jerome when printing on the
216  hpcolor printer. All his jobs will be allowed on this printer, but
217  accounting of the pages he prints will still be kept.
218  Print Quotas for jerome on other printers are unchanged.
219
220This program is free software; you can redistribute it and/or modify
221it under the terms of the GNU General Public License as published by
222the Free Software Foundation; either version 2 of the License, or
223(at your option) any later version.
224
225This program is distributed in the hope that it will be useful,
226but WITHOUT ANY WARRANTY; without even the implied warranty of
227MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
228GNU General Public License for more details.
229
230You should have received a copy of the GNU General Public License
231along with this program; if not, write to the Free Software
232Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
233
234Please e-mail bugs to: %s""" % (version.__version__, version.__author__)
235       
236class EdPyKota(PyKotaTool) :       
237    """A class for edpykota."""
238    def main(self, names, options) :
239        """Edit user or group quotas."""
240        printers = self.storage.getMatchingPrinters(options["printer"])
241        if not printers :
242            pname = options["printer"]
243            if options["add"] and pname :
244                if self.isValidName(pname) :
245                    printerid = self.storage.addPrinter(pname)
246                    printers = [ (printerid, pname) ]
247                else :   
248                    raise PyKotaToolError, _("Invalid printer name %s") % pname
249            else :
250                raise PyKotaToolError, _("There's no printer matching %s") % pname
251        softlimit = hardlimit = None   
252        if options["softlimit"] :
253            try :
254                softlimit = int(options["softlimit"].strip())
255            except ValueError :   
256                raise PyKotaToolError, _("Invalid softlimit value %s.") % options["softlimit"]
257        if options["hardlimit"] :
258            try :
259                hardlimit = int(options["hardlimit"].strip())
260            except ValueError :   
261                raise PyKotaToolError, _("Invalid hardlimit value %s.") % options["hardlimit"]
262        if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :       
263            # error, exchange them
264            self.logger.log_message(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
265            (softlimit, hardlimit) = (hardlimit, softlimit)
266        if not names :   
267            if options["add"] :
268                raise PyKotaToolError, _("You have to pass user names on the command line")
269            else :   
270                names = [ "*" ] # all users
271        for (printerid, printer) in printers :
272            if options["prototype"] :
273                if options["groups"] :
274                    prototype = self.storage.getGroupPQuota(self.storage.getGroupId(options["prototype"]), printerid)
275                else :     
276                    # default is user quota edition
277                    prototype = self.storage.getUserPQuota(self.storage.getUserId(options["prototype"]), printerid)
278                if prototype is None :
279                    self.logger.log_message(_("Prototype %s not found in Quota Storage for printer %s.") % (options["prototype"], printer))
280                    continue    # skip this printer
281                else :   
282                    (softlimit, hardlimit) = (prototype["softlimit"], prototype["hardlimit"])
283            if hardlimit is None :   
284                hardlimit = softlimit
285                if hardlimit is not None :
286                    self.logger.log_message(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer))
287            if softlimit is None :   
288                softlimit = hardlimit
289                if softlimit is not None :
290                    self.logger.log_message(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer))
291            if (not options["reset"] and not options["noquota"] and not options["prototype"]) and ((hardlimit is None) or (softlimit is None)) :
292                raise PyKotaToolError, _("Both hard and soft limits must be set ! Aborting.")
293            if options["add"] :   
294                allidnames = [(self.storage.getUserId(n), n) for n in names]
295            else :   
296                if options["groups"] :   
297                    allidnames = self.storage.getPrinterGroups(printerid)
298                else :   
299                    allidnames = self.storage.getPrinterUsers(printerid)
300            for (ident, name) in [(i, n) for (i, n) in allidnames if self.matchString(n, names)]:
301                if options["groups"] :
302                    quota = self.storage.getGroupPQuota(ident, printerid)
303                else :
304                    quota = self.storage.getUserPQuota(ident, printerid)
305                if quota is None :
306                    # not found
307                    if options["add"] :
308                        # In case we want to add something, it is crucial
309                        # that we DON'T check with the system accounts files
310                        # like /etc/passwd because users may be defined
311                        # only remotely
312                        if options["groups"] :
313                            if self.isValidName(name) :
314                                (ident, printerid) = self.storage.addGroupPQuota(name, printerid)
315                                quota = self.storage.getGroupPQuota(ident, printerid)
316                            else :   
317                                self.logger.log_message(_("Invalid group name %s") % name)
318                        else :
319                            if self.isValidName(name) :
320                                (ident, printerid) = self.storage.addUserPQuota(name, printerid)
321                                quota = self.storage.getUserPQuota(ident, printerid)
322                            else :   
323                                self.logger.log_message(_("Invalid user name %s") % name)
324                if quota is None :     
325                    self.logger.log_message(_("Quota not found for object %s on printer %s.") % (name, printer))
326                else :   
327                    if options["groups"] :
328                        if options["noquota"] or options["prototype"] or ((softlimit is not None) and (hardlimit is not None)) :
329                            self.storage.setGroupPQuota(ident, printerid, softlimit, hardlimit)
330                        if options["reset"] :
331                            self.storage.resetGroupPQuota(ident, printerid)
332                        self.warnGroupPQuota(name, printer)   
333                    else :
334                        if options["noquota"] or options["prototype"] or ((softlimit is not None) and (hardlimit is not None)) :
335                            self.storage.setUserPQuota(ident, printerid, softlimit, hardlimit)
336                        if options["reset"] :
337                            self.storage.resetUserPQuota(ident, printerid)
338                        self.warnUserPQuota(name, printer)   
339                     
340if __name__ == "__main__" : 
341    try :
342        defaults = { \
343                     "printer" : "*", \
344                   }
345        short_options = "vhnaugrp:P:S:H:"
346        long_options = ["help", "version", "noquota", "add", "users", "groups", "reset", "prototype=", "printer=", "softlimit=", "hardlimit="]
347       
348        # Initializes the command line tool
349        editor = EdPyKota(doc=__doc__)
350       
351        # parse and checks the command line
352        (options, args) = editor.parseCommandline(sys.argv[1:], short_options, long_options)
353       
354        # sets long options
355        options["help"] = options["h"] or options["help"]
356        options["version"] = options["v"] or options["version"]
357        options["add"] = options["a"] or options["add"]
358        options["users"] = options["u"] or options["users"]
359        options["groups"] = options["g"] or options["groups"]
360        options["prototype"] = options["p"] or options["prototype"]
361        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
362        options["softlimit"] = options["S"] or options["softlimit"]
363        options["hardlimit"] = options["H"] or options["hardlimit"] 
364        options["reset"] = options["r"] or options["reset"] 
365        options["noquota"] = options["n"] or options["noquota"]
366       
367        if options["help"] :
368            editor.display_usage_and_quit()
369        elif options["version"] :
370            editor.display_version_and_quit()
371        elif options["users"] and options["groups"] :   
372            raise PyKotaToolError, _("incompatible options, see help.")
373        elif (options["softlimit"] or options["hardlimit"]) and options["prototype"] :   
374            raise PyKotaToolError, _("incompatible options, see help.")
375        elif options["noquota"] and (options["prototype"] or options["hardlimit"] or options["softlimit"]) :
376            raise PyKotaToolError, _("incompatible options, see help.")
377        elif options["groups"] :   
378            raise PyKotaToolError, _("option --groups is currently not implemented.")
379        else :
380            sys.exit(editor.main(args, options))
381    except PyKotaToolError, msg :           
382        sys.stderr.write("%s\n" % msg)
383        sys.stderr.flush()
384        sys.exit(-1)
Note: See TracBrowser for help on using the browser.