root / pykota / trunk / pykota / reporter.py @ 2054

Revision 2054, 10.0 kB (checked in by jalet, 19 years ago)

Big database structure changes. Upgrade script is now included as well as
the new LDAP schema.
Introduction of the -o | --overcharge command line option to edpykota.
The output of repykota is more complete, but doesn't fit in 80 columns anymore.
Introduction of the new 'maxdenybanners' directive.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[1048]1# PyKota
[1144]2# -*- coding: ISO-8859-15 -*-
[1048]3#
4# PyKota : Print Quotas for CUPS and LPRng
5#
[1257]6# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
[1048]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 2 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, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20#
21# $Id$
22#
23# $Log$
[2054]24# Revision 1.11  2005/02/13 22:02:29  jalet
25# Big database structure changes. Upgrade script is now included as well as
26# the new LDAP schema.
27# Introduction of the -o | --overcharge command line option to edpykota.
28# The output of repykota is more complete, but doesn't fit in 80 columns anymore.
29# Introduction of the new 'maxdenybanners' directive.
30#
[1692]31# Revision 1.10  2004/09/02 10:09:30  jalet
32# Fixed bug in LDAP user deletion code which didn't correctly delete the user's
33# pykotaLastJob entries.
34#
[1582]35# Revision 1.9  2004/07/01 17:45:49  jalet
36# Added code to handle the description field for printers
37#
[1418]38# Revision 1.8  2004/03/24 15:15:24  jalet
39# Began integration of Henrik Janhagen's work on quota-then-balance
40# and balance-then-quota
41#
[1257]42# Revision 1.7  2004/01/08 14:10:32  jalet
43# Copyright year changed.
44#
[1240]45# Revision 1.6  2003/12/27 16:49:25  uid67467
46# Should be ok now.
[1239]47#
[1235]48# Revision 1.4  2003/12/02 14:40:21  jalet
49# Some code refactoring.
50# New HTML reporter added, which is now used in the CGI script for web based
51# print quota reports. It will need some de-uglyfication though...
52#
[1219]53# Revision 1.3  2003/11/25 23:46:40  jalet
54# Don't try to verify if module name is valid, Python does this better than us.
55#
[1144]56# Revision 1.2  2003/10/07 09:07:28  jalet
57# Character encoding added to please latest version of Python
58#
[1048]59# Revision 1.1  2003/06/30 12:46:15  jalet
60# Extracted reporting code.
61#
62#
63#
64
[1240]65from mx import DateTime
66
[1048]67class PyKotaReporterError(Exception):
68    """An exception for Reporter related stuff."""
69    def __init__(self, message = ""):
70        self.message = message
71        Exception.__init__(self, message)
72    def __repr__(self):
73        return self.message
74    __str__ = __repr__
75   
76class BaseReporter :   
77    """Base class for all reports."""
78    def __init__(self, tool, printers, ugnames, isgroup) :
79        """Initialize local datas."""
80        self.tool = tool
81        self.printers = printers
82        self.ugnames = ugnames
83        self.isgroup = isgroup
84       
[1235]85    def getPrinterTitle(self, printer) :     
[1582]86        return (_("Report for %s quota on printer %s") % ((self.isgroup and "group") or "user", printer.Name)) + (" (%s)" % printer.Description)
[1235]87       
88    def getPrinterGraceDelay(self, printer) :   
89        return _("Pages grace time: %i days") % self.tool.config.getGraceDelay(printer.Name)
90       
91    def getPrinterPrices(self, printer) :   
92        return (_("Price per job: %.3f") % (printer.PricePerJob or 0.0), _("Price per page: %.3f") % (printer.PricePerPage or 0.0))
93           
94    def getReportHeader(self) :       
95        if self.isgroup :
[2054]96            return _("Group          overcharge   used    soft    hard    balance grace         total       paid warn")
[1235]97        else :   
[2054]98            return _("User           overcharge   used    soft    hard    balance grace         total       paid warn")
[1235]99           
100    def getPrinterRealPageCounter(self, printer) :       
[1692]101        msg = _("unknown")
102        if printer.LastJob.Exists :
103            try :
104                msg = "%9i" % printer.LastJob.PrinterPageCounter
105            except TypeError :     
106                pass
[1235]107        return _("Real : %s") % msg
108               
109    def getTotals(self, total, totalmoney) :           
110        return (_("Total : %9i") % (total or 0.0), ("%11s" % ("%7.2f" % (totalmoney or 0.0))[:11]))
111           
112    def getQuota(self, entry, quota) :
113        """Prints the quota information."""
114        lifepagecounter = int(quota.LifePageCounter or 0)
115        pagecounter = int(quota.PageCounter or 0)
116        balance = float(entry.AccountBalance or 0.0)
117        lifetimepaid = float(entry.LifeTimePaid or 0.0)
[2054]118        if not hasattr(entry, "OverCharge") :
119            overcharge = _("N/A")       # Not available for groups
120        else :   
121            overcharge = float(entry.OverCharge or 0.0)
122        if not hasattr(quota, "WarnCount") :   
123            warncount = _("N/A")        # Not available for groups
124        else :   
125            warncount = int(quota.WarnCount or 0)
[1582]126       
[1418]127        #balance
[1235]128        if entry.LimitBy and (entry.LimitBy.lower() == "balance") :   
129            if balance <= 0 :
130                datelimit = "DENY"
131                reached = "+B"
[1240]132            elif balance <= self.tool.config.getPoorMan() :
133                datelimit = "WARNING"
134                reached = "?B"
[1235]135            else :   
136                datelimit = ""
137                reached = "-B"
[1418]138
139        #balance-then-quota
140        elif entry.LimitBy and (entry.LimitBy.lower() == "balance-then-quota") :
141            if balance <= 0 :
142                if (quota.HardLimit is not None) and (pagecounter >= quota.HardLimit) :
143                    datelimit = "DENY"
144                elif (quota.HardLimit is None) and (quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) :
145                    datelimit = "DENY"
146                elif quota.DateLimit is not None :
147                    now = DateTime.now()
148                    datelimit = DateTime.ISO.ParseDateTime(quota.DateLimit)
149                    if now >= datelimit :
150                        datelimit = "QUOTA_DENY"
151                else :
152                    datelimit = ""
153                reached = ( ((datelimit == "DENY" ) and "+B") or "-Q")
154                datelimit = ( ((datelimit == "QUOTA_DENY") and "DENY") or datelimit)
155            elif balance <= self.tool.config.getPoorMan() :
156                if (quota.HardLimit is not None) and (pagecounter >= quota.HardLimit) :
157                    datelimit = "WARNING"
158                elif (quota.HardLimit is None) and (quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) :
159                    datelimit = "WARNING"
160                elif quota.DateLimit is not None :
161                    now = DateTime.now()
162                    datelimit = DateTime.ISO.ParseDateTime(quota.DateLimit)
163                    if now >= datelimit :
164                        datelimit = "QUOTA_DENY"
165                else :
166                    datelimit = ""
167                reached = ( ((datelimit == "WARNING" ) and "?B") or "+Q")
168                datelimit = ( ((datelimit == "QUOTA_DENY") and "WARNING") or datelimit)
169            else :
170                datelimit = ""
171                reached = "-B"
172
173        #Quota-then-balance
174        elif entry.LimitBy and (entry.LimitBy.lower() == "quota-then-balance") :
175            if (quota.HardLimit is not None) and (pagecounter >= quota.HardLimit) :
176                datelimit = "DENY"
177            elif (quota.HardLimit is None) and (quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) :
178                datelimit = "DENY"
179            elif quota.DateLimit is not None :
180                now = DateTime.now()
181                datelimit = DateTime.ISO.ParseDateTime(quota.DateLimit)
182                if now >= datelimit :
183                    datelimit = "DENY"
184            else :
185                datelimit = ""
186               
187            reached = (((quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) and "+") or "-") + "Q"
188
189            if (datelimit == "DENY") and (reached == "-Q") and (balance > self.tool.config.getPoorMan()) :
190                datelimit = ""
191                reached = "-B"
192            else :
193                reached = (((datelimit == "DENY") and (self.tool.config.getPoorMan() < balance ) and "-B") or reached)
194                if (datelimit == "DENY") and (self.tool.config.getPoorMan() < balance) :
195                    datelimit = ""
196                reached = (((datelimit == "DENY") and (0.0 < balance <= self.tool.config.getPoorMan()) and "?B") or reached)
197                datelimit = (((datelimit == "DENY") and (0.0 < balance <= self.tool.config.getPoorMan()) and "WARNING") or datelimit)
198
199        #Quota
[1235]200        else :
[1240]201            if (quota.HardLimit is not None) and (pagecounter >= quota.HardLimit) :   
202                datelimit = "DENY"
203            elif (quota.HardLimit is None) and (quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) :
204                datelimit = "DENY"
205            elif quota.DateLimit is not None :
[1235]206                now = DateTime.now()
207                datelimit = DateTime.ISO.ParseDateTime(quota.DateLimit)
208                if now >= datelimit :
209                    datelimit = "DENY"
210            else :   
211                datelimit = ""
212            reached = (((quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) and "+") or "-") + "Q"
213           
214        strbalance = ("%5.2f" % balance)[:10]
215        strlifetimepaid = ("%6.2f" % lifetimepaid)[:10]
[2054]216        strovercharge = ("%5s" % overcharge)[:5]
217        strwarncount = ("%4s" % warncount)[:4]
218        return (lifepagecounter, lifetimepaid, entry.Name, reached, \
219                pagecounter, str(quota.SoftLimit), str(quota.HardLimit), \
220                strbalance, str(datelimit)[:10], lifepagecounter, \
221                strlifetimepaid, strovercharge, strwarncount)
[1235]222       
[1048]223def openReporter(tool, reporttype, printers, ugnames, isgroup) :
224    """Returns a reporter instance of the proper reporter."""
225    try :
[1219]226        exec "from pykota.reporters import %s as reporterbackend" % reporttype.lower()
[1048]227    except ImportError :
228        raise PyKotaReporterError, _("Unsupported reporter backend %s") % reporttype
229    else :   
[1240]230        return reporterbackend.Reporter(tool, printers, ugnames, isgroup)
Note: See TracBrowser for help on using the browser.