root / pykota / trunk / bin / edpykota @ 2028

Revision 2028, 32.8 kB (checked in by jalet, 19 years ago)

Modified copyright years

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