root / pykota / trunk / bin / edpykota @ 2006

Revision 1967, 32.8 kB (checked in by jalet, 20 years ago)

Integrated the patch by Wilson Roberto Afonso and Matt Hyclak to allow
edpykota to accept the -U | --used value command line option.

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