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

Revision 3260, 6.9 kB (checked in by jerome, 16 years ago)

Changed license to GNU GPL v3 or later.
Changed Python source encoding from ISO-8859-15 to UTF-8 (only ASCII
was used anyway).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: UTF-8 -*-
2#
3# PyKota : Print Quotas for CUPS
4#
5# (c) 2003, 2004, 2005, 2006, 2007 Jerome Alet <alet@librelogiciel.com>
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19# $Id$
20#
21#
22
23"""This module defines bases classes used by all reporters."""
24
25import os
26import imp
27from mx import DateTime
28
29class PyKotaReporterError(Exception):
30    """An exception for Reporter related stuff."""
31    def __init__(self, message = ""):
32        self.message = message
33        Exception.__init__(self, message)
34    def __repr__(self):
35        return self.message
36    __str__ = __repr__
37   
38class BaseReporter :   
39    """Base class for all reports."""
40    def __init__(self, tool, printers, ugnames, isgroup) :
41        """Initialize local datas."""
42        self.tool = tool
43        self.printers = printers
44        self.ugnames = ugnames
45        self.isgroup = isgroup
46       
47    def getPrinterTitle(self, printer) :     
48        """Returns the formatted title for a given printer."""
49        return (_("Report for %s quota on printer %s") % ((self.isgroup and "group") or "user", printer.Name)) + (" (%s)" % printer.Description)
50       
51    def getPrinterGraceDelay(self, printer) :   
52        """Returns the formatted grace delay for a given printer."""
53        return _("Pages grace time: %i days") % self.tool.config.getGraceDelay(printer.Name)
54       
55    def getPrinterPrices(self, printer) :   
56        """Returns the formatted prices for a given printer."""
57        return (_("Price per job: %.3f") % (printer.PricePerJob or 0.0), _("Price per page: %.3f") % (printer.PricePerPage or 0.0))
58           
59    def getReportHeader(self) :       
60        """Returns the correct header depending on users vs users groups."""
61        if self.isgroup :
62            return _("Group          overcharge   used    soft    hard    balance grace         total       paid warn")
63        else :   
64            return _("User           overcharge   used    soft    hard    balance grace         total       paid warn")
65           
66    def getPrinterRealPageCounter(self, printer) :       
67        """Returns the formatted real page counter for a given printer."""
68        msg = _("unknown")
69        if printer.LastJob.Exists :
70            try :
71                msg = "%9i" % printer.LastJob.PrinterPageCounter
72            except TypeError :     
73                pass
74        return _("Real : %s") % msg
75               
76    def getTotals(self, total, totalmoney) :           
77        """Returns the formatted totals."""
78        return (_("Total : %9i") % (total or 0.0), ("%11s" % ("%7.2f" % (totalmoney or 0.0))[:11]))
79           
80    def getQuota(self, entry, quota) :
81        """Prints the quota information."""
82        lifepagecounter = int(quota.LifePageCounter or 0)
83        pagecounter = int(quota.PageCounter or 0)
84        balance = float(entry.AccountBalance or 0.0)
85        lifetimepaid = float(entry.LifeTimePaid or 0.0)
86        if not hasattr(entry, "OverCharge") :
87            overcharge = _("N/A")       # Not available for groups
88        else :   
89            overcharge = float(entry.OverCharge or 0.0)
90        if not hasattr(quota, "WarnCount") :   
91            warncount = _("N/A")        # Not available for groups
92        else :   
93            warncount = int(quota.WarnCount or 0)
94       
95        if (not entry.LimitBy) or (entry.LimitBy.lower() == "quota") :
96            if (quota.HardLimit is not None) and (pagecounter >= quota.HardLimit) :   
97                datelimit = "DENY"
98            elif (quota.HardLimit is None) and (quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) :
99                datelimit = "DENY"
100            elif quota.DateLimit is not None :
101                now = DateTime.now()
102                datelimit = DateTime.ISO.ParseDateTime(str(quota.DateLimit)[:19])
103                if now >= datelimit :
104                    datelimit = "DENY"
105            else :   
106                datelimit = ""
107            reached = (((quota.SoftLimit is not None) and (pagecounter >= quota.SoftLimit) and "+") or "-") + "Q"
108        else :
109            if entry.LimitBy.lower() == "balance" :
110                balancezero = self.tool.config.getBalanceZero()
111                if balance == balancezero :
112                    if entry.OverCharge > 0 :
113                        datelimit = "DENY"
114                        reached = "+B"
115                    else :   
116                        # overcharging by a negative or nul factor means user is always allowed to print
117                        # TODO : do something when printer prices are negative as well !
118                        datelimit = ""
119                        reached = "-B"
120                elif balance < balancezero :
121                    datelimit = "DENY"
122                    reached = "+B"
123                elif balance <= self.tool.config.getPoorMan() :
124                    datelimit = "WARNING"
125                    reached = "?B"
126                else :   
127                    datelimit = ""
128                    reached = "-B"
129            elif entry.LimitBy.lower() == "noquota" :
130                reached = "NQ"
131                datelimit = ""
132            elif entry.LimitBy.lower() == "nochange" :
133                reached = "NC"
134                datelimit = ""
135            else :
136                # noprint
137                reached = "NP"
138                datelimit = "DENY"
139           
140        strbalance = ("%5.2f" % balance)[:10]
141        strlifetimepaid = ("%6.2f" % lifetimepaid)[:10]
142        strovercharge = ("%5s" % overcharge)[:5]
143        strwarncount = ("%4s" % warncount)[:4]
144        return (lifepagecounter, lifetimepaid, entry.Name, reached, \
145                pagecounter, str(quota.SoftLimit), str(quota.HardLimit), \
146                strbalance, str(datelimit)[:10], lifepagecounter, \
147                strlifetimepaid, strovercharge, strwarncount)
148       
149def openReporter(tool, reporttype, printers, ugnames, isgroup) :
150    """Returns a reporter instance of the proper reporter."""
151    try :
152        reporterbackend = imp.load_source("reporterbackend", 
153                                           os.path.join(os.path.dirname(__file__),
154                                                        "reporters",
155                                                        "%s.py" % reporttype.lower()))
156    except ImportError :
157        raise PyKotaReporterError, _("Unsupported reporter backend %s") % reporttype
158    else :   
159        return reporterbackend.Reporter(tool, printers, ugnames, isgroup)
Note: See TracBrowser for help on using the browser.