root / pykota / trunk / bin / edpykota @ 2036

Revision 2036, 33.2 kB (checked in by jalet, 19 years ago)

edpykota's --delete command line tool doesn't use "*" as its default argument
anymore when the user doesn't pass any real argument :-)

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