root / pykota / trunk / bin / repykota @ 1041

Revision 1041, 12.3 kB (checked in by jalet, 21 years ago)

Hey, it may work (edpykota --reset excepted) !

  • 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
3# PyKota Print Quota Reports generator
4#
5# PyKota - Print Quotas for CUPS and LPRng
6#
7# (c) 2003 Jerome Alet <alet@librelogiciel.com>
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21#
22# $Id$
23#
24# $Log$
25# Revision 1.39  2003/06/25 14:10:01  jalet
26# Hey, it may work (edpykota --reset excepted) !
27#
28# Revision 1.38  2003/06/15 22:26:52  jalet
29# More work on LDAP
30#
31# Revision 1.37  2003/06/10 16:37:54  jalet
32# Deletion of the second user which is not needed anymore.
33# Added a debug configuration field in /etc/pykota.conf
34# All queries can now be sent to the logger in debug mode, this will
35# greatly help improve performance when time for this will come.
36#
37# Revision 1.36  2003/06/06 14:21:08  jalet
38# New LDAP schema.
39# Small bug fixes.
40#
41# Revision 1.35  2003/05/28 13:56:24  jalet
42# Unneeded code.
43#
44# Revision 1.34  2003/04/29 22:03:38  jalet
45# Better error handling.
46#
47# Revision 1.33  2003/04/28 08:25:48  jalet
48# Small display bug in repykota was fixed.
49#
50# Revision 1.32  2003/04/23 22:13:56  jalet
51# Preliminary support for LPRng added BUT STILL UNTESTED.
52#
53# Revision 1.31  2003/04/23 09:58:17  jalet
54# Prices per page/job are now displayed
55#
56# Revision 1.30  2003/04/18 08:34:51  jalet
57# Minor fix.
58#
59# Revision 1.29  2003/04/18 08:29:30  jalet
60# Minor bug fix
61#
62# Revision 1.28  2003/04/17 09:36:30  jalet
63# Bad alignment in output
64#
65# Revision 1.27  2003/04/17 09:26:21  jalet
66# repykota now reports account balances too.
67#
68# Revision 1.26  2003/04/16 12:35:49  jalet
69# Groups quota work now !
70#
71# Revision 1.25  2003/04/15 11:30:57  jalet
72# More work done on money print charging.
73# Minor bugs corrected.
74# All tools now access to the storage as priviledged users, repykota excepted.
75#
76# Revision 1.24  2003/04/14 20:05:20  jalet
77# Reversed test.
78#
79# Revision 1.23  2003/04/11 14:42:54  jalet
80# Translations
81#
82# Revision 1.21  2003/04/10 21:47:20  jalet
83# Job history added. Upgrade script neutralized for now !
84#
85# Revision 1.20  2003/04/08 21:31:39  jalet
86# (anything or 0) = anything !!! Go back to school Jerome !
87#
88# Revision 1.19  2003/04/08 21:13:44  jalet
89# Prepare --groups option to work.
90#
91# Revision 1.18  2003/04/08 21:10:18  jalet
92# Checks --groups option presence instead of --users because --users is the default.
93#
94# Revision 1.17  2003/03/29 13:45:27  jalet
95# GPL paragraphs were incorrectly (from memory) copied into the sources.
96# Two README files were added.
97# Upgrade script for PostgreSQL pre 1.01 schema was added.
98#
99# Revision 1.16  2003/03/09 23:56:21  jalet
100# Option noquota added to do accounting only.
101#
102# Revision 1.15  2003/03/09 23:39:14  jalet
103# Simplified translations.
104#
105# Revision 1.14  2003/02/27 09:04:02  jalet
106# Missing translation
107#
108# Revision 1.13  2003/02/27 08:44:01  jalet
109# Check to see if the printer was ever used at all, and displays "unknown"
110# as the pagecounter value in this casCheck to see if the printer was ever used at all, and displays "unknown"
111# as the pagecounter value in this case.
112#
113# Revision 1.12  2003/02/17 23:02:23  jalet
114# getGraceDelay for printer
115#
116# Revision 1.11  2003/02/10 12:12:34  jalet
117# Translations.
118#
119# Revision 1.10  2003/02/10 12:07:30  jalet
120# Now repykota should output the recorded total page number for each printer too.
121#
122# Revision 1.9  2003/02/09 13:40:29  jalet
123# typo
124#
125# Revision 1.8  2003/02/09 12:56:53  jalet
126# Internationalization begins...
127#
128# Revision 1.7  2003/02/08 23:17:20  jalet
129# repykota now outputs life time page counters and the total pages printed by
130# all users/groups on each printer.
131#
132# Revision 1.6  2003/02/07 23:39:16  jalet
133# Typos
134#
135# Revision 1.5  2003/02/07 08:38:36  jalet
136# Missing conversion.
137# empty line between two printers
138#
139# Revision 1.4  2003/02/07 08:34:15  jalet
140# Test wrt date limit was wrong
141#
142# Revision 1.3  2003/02/07 00:08:52  jalet
143# Typos
144#
145# Revision 1.2  2003/02/06 23:58:05  jalet
146# repykota should be ok
147#
148#
149#
150
151import sys
152import os
153import pwd
154import grp
155
156from mx import DateTime
157
158from pykota import version
159from pykota.tool import PyKotaTool, PyKotaToolError
160from pykota.config import PyKotaConfigError
161from pykota.storage import PyKotaStorageError
162
163__doc__ = """repykota v%s (C) 2003 C@LL - Conseil Internet & Logiciels Libres
164
165Generates print quota reports.
166
167command line usage :
168
169  repykota [options]
170
171options :
172
173  -v | --version       Prints repykota's version number then exits.
174  -h | --help          Prints this message then exits.
175 
176  -u | --users         Generates a report on users quota, this is
177                       the default.
178 
179  -g | --groups        Generates a report on group quota instead of users.
180 
181  -P | --printer p     Report quotas on this printer only. Actually p can
182                       use wildcards characters to select only
183                       some printers. The default value is *, meaning
184                       all printers.
185 
186examples :                             
187
188  $ repykota --printer lp
189 
190  This will print the quota status for all users who use the lp printer.
191
192  $ repykota
193 
194  This will print the quota status for all users on all printers.
195 
196  $ repykota --printer "laser*" jerome "jo*"
197 
198  This will print the quota status for user jerome and all users
199  whose name begins with "jo" on all printers which name begin
200  with "laser"
201 
202  If launched by a non-root user, additionnal arguments representing
203  users or groups names are ignored, and only the current user/group
204  is reported.
205
206This program is free software; you can redistribute it and/or modify
207it under the terms of the GNU General Public License as published by
208the Free Software Foundation; either version 2 of the License, or
209(at your option) any later version.
210
211This program is distributed in the hope that it will be useful,
212but WITHOUT ANY WARRANTY; without even the implied warranty of
213MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
214GNU General Public License for more details.
215
216You should have received a copy of the GNU General Public License
217along with this program; if not, write to the Free Software
218Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
219
220Please e-mail bugs to: %s""" % (version.__version__, version.__author__)
221       
222class RePyKota(PyKotaTool) :       
223    """A class for repykota."""
224    def main(self, ugnames, options) :
225        """Print Quota reports generator."""
226        uid = os.geteuid()
227        if not uid :
228            # root user
229            if not ugnames :
230                # no username, means all usernames
231                ugnames = [ "*" ]
232        else :       
233            # not the root user
234            # reports only the current user
235            if options["groups"] :
236                ugnames = [ grp.getgrgid(pwd.getpwuid(uid)[3])[0] ]
237            else :
238                ugnames = [ pwd.getpwuid(uid)[0] ]
239       
240        printers = self.storage.getMatchingPrinters(options["printer"])
241        if not printers :
242            raise PyKotaToolError, _("There's no printer matching %s") % options["printer"]
243        for printer in printers :
244            print _("*** Report for %s quota on printer %s") % ((options["groups"] and "group") or "user", printer.Name)
245            print _("Pages grace time: %i days") % self.config.getGraceDelay(printer.Name)
246            if printer.PricePerJob is not None :
247                print _("Price per job: %.3f") % printer.PricePerJob
248            if printer.PricePerPage is not None :   
249                print _("Price per page: %.3f") % printer.PricePerPage
250            total = 0
251            totalmoney = 0.0
252            if options["groups"] :
253                print _("Group           used    soft    hard    balance grace         total       paid") 
254                print "------------------------------------------------------------------------------"
255                for (group, grouppquota) in self.storage.getPrinterGroupsAndQuotas(printer, ugnames) :
256                    (pages, money) = self.printQuota(group, grouppquota)
257                    total += pages
258                    totalmoney += money
259            else :
260                # default is user quota report
261                print _("User            used    soft    hard    balance grace         total       paid") 
262                print "------------------------------------------------------------------------------"
263                for (user, userpquota) in self.storage.getPrinterUsersAndQuotas(printer, ugnames) :
264                    (pages, money) = self.printQuota(user, userpquota)
265                    total += pages
266                    totalmoney += money
267            if total or totalmoney :       
268                print (" " * 50) + (_("Total : %9i") % total) + ("%11s" % ("%7.2f" % totalmoney)[:11])
269            try :
270                msg = "%9i" % printer.LastJob.PrinterPageCounter
271            except TypeError :     
272                msg = _("unknown")
273            print (" " * 51) + (_("Real : %s") % msg)
274            print       
275        if options["groups"] :   
276            print _("Totals may be inaccurate if some users are members of several groups.")
277                       
278    def printQuota(self, entry, quota) :
279        """Prints the quota information."""
280        lifepagecounter = int(quota.LifePageCounter or 0)
281        pagecounter = int(quota.PageCounter or 0)
282        balance = float(entry.AccountBalance or 0.0)
283        lifetimepaid = float(entry.LifeTimePaid or 0.0)
284       
285        if quota.DateLimit is not None :
286            now = DateTime.now()
287            datelimit = DateTime.ISO.ParseDateTime(quota.DateLimit)
288            if now >= datelimit :
289                datelimit = "DENY"
290        elif (quota.HardLimit is not None) and (pagecounter >= quota.HardLimit) :   
291            datelimit = "DENY"
292        elif (quota.HardLimit is None) and (quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) :
293            datelimit = "DENY"
294        else :   
295            datelimit = ""
296           
297        if entry.LimitBy.lower() == "balance" :   
298            reached = (((balance <= 0) and "+") or "-") + "B"
299        else :
300            reached = (((quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) and "+") or "-") + "Q"
301           
302        strbalance = ("%5.2f" % balance)[:10]
303        strlifetimepaid = ("%6.2f" % lifetimepaid)[:10]
304        print "%-9.9s %s %7i %7s %7s %10s %-10.10s %8i %10s" % (entry.Name, reached, pagecounter, str(quota.SoftLimit), str(quota.HardLimit), strbalance, str(datelimit)[:10], lifepagecounter, strlifetimepaid)
305        return (lifepagecounter, lifetimepaid)
306                   
307if __name__ == "__main__" : 
308    try :
309        defaults = { \
310                     "printer" : "*", \
311                   }
312        short_options = "vhugP:"
313        long_options = ["help", "version", "users", "groups", "printer="]
314       
315        # Initializes the command line tool
316        reporter = RePyKota(doc=__doc__)
317       
318        # parse and checks the command line
319        (options, args) = reporter.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
320       
321        # sets long options
322        options["help"] = options["h"] or options["help"]
323        options["version"] = options["v"] or options["version"]
324        options["users"] = options["u"] or options["users"]
325        options["groups"] = options["g"] or options["groups"]
326        options["printer"] = options["P"] or options["printer"] or defaults["printer"]
327       
328        if options["help"] :
329            reporter.display_usage_and_quit()
330        elif options["version"] :
331            reporter.display_version_and_quit()
332        elif options["users"] and options["groups"] :   
333            raise PyKotaToolError, _("incompatible options, see help.")
334        else :
335            sys.exit(reporter.main(args, options))
336    except (PyKotaToolError, PyKotaConfigError, PyKotaStorageError), msg :           
337        sys.stderr.write("%s\n" % msg)
338        sys.stderr.flush()
339        sys.exit(-1)
Note: See TracBrowser for help on using the browser.