root / pykota / trunk / bin / edpykota @ 2030

Revision 2030, 32.9 kB (checked in by jalet, 19 years ago)

Big bug fix wrt the datelimit attribute

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