root / pykota / trunk / bin / pkbcodes @ 2782

Revision 2782, 8.6 kB (checked in by jerome, 19 years ago)

Code cleaning.
Topped to 10000 the number of times the percent will be displayed by not displaying it if there's no change.
This is very useful when adding 25000 users on 300 printers through an ssh connection...

  • 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 Billing Codes manager
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22#
23# $Id$
24#
25#
26
27import os
28import sys
29import pwd
30
31from pykota.tool import Percent, PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
32from pykota.storage import StorageBillingCode
33
34__doc__ = N_("""pkbcodes v%(__version__)s (c) %(__years__)s %(__author__)s
35
36A billing codes Manager for PyKota.
37
38command line usage :
39
40  pkbcodes [options] code1 code2 code3 ... codeN
41
42options :
43
44  -v | --version       Prints pkbcodes version number then exits.
45  -h | --help          Prints this message then exits.
46 
47  -a | --add           Adds billing codes if they don't exist in PyKota's
48                       database. If they exist, they are modified
49                       unless -s|--skipexisting is also used.
50
51  -d | --delete        Deletes billing codes from PyKota's database.
52                       NB : the history entries with this billing code
53                       are not deleted, voluntarily.
54
55  -D | --description d Adds a textual description to billing codes.
56
57  -l | --list          List informations about the billing codes.
58
59  -r | --reset         Resets the billing codes' balance and page counters
60                       to 0.
61
62  -s | --skipexisting  In combination with the --add option above, tells
63                       pkbcodes to not modify existing billing codes.
64
65  code1 through codeN can contain wildcards if the --add option
66  is not set.
67
68examples :                             
69
70  $ pkbcodes --add -D "My project" myproj
71
72  Will create the myproj billing code with "My project"
73  as the description.
74
75  $ pkbcodes --delete "*"
76
77  This will completely delete all the billing codes, but without
78  removing any matching job from the history. USE WITH CARE ANYWAY !
79 
80  $ pkbcodes --list "my*"
81 
82  This will list all billing codes which name begins with 'my'.
83""")
84       
85class PKBcodes(PyKotaTool) :       
86    """A class for a billing codes manager."""
87    def modifyBillingCode(self, billingcode, reset, description) :
88        """Modifies a billing code."""
89        if reset :
90            billingcode.reset()   
91        if description is not None : # NB : "" is allowed !
92            billingcode.setDescription(description)
93       
94    def main(self, names, options) :
95        """Manage billing codes."""
96        if (not self.config.isAdmin) and (not options["list"]) :
97            raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
98           
99        if not options["add"] :
100            if not options["list"] :
101                self.display(_("Extracting datas..."))
102            if not names :      # NB : can't happen for --delete because it's catched earlier
103                names = ["*"]
104            billingcodes = self.storage.getMatchingBillingCodes(",".join(names))
105            if not billingcodes :
106                raise PyKotaCommandLineError, _("There's no billingcode matching %s") % " ".join(names)
107                       
108        if options["list"] :
109            for billingcode in billingcodes :
110                print "%s [%s] %s %s %s %.2f %s" % \
111                      (billingcode.BillingCode, billingcode.Description, \
112                       billingcode.PageCounter, \
113                       _("pages"), \
114                       _("and"), \
115                       billingcode.Balance, \
116                       _("credits"))
117        elif options["delete"] :   
118            percent = Percent(self, "\n%s..." % _("Deletion"), len(billingcodes))
119            self.storage.deleteManyBillingCodes(billingcodes)
120            percent.display("\n")
121        else :
122            reset = options["reset"]
123            description = options["description"]
124            if description :
125                description = options["description"].strip()
126            skipexisting = options["skipexisting"]       
127           
128            self.storage.beginTransaction()
129            try :
130                if options["add"] :   
131                    percent = Percent(self, "%s...\n" % _("Creation"), len(names))
132                    for bname in names :
133                        billingcode = StorageBillingCode(self.storage, bname)
134                        self.modifyBillingCode(billingcode, reset, description)
135                        oldbillingcode = self.storage.addBillingCode(billingcode)
136                        if oldbillingcode is not None :
137                            if skipexisting :
138                                self.logdebug(_("Billing code [%s] already exists, skipping.") % bname)
139                            else :   
140                                self.logdebug(_("Billing code [%s] already exists, will be modified.") % bname)
141                                self.modifyBillingCode(oldbillingcode, reset, description)
142                                oldbillingcode.save()
143                        percent.oneMore()
144                else :       
145                    percent = Percent(self, "\n%s...\n" % _("Modification"), len(billingcodes))
146                    for billingcode in billingcodes :
147                        self.modifyBillingCode(billingcode, reset, description)
148                        billingcode.save()   
149                        percent.oneMore()
150            except :                   
151                self.storage.rollbackTransaction()
152                raise
153            else :   
154                self.storage.commitTransaction()
155                       
156        try :
157            percent.done()
158        except NameError :   
159            pass
160                     
161if __name__ == "__main__" : 
162    retcode = 0
163    try :
164        short_options = "hvaD:dlrs"
165        long_options = ["help", "version", "add", "description=", "delete", "list", "reset", "skipexisting"]
166       
167        # Initializes the command line tool
168        manager = PKBcodes(doc=__doc__)
169        manager.deferredInit()
170       
171        # parse and checks the command line
172        (options, args) = manager.parseCommandline(sys.argv[1:], short_options, long_options)
173       
174        # sets long options
175        options["help"] = options["h"] or options["help"]
176        options["version"] = options["v"] or options["version"]
177        options["add"] = options["a"] or options["add"]
178        options["description"] = options["D"] or options["description"]
179        options["delete"] = options["d"] or options["delete"] 
180        options["list"] = options["l"] or options["list"]
181        options["reset"] = options["r"] or options["reset"]
182        options["skipexisting"] = options["s"] or options["skipexisting"]
183       
184        if options["help"] :
185            manager.display_usage_and_quit()
186        elif options["version"] :
187            manager.display_version_and_quit()
188        elif (options["delete"] and (options["add"] or options["reset"] or options["description"])) \
189           or (options["skipexisting"] and not options["add"]) \
190           or (options["list"] and (options["add"] or options["delete"] or options["reset"] or options["description"])) :
191            raise PyKotaCommandLineError, _("incompatible options, see help.")
192        elif (not args) and (options["add"] or options["delete"]) :   
193            raise PyKotaCommandLineError, _("You have to pass billing codes on the command line")
194        else :
195            retcode = manager.main(args, options)
196    except KeyboardInterrupt :       
197        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
198        retcode = -3
199    except PyKotaCommandLineError, msg :   
200        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
201        retcode = -2
202    except SystemExit :       
203        pass
204    except :
205        try :
206            manager.crashed("pkbcodes failed")
207        except :   
208            crashed("pkbcodes failed")
209        retcode = -1
210
211    try :
212        manager.storage.close()
213    except (TypeError, NameError, AttributeError) :   
214        pass
215       
216    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.