root / pykota / trunk / bin / edpykota @ 1284

Revision 1284, 28.3 kB (checked in by jalet, 20 years ago)

User's email address can now be set at user's creation time.

  • 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22#
23# $Id$
24#
25# $Log$
26# Revision 1.66  2004/01/12 21:54:36  jalet
27# User's email address can now be set at user's creation time.
28#
29# Revision 1.65  2004/01/08 16:24:49  jalet
30# edpykota now supports adding printers to printer groups.
31#
32# Revision 1.64  2004/01/08 14:10:32  jalet
33# Copyright year changed.
34#
35# Revision 1.63  2003/11/24 16:50:58  jalet
36# Old help message deletedd
37#
38# Revision 1.62  2003/11/12 23:28:38  jalet
39# More work on new backend. This commit may be unstable.
40#
41# Revision 1.61  2003/11/12 13:06:35  jalet
42# Bug fix wrt no user/group name command line argument to edpykota
43#
44# Revision 1.60  2003/10/09 21:25:24  jalet
45# Multiple printer names or wildcards can be passed on the command line
46# separated with commas.
47# Beta phase.
48#
49# Revision 1.59  2003/10/07 09:07:27  jalet
50# Character encoding added to please latest version of Python
51#
52# Revision 1.58  2003/10/03 12:27:01  jalet
53# Several optimizations, especially with LDAP backend
54#
55# Revision 1.57  2003/08/20 16:01:19  jalet
56# Comment added.
57#
58# Revision 1.56  2003/07/29 20:55:17  jalet
59# 1.14 is out !
60#
61# Revision 1.55  2003/07/28 09:11:12  jalet
62# PyKota now tries to add its attributes intelligently in existing LDAP
63# directories.
64#
65# Revision 1.54  2003/07/21 06:32:42  jalet
66# Prevents email messages to be sent at modification/creation time for
67# a user/group quota
68#
69# Revision 1.53  2003/07/09 06:03:41  jalet
70# Fixed typo when using edpykota --prototype
71#
72# Revision 1.52  2003/07/07 12:11:13  jalet
73# Small fix
74#
75# Revision 1.51  2003/07/07 11:55:50  jalet
76# Small fix
77#
78# Revision 1.50  2003/07/05 12:33:53  jalet
79# More on previous fix.
80#
81# Revision 1.49  2003/07/05 12:32:07  jalet
82# Ensure that the user don't pass more than two prices for a printer.
83#
84# Revision 1.48  2003/06/25 19:52:30  jalet
85# Should be ready for testing :-)
86#
87# Revision 1.47  2003/06/25 14:10:01  jalet
88# Hey, it may work (edpykota --reset excepted) !
89#
90# Revision 1.46  2003/06/16 11:59:09  jalet
91# More work on LDAP
92#
93# Revision 1.45  2003/06/11 19:32:00  jalet
94# Severe bug wrt account balance setting should be corrected.
95#
96# Revision 1.44  2003/04/29 22:03:38  jalet
97# Better error handling.
98#
99# Revision 1.43  2003/04/23 22:13:56  jalet
100# Preliminary support for LPRng added BUT STILL UNTESTED.
101#
102# Revision 1.42  2003/04/17 13:38:47  jalet
103# Docstring corrected for better manual page
104#
105# Revision 1.41  2003/04/16 12:35:49  jalet
106# Groups quota work now !
107#
108# Revision 1.40  2003/04/16 08:22:09  jalet
109# More strict error detection.
110# Minor code rewrite to avoid some repetitive tests.
111#
112# Revision 1.39  2003/04/16 08:01:53  jalet
113# edpykota --charge command line option works now.
114#
115# Revision 1.38  2003/04/15 22:02:43  jalet
116# More complete docstring
117#
118# Revision 1.37  2003/04/15 21:58:33  jalet
119# edpykota now accepts a --delete option.
120# Preparation to allow edpykota to accept much more command line options
121# (WARNING : docstring is OK, but code isn't !)
122#
123# Revision 1.36  2003/04/15 13:55:28  jalet
124# Options --limitby and --balance added to edpykota
125#
126# Revision 1.35  2003/04/15 13:06:39  jalet
127# Allow to add a printer without any user
128#
129# Revision 1.34  2003/04/11 16:51:11  jalet
130# Bug fix for edpykota --add with users who already had a quota on the printer.
131#
132# Revision 1.33  2003/04/10 21:47:20  jalet
133# Job history added. Upgrade script neutralized for now !
134#
135# Revision 1.32  2003/04/08 21:31:39  jalet
136# (anything or 0) = anything !!! Go back to school Jerome !
137#
138# Revision 1.31  2003/04/08 21:13:44  jalet
139# Prepare --groups option to work.
140#
141# Revision 1.30  2003/04/08 21:10:18  jalet
142# Checks --groups option presence instead of --users because --users is the default.
143#
144# Revision 1.29  2003/04/05 09:28:56  jalet
145# Unnecessary message was logged
146#
147# Revision 1.28  2003/03/29 13:45:26  jalet
148# GPL paragraphs were incorrectly (from memory) copied into the sources.
149# Two README files were added.
150# Upgrade script for PostgreSQL pre 1.01 schema was added.
151#
152# Revision 1.27  2003/03/10 00:23:04  jalet
153# Bad english
154#
155# Revision 1.26  2003/03/10 00:11:27  jalet
156# Cleaner example.
157#
158# Revision 1.25  2003/03/09 23:56:21  jalet
159# Option noquota added to do accounting only.
160#
161# Revision 1.24  2003/02/27 23:48:41  jalet
162# Correctly maps PyKota's log levels to syslog log levels
163#
164# Revision 1.23  2003/02/27 22:55:20  jalet
165# WARN log priority doesn't exist.
166#
167# Revision 1.22  2003/02/27 09:37:02  jalet
168# Wildcards seem to work now
169#
170# Revision 1.21  2003/02/27 09:04:46  jalet
171# user and group names can be passed as wildcards if the --add option
172# is not set. The default is to act on all users or groups.
173#
174# Revision 1.20  2003/02/10 12:07:30  jalet
175# Now repykota should output the recorded total page number for each printer too.
176#
177# Revision 1.19  2003/02/09 13:40:29  jalet
178# typo
179#
180# Revision 1.18  2003/02/09 12:56:53  jalet
181# Internationalization begins...
182#
183# Revision 1.17  2003/02/08 22:47:23  jalet
184# Option --reset can now be used without having to use soft and hard limits
185# on the command line.
186#
187# Revision 1.16  2003/02/08 22:39:46  jalet
188# --reset command line option added
189#
190# Revision 1.15  2003/02/08 22:20:01  jalet
191# Clarification on why we don't check with /etc/passwd to see if the user
192# name is valid or not.
193#
194# Revision 1.14  2003/02/08 22:18:15  jalet
195# Now checks user and group names for validity before adding them
196#
197# Revision 1.13  2003/02/08 22:09:02  jalet
198# Only printer was added the first time.
199#
200# Revision 1.12  2003/02/08 21:44:49  jalet
201# Python 2.1 string module doesn't define ascii_letters
202#
203# Revision 1.11  2003/02/08 09:42:44  jalet
204# Better handle wrong or bad command line arguments
205#
206# Revision 1.10  2003/02/08 09:39:20  jalet
207# typos
208#
209# Revision 1.9  2003/02/08 09:38:06  jalet
210# Badly placed test
211#
212# Revision 1.8  2003/02/07 22:53:57  jalet
213# Checks if printer name is valid before adding it
214#
215# Revision 1.7  2003/02/07 22:17:58  jalet
216# Incomplete test
217#
218# Revision 1.6  2003/02/07 22:13:13  jalet
219# Perhaps edpykota is now able to add printers !!! Oh, stupid me !
220#
221# Revision 1.5  2003/02/06 14:49:04  jalet
222# edpykota should be ok now
223#
224# Revision 1.4  2003/02/06 14:28:59  jalet
225# edpykota should be ok, minus some typos
226#
227# Revision 1.3  2003/02/06 10:47:21  jalet
228# Documentation string and command line options didn't match.
229#
230# Revision 1.2  2003/02/06 10:39:23  jalet
231# Preliminary edpykota work.
232#
233# Revision 1.1  2003/02/05 21:41:09  jalet
234# Skeletons added for all command line tools
235#
236#
237#
238
239import sys
240
241from pykota import version
242from pykota.tool import PyKotaTool, PyKotaToolError
243from pykota.config import PyKotaConfigError
244from pykota.storage import PyKotaStorageError
245
246__doc__ = """edpykota v%s (c) 2003-2004 C@LL - Conseil Internet & Logiciels Libres
247A Print Quota editor for PyKota.
248
249command line usage :
250
251  edpykota [options] user1 user2 ... userN
252 
253  edpykota [options] group1 group2 ... groupN
254
255options :
256
257  -v | --version       Prints edpykota's version number then exits.
258  -h | --help          Prints this message then exits.
259 
260  -a | --add           Adds users and/or printers if they don't
261                       exist on the Quota Storage Server.
262                       
263  -d | --delete        Deletes users/groups from the quota storage.
264                       Printers are never deleted.
265                       
266  -c | --charge p[,j]  Sets the price per page and per job to charge
267                       for a particular printer. Job price is optional.
268                       If both are to be set, separate them with a comma.
269                       Floating point values are allowed.
270 
271  -i | --ingroups g1[,g2...]  Puts the users into each of the groups
272                              listed, separated by commas. The groups
273                              must already exist in the Quota Storage.
274 
275  -u | --users         Edit users print quotas, this is the default.
276 
277  -P | --printer p     Edit quotas on printer p only. Actually p can
278                       use wildcards characters to select only
279                       some printers. The default value is *, meaning
280                       all printers.
281                       You can specify several names or wildcards,
282                       by separating them with commas.
283 
284  -G | --pgroups pg1[,pg2...] Adds the printer(s) to the printer groups
285                       pg1, pg2, etc... which must already exist.
286                       A printer group is just like a normal printer,
287                       only that it is usually unknown from the printing
288                       system. Create printer groups exactly the same
289                       way that you create printers, then add other
290                       printers to them with this option.
291                       Accounting is done on a printer and on all
292                       the printer groups it belongs to, quota checking
293                       is done on a printer and on all the printer groups
294                       it belongs to.
295 
296  -g | --groups        Edit users groups print quotas instead of users.
297                         
298  -p | --prototype u|g Uses user u or group g as a prototype to set
299                       print quotas
300                       
301  -n | --noquota       Doesn't set a quota but only does accounting.
302 
303  -r | --reset         Resets the printed page counter for the user
304                       or group to zero. The life time page counter
305                       is kept unchanged.
306                       
307  -l | --limitby l     Choose if the user/group is limited in printing                     
308                       by its account balance or by its page quota.
309                       The default value is 'quota'. Allowed values
310                       are 'quota' and 'balance'.
311                       
312  -b | --balance b     Sets the user's account balance to b.                     
313                       Account balance may be increase or decreased
314                       if b is prefixed with + or -.
315                       WARNING : when decreasing account balance,
316                       the total paid so far by the user is decreased
317                       too.
318                       Groups don't have a real balance, but the
319                       sum of their users' account balance.
320                       
321  -S | --softlimit sl  Sets the quota soft limit to sl pages.                       
322 
323  -H | --hardlimit hl  Sets the quota hard limit to hl pages.
324 
325  user1 through userN and group1 through groupN can use wildcards
326  if the --add option is not set.
327 
328examples :                             
329
330  $ edpykota --add -p jerome john paul george ringo/ringo@yourdomain.com
331 
332  This will add users john, paul, george and ringo to the quota
333  database, and set their print quotas to the same values than user
334  jerome. User jerome must already exist.
335  User ringo's email address will also be set to 'ringo@yourdomain.com'
336 
337  $ edpykota --printer lp -S 50 -H 60 jerome
338 
339  This will set jerome's print quota on the lp printer to a soft limit
340  of 50 pages, and a hard limit of 60 pages. If either user jerome or
341  printer lp doesn't exist on the Quota Storage Server then nothing is done.
342
343  $ edpykota --add --printer lp --ingroups coders,it -S 50 -H 60 jerome
344 
345  Same as above, but if either user jerome or printer lp doesn't exist
346  on the Quota Storage Server they are automatically added. Also
347  user jerome is put into the groups "coders" and "it" which must
348  already exist in the Quota Storage.
349           
350  $ edpykota -g -S 500 -H 550 financial support           
351 
352  This will set print quota soft limit to 500 pages and hard limit
353  to 550 pages for groups financial and support on all printers.
354 
355  $ edpykota --reset jerome "jo*"
356 
357  This will reset jerome's page counter to zero on all printers, as
358  well as every user whose name begins with 'jo'.
359  Their life time page counter on each printer will be kept unchanged.
360 
361  $ edpykota --printer hpcolor --noquota jerome
362 
363  This will tell PyKota to not limit jerome when printing on the
364  hpcolor printer. All his jobs will be allowed on this printer, but
365  accounting of the pages he prints will still be kept.
366  Print Quotas for jerome on other printers are unchanged.
367 
368  $ edpykota --limitby balance jerome
369 
370  This will tell PyKota to limit jerome by his account's balance
371  when printing.
372 
373  $ edpykota --balance +10.0 jerome
374 
375  This will increase jerome's account balance by 10.0 (in your
376  own currency). You can decrease the account balance with a
377  dash prefix, and set it to a fixed amount with no prefix.
378 
379  $ edpykota --delete jerome rachel
380 
381  This will completely delete jerome and rachel from the Quota Storage
382  database. All their quotas and jobs will be deleted too.
383 
384  $ edpykota --printer lp --charge 0.1
385 
386  This will set the page price for printer lp to 0.1. Job price
387  will not be changed.
388 
389  $ edpykota --printer hplj1,hplj2 --pgroups Laser,HP
390 
391  This will put printers hplj1 and hplj2 in printers groups Laser and HP.
392  When printing either on hplj1 or hplj2, print quota will also be
393  checked and accounted for on virtual printers Laser and HP.
394
395This program is free software; you can redistribute it and/or modify
396it under the terms of the GNU General Public License as published by
397the Free Software Foundation; either version 2 of the License, or
398(at your option) any later version.
399
400This program is distributed in the hope that it will be useful,
401but WITHOUT ANY WARRANTY; without even the implied warranty of
402MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
403GNU General Public License for more details.
404
405You should have received a copy of the GNU General Public License
406along with this program; if not, write to the Free Software
407Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
408
409Please e-mail bugs to: %s""" % (version.__version__, version.__author__)
410       
411class EdPyKota(PyKotaTool) :       
412    """A class for edpykota."""
413    def main(self, names, options) :
414        """Edit user or group quotas."""
415       
416        suffix = (options["groups"] and "Group") or "User"       
417       
418        softlimit = hardlimit = None   
419        if not options["noquota"] :
420            if options["softlimit"] :
421                try :
422                    softlimit = int(options["softlimit"].strip())
423                except ValueError :   
424                    raise PyKotaToolError, _("Invalid softlimit value %s.") % options["softlimit"]
425            if options["hardlimit"] :
426                try :
427                    hardlimit = int(options["hardlimit"].strip())
428                except ValueError :   
429                    raise PyKotaToolError, _("Invalid hardlimit value %s.") % options["hardlimit"]
430            if (softlimit is not None) and (hardlimit is not None) and (hardlimit < softlimit) :       
431                # error, exchange them
432                self.logger.log_message(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
433                (softlimit, hardlimit) = (hardlimit, softlimit)
434           
435        balance = options["balance"]
436        if balance :
437            balance = balance.strip()
438            try :
439                balancevalue = float(balance)
440            except ValueError :   
441                raise PyKotaToolError, _("Invalid balance value %s" % options["balance"])
442           
443        if options["charge"] :
444            try :
445                charges = [float(part) for part in options["charge"].split(',', 1)]
446            except ValueError :   
447                raise PyKotaToolError, _("Invalid charge amount value %s" % options["charge"])
448            else :   
449                if len(charges) > 2 :
450                    charges = charges[:2]
451                if len(charges) != 2 :
452                    charges = [charges[0], None]
453                   
454        limitby = options["limitby"]
455        if limitby :
456            limitby = limitby.strip().lower()
457        if limitby and (limitby not in ('quota', 'balance')) :   
458            raise PyKotaToolError, _("Invalid limitby value %s" % options["limitby"])
459           
460        if options["ingroups"] :   
461            groupnames = [gname.strip() for gname in options["ingroups"].split(',')]
462        else :   
463            groupnames = []
464           
465        if options["prototype"] :   
466            protoentry = getattr(self.storage, "get%s" % suffix)(options["prototype"])
467           
468        printeradded = 0
469        printers = self.storage.getMatchingPrinters(options["printer"])
470        if not printers :
471            pname = options["printer"]
472            if options["add"] and pname :
473                if self.isValidName(pname) :
474                    printers = [ self.storage.addPrinter(pname) ]
475                    if printers[0].Exists :
476                        printeradded = 1
477                    else :   
478                        raise PyKotaToolError, _("Impossible to add printer %s") % pname
479                else :   
480                    raise PyKotaToolError, _("Invalid printer name %s") % pname
481            else :
482                raise PyKotaToolError, _("There's no printer matching %s") % pname
483        if not names :   
484            if options["add"] :
485                if not printeradded :
486                    raise PyKotaToolError, _("You have to pass user or group names on the command line")
487                else :   
488                    names = getattr(self.storage, "getAll%ssNames" % suffix)()
489            else :   
490                names = [ "*" ] # all users
491               
492        printersgroups = []       
493        if options["pgroups"] :       
494            printersgroups = self.storage.getMatchingPrinters(options["pgroups"])
495           
496        changed = {} # tracks changes made at the user/group level
497        for printer in printers :
498            for pgroup in printersgroups :
499                pgroup.addPrinterToGroup(printer)   
500               
501            if options["charge"] :
502                (perpage, perjob) = charges
503                printer.setPrices(perpage, perjob)   
504               
505            if options["prototype"] :
506                if protoentry.Exists :
507                    protoquota = getattr(self.storage, "get%sPQuota" % suffix)(protoentry, printer)
508                    if not protoquota.Exists :
509                        self.logger.log_message(_("Prototype %s not found in Quota Storage for printer %s.") % (protoentry.Name, printer.Name))
510                        continue    # skip this printer
511                    else :   
512                        (softlimit, hardlimit) = (protoquota.SoftLimit, protoquota.HardLimit)
513                else :       
514                    self.logger.log_message(_("Prototype object %s not found in Quota Storage.") % protoentry.Name)
515                   
516            if not options["noquota"] :   
517                if hardlimit is None :   
518                    hardlimit = softlimit
519                    if hardlimit is not None :
520                        self.logger.log_message(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer.Name))
521                if softlimit is None :   
522                    softlimit = hardlimit
523                    if softlimit is not None :
524                        self.logger.log_message(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer.Name))
525                       
526            if options["add"] :   
527                allentries = []   
528                for name in names :
529                    email = ""
530                    if not options["groups"] :
531                        splitname = name.split('/', 1)     # username/email
532                        if len(splitname) == 1 :
533                            splitname.append("")
534                        (name, email) = splitname
535                        if email and (email.count('@') != 1) :
536                            self.logger.log_message(_("Invalid email address %s") % email)
537                            email = ""
538                    entry = getattr(self.storage, "get%s" % suffix)(name)
539                    if email and not options["groups"] :
540                        entry.Email = email
541                    entrypquota = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
542                    allentries.append((entry, entrypquota))
543            else :   
544                allentries = getattr(self.storage, "getPrinter%ssAndQuotas" % suffix)(printer, names)
545               
546            for (entry, entrypquota) in allentries :
547                if not changed.has_key(entry.Name) :
548                    changed[entry.Name] = {}
549                    if not options["groups"] :
550                        changed[entry.Name]["ingroups"] = []
551                       
552                if not entry.Exists :       
553                    # not found
554                    if options["add"] :
555                        # In case we want to add something, it is crucial
556                        # that we DON'T check with the system accounts files
557                        # like /etc/passwd because users may be defined
558                        # only remotely
559                        if self.isValidName(entry.Name) :
560                            entry = getattr(self.storage, "add%s" % suffix)(entry)
561                        else :   
562                            if options["groups"] :
563                                self.logger.log_message(_("Invalid group name %s") % entry.Name)
564                            else :   
565                                self.logger.log_message(_("Invalid user name %s") % entry.Name)
566                               
567                if entry.Exists and (not entrypquota.Exists) :
568                    # not found
569                    if options["add"] :
570                        entrypquota = getattr(self.storage, "add%sPQuota" % suffix)(entry, printer)
571                       
572                if not entrypquota.Exists :     
573                    self.logger.log_message(_("Quota not found for object %s on printer %s.") % (entry.Name, printer.Name))
574                else :   
575                    if options["delete"] :
576                        entry.delete()
577                    else :
578                        if options["noquota"] or options["prototype"] or ((softlimit is not None) and (hardlimit is not None)) :
579                            entrypquota.setLimits(softlimit, hardlimit)
580                        if limitby :
581                            if changed[entry.Name].get("limitby") is None :
582                                entry.setLimitBy(limitby)
583                                changed[entry.Name]["limitby"] = limitby
584                       
585                        if not options["groups"] :
586                            if options["reset"] :
587                                entrypquota.reset()
588                               
589                            if balance :
590                                if changed[entry.Name].get("balance") is None :
591                                    if balance.startswith("+") or balance.startswith("-") :
592                                        newbalance = float(entry.AccountBalance or 0.0) + balancevalue
593                                        newlifetimepaid = float(entry.LifeTimePaid or 0.0) + balancevalue
594                                        entry.setAccountBalance(newbalance, newlifetimepaid)
595                                    else :
596                                        diff = balancevalue - float(entry.AccountBalance or 0.0)
597                                        newlifetimepaid = float(entry.LifeTimePaid or 0.0) + diff
598                                        entry.setAccountBalance(balancevalue, newlifetimepaid)
599                                    changed[entry.Name]["balance"] = balance
600                                   
601                            for groupname in groupnames :       
602                                # not executed if option --ingroups is not used
603                                if groupname not in changed[entry.Name]["ingroups"] :
604                                    group = self.storage.getGroup(groupname)
605                                    if group.Exists :
606                                        self.storage.addUserToGroup(entry, group)
607                                        changed[entry.Name]["ingroups"].append(groupname)
608                                    else :
609                                        self.logger.log_message(_("Group %s not found in the PyKota Storage.") % groupname)
610                                       
611                        # This line disabled to prevent sending of unwanted email                 
612                        # messages if quota is reached at creation/modification time.
613                        # The check will be done at print time anyway.
614                        # getattr(self, "warn%sPQuota" % suffix)(entrypquota)   
615                     
616if __name__ == "__main__" : 
617    retcode = 0
618    try :
619        defaults = { \
620                     "printer" : "*", \
621                   }
622        short_options = "vhdc:l:b:i:naugrp:P:S:H:G:"
623        long_options = ["help", "version", "charge=", "delete", "limitby=", "balance=", "ingroups=", "noquota", "add", "users", "groups", "reset", "prototype=", "printer=", "softlimit=", "hardlimit=", "pgroups="]
624       
625        # Initializes the command line tool
626        editor = EdPyKota(doc=__doc__)
627       
628        # parse and checks the command line
629        (options, args) = editor.parseCommandline(sys.argv[1:], short_options, long_options)
630       
631        # sets long options
632        options["help"] = options["h"] or options["help"]
633        options["version"] = options["v"] or options["version"]
634        options["add"] = options["a"] or options["add"]
635        options["users"] = options["u"] or options["users"]
636        options["groups"] = options["g"] or options["groups"]
637        options["prototype"] = options["p"] or options["prototype"]
638        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
639        options["softlimit"] = options["S"] or options["softlimit"]
640        options["hardlimit"] = options["H"] or options["hardlimit"] 
641        options["reset"] = options["r"] or options["reset"] 
642        options["noquota"] = options["n"] or options["noquota"]
643        options["limitby"] = options["l"] or options["limitby"]
644        options["balance"] = options["b"] or options["balance"] 
645        options["delete"] = options["d"] or options["delete"] 
646        options["ingroups"] = options["i"] or options["ingroups"]
647        options["charge"] = options["c"] or options["charge"]
648        options["pgroups"] = options["G"] or options["pgroups"]
649       
650        if options["help"] :
651            editor.display_usage_and_quit()
652        elif options["version"] :
653            editor.display_version_and_quit()
654        elif options["users"] and options["groups"] :   
655            raise PyKotaToolError, _("incompatible options, see help.")
656        elif (options["add"] or options["prototype"]) and options["delete"] :   
657            raise PyKotaToolError, _("incompatible options, see help.")
658        elif (options["softlimit"] or options["hardlimit"]) and options["prototype"] :   
659            raise PyKotaToolError, _("incompatible options, see help.")
660        elif options["noquota"] and (options["prototype"] or options["hardlimit"] or options["softlimit"]) :
661            raise PyKotaToolError, _("incompatible options, see help.")
662        elif options["groups"] and (options["balance"] or options["ingroups"]) :
663            raise PyKotaToolError, _("incompatible options, see help.")
664        else :
665            retcode = editor.main(args, options)
666    except (PyKotaToolError, PyKotaConfigError, PyKotaStorageError), msg :           
667        sys.stderr.write("%s\n" % msg)
668        sys.stderr.flush()
669        retcode = -1
670
671    try :
672        editor.storage.close()
673    except (TypeError, NameError, AttributeError) :   
674        pass
675       
676    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.