root / pykota / trunk / bin / pkbcodes @ 3295

Revision 3295, 8.7 kB (checked in by jerome, 16 years ago)

Made the CGI scripts work again.
Moved even more functions to the utils module.
Removed the cgifuncs module, moved (and changed) content into utils.
If no output encoding defined, use UTF-8 : when wget is used to try
the CGI scripts, it doesn't set by default the accepted charset and
language headers.

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