root / pykota / trunk / cgi-bin / printquota.cgi @ 2578

Revision 2578, 13.4 kB (checked in by jerome, 19 years ago)

Missing a space, this looked ugly :-)

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[1240]1#! /usr/bin/python
[1635]2# -*- coding: ISO-8859-15 -*-
[794]3
4# PyKota Print Quota Reports generator
5#
[952]6# PyKota - Print Quotas for CUPS and LPRng
[794]7#
[2028]8# (c) 2003, 2004, 2005 Jerome Alet <alet@librelogiciel.com>
[873]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.
[794]13#
[873]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
[2303]21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
[794]22#
23# $Id$
24#
[2056]25#
[794]26
27import sys
28import os
29import cgi
[1274]30import urllib
[794]31
[2266]32from mx import DateTime
33
[1048]34from pykota import version
35from pykota.tool import PyKotaTool, PyKotaToolError
[1049]36from pykota.reporter import PyKotaReporterError, openReporter
[2018]37from pykota.cgifuncs import getLanguagePreference, getCharsetPreference
[1048]38
[799]39header = """Content-type: text/html
[794]40
[1763]41<?xml version="1.0" encoding="%s"?>
[799]42<html>
43  <head>
[1614]44    <title>%s</title>
[1274]45    <link rel="stylesheet" type="text/css" href="/pykota.css" />
[799]46  </head>
47  <body>
[2265]48    <p>
49      <form action="printquota.cgi" method="POST">
50        <table>
51          <tr>
52            <td>
53              <p>
54                <a href="%s"><img src="%s?version=%s" alt="PyKota's Logo" /></a>
55                <br />
56                <a href="%s">PyKota v%s</a>
57              </p>
58            </td>
59            <td colspan="2">
60              <h1>%s</h1>
61            </td>
62          </tr>
63          <tr>
64            <td colspan="3" align="center">
65              <input type="submit" name="report" value="%s" />
66            </td>
67          </tr>
68        </table>"""
[1049]69   
[799]70footer = """
[2265]71        <table>
72          <tr>
73            <td colspan="3" align="center">
74              <input type="submit" name="report" value="%s" />
75            </td>
76          </tr>
77        </table> 
78      </form>
79    </p>
80    <hr width="25%%" />
81    <p>
82      <font size="-2">
83        <a href="http://www.librelogiciel.com/software/">%s</a>
[2267]84        &copy; %s %s
[2265]85      </font>
86    </p>
[799]87  </body>
88</html>""" 
[794]89
[1049]90class PyKotaReportGUI(PyKotaTool) :
91    """PyKota Administrative GUI"""
92    def guiDisplay(self) :
93        """Displays the administrative interface."""
94        global header, footer
[2265]95        print header % (self.getCharset(), _("PyKota Reports"), \
96                        self.config.getLogoLink(), \
97                        self.config.getLogoURL(), version.__version__, \
98                        self.config.getLogoLink(), \
99                        version.__version__, _("PyKota Reports"), \
100                        _("Report"))
[1049]101        print self.body
[2344]102        print footer % (_("Report"), version.__doc__, version.__years__, version.__author__)
[1049]103       
104    def error(self, message) :
105        """Adds an error message to the GUI's body."""
106        if message :
107            self.body = '<p><font color="red">%s</font></p>\n%s' % (message, self.body)
108       
109    def htmlListPrinters(self, selected=[], mask="*") :   
110        """Displays the printers multiple selection list."""
111        printers = self.storage.getMatchingPrinters(mask)
112        selectednames = [p.Name for p in selected]
[1817]113        message = '<table><tr><td valign="top">%s :</td><td valign="top"><select name="printers" multiple="multiple">' % _("Printer")
[1049]114        for printer in printers :
115            if printer.Name in selectednames :
[1582]116                message += '<option value="%s" selected="selected">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
[1049]117            else :
[1582]118                message += '<option value="%s">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
[1054]119        message += '</select></td></tr></table>'
[1049]120        return message
121       
122    def htmlUGNamesInput(self, value="*") :   
123        """Input field for user/group names wildcard."""
[1614]124        return _("User / Group names mask") + (' : <input type="text" name="ugmask" size="20" value="%s" /> <em>e.g. <strong>jo*</strong></em>' % (value or "*"))
[1049]125       
126    def htmlGroupsCheckbox(self, isgroup=0) :
127        """Groups checkbox."""
128        if isgroup :
[1614]129            return _("Groups report") + ' : <input type="checkbox" checked="checked" name="isgroup" />'
[1049]130        else :   
[1614]131            return _("Groups report") + ' : <input type="checkbox" name="isgroup" />'
[1049]132           
133    def guiAction(self) :
134        """Main function"""
135        printers = ugmask = isgroup = None
[2032]136        remuser = os.environ.get("REMOTE_USER", "root")   
137        # special hack to accomodate mod_auth_ldap Apache module
138        try :
139            remuser = remuser.split("=")[1].split(",")[0]
140        except IndexError :   
141            pass
[1817]142        self.body = "<p>%s</p>\n" % _("Please click on the above button")
[1763]143        if self.form.has_key("report") :
144            if self.form.has_key("printers") :
145                printersfield = self.form["printers"]
146                if type(printersfield) != type([]) :
147                    printersfield = [ printersfield ]
148                printers = [self.storage.getPrinter(p.value) for p in printersfield]
149            else :   
150                printers = self.storage.getMatchingPrinters("*")
151            if remuser == "root" :
152                if self.form.has_key("ugmask") :     
153                    ugmask = self.form["ugmask"].value
154                else :     
155                    ugmask = "*"
156            else :       
157                if self.form.has_key("isgroup") :   
158                    user = self.storage.getUser(remuser)
159                    if user.Exists :
160                        ugmask = " ".join([ g.Name for g in self.storage.getUserGroups(user) ])
[1121]161                    else :   
[1763]162                        ugmask = remuser # result will probably be empty, we don't care
[1049]163                else :   
[1763]164                    ugmask = remuser
165            if self.form.has_key("isgroup") :   
166                isgroup = 1
167            else :   
168                isgroup = 0
[1049]169        self.body += self.htmlListPrinters(printers or [])           
170        self.body += "<br />"
171        self.body += self.htmlUGNamesInput(ugmask)
172        self.body += "<br />"
173        self.body += self.htmlGroupsCheckbox(isgroup)
[2229]174        try :
175            if not self.form.has_key("history") :
176                if printers and ugmask :
177                    self.reportingtool = openReporter(admin, "html", printers, ugmask.split(), isgroup)
178                    self.body += "%s" % self.reportingtool.generateReport()
179            else :       
180                if remuser != "root" :
181                    username = remuser
182                elif self.form.has_key("username") :   
183                    username = self.form["username"].value
184                else :   
185                    username = None
186                if username is not None :   
187                    user = self.storage.getUser(username)
188                else :   
[2578]189                    user = None
[2229]190                if self.form.has_key("printername") :
191                    printer = self.storage.getPrinter(self.form["printername"].value)
192                else :   
193                    printer = None
194                if self.form.has_key("datelimit") :   
195                    datelimit = self.form["datelimit"].value
196                else :   
197                    datelimit = None
198                if self.form.has_key("hostname") :   
199                    hostname = self.form["hostname"].value
200                else :   
201                    hostname = None
202                if self.form.has_key("billingcode") :   
203                    billingcode = self.form["billingcode"].value
204                else :   
205                    billingcode = None
206                self.report = ["<h2>%s</h2>" % _("History")]   
[2266]207                history = self.storage.retrieveHistory(user, printer, hostname, billingcode, end=datelimit)
[2229]208                if not history :
209                    self.report.append("<h3>%s</h3>" % _("Empty"))
210                else :
211                    self.report.append('<table class="pykotatable" border="1">')
212                    headers = [_("Date"), _("Action"), _("User"), _("Printer"), \
[2485]213                               _("Hostname"), _("JobId"), _("Number of pages"), \
214                               _("Cost"), _("Copies"), _("Number of bytes"), \
215                               _("Printer's internal counter"), _("Title"), _("Filename"), \
216                               _("Options"), _("MD5Sum"), _("Billing code"), \
217                               _("Precomputed number of pages"), _("Precomputed cost"), _("Pages details") + " " + _("(not supported yet)")]
[2229]218                    self.report.append('<tr class="pykotacolsheader">%s</tr>' % "".join(["<th>%s</th>" % h for h in headers]))
219                    oddeven = 0
220                    for job in history :
221                        oddeven += 1
222                        if oddeven % 2 :
223                            oddevenclass = "odd"
224                        else :   
225                            oddevenclass = "even"
226                        if job.JobAction == "DENY" :
227                            oddevenclass = "deny"
228                        elif job.JobAction == "WARN" :   
229                            oddevenclass = "warn"
230                        username_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "username" : job.UserName}), job.UserName)
231                        printername_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "printername" : job.PrinterName}), job.PrinterName)
232                        if job.JobHostName :
233                            hostname_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "hostname" : job.JobHostName}), job.JobHostName)
234                        else :   
235                            hostname_url = None
236                        if job.JobBillingCode :
237                            billingcode_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "billingcode" : job.JobBillingCode}), job.JobBillingCode)
238                        else :   
239                            billingcode_url = None
240                        self.report.append('<tr class="%s">%s</tr>' % \
241                                              (oddevenclass, \
242                                               "".join(["<td>%s</td>" % (h or "&nbsp;") \
243                                                  for h in (job.JobDate[:19], \
[2496]244                                                            _(job.JobAction), \
[2229]245                                                            username_url, \
246                                                            printername_url, \
247                                                            hostname_url, \
248                                                            job.JobId, \
249                                                            job.JobSize, \
250                                                            job.JobPrice, \
251                                                            job.JobCopies, \
252                                                            job.JobSizeBytes, \
253                                                            job.PrinterPageCounter, \
254                                                            job.JobTitle, \
255                                                            job.JobFileName, \
256                                                            job.JobOptions, \
257                                                            job.JobMD5Sum, \
258                                                            billingcode_url, \
[2455]259                                                            job.PrecomputedJobSize, \
260                                                            job.PrecomputedJobPrice, \
[2229]261                                                            job.JobPages)])))
262                    self.report.append('</table>')
[2266]263                    d = DateTime.ISO.ParseDateTime(job.JobDate)       
[2229]264                    dico = { "history" : 1,
[2266]265                             "datelimit" : "%04i%02i%02i %02i:%02i:%02i" % (d.year, d.month, d.day, d.hour, d.minute, d.second),
[2229]266                           }
267                    if user and user.Exists :
268                        dico.update({ "username" : user.Name })
269                    if printer and printer.Exists :
270                        dico.update({ "printername" : printer.Name })
271                    if hostname :   
272                        dico.update({ "hostname" : hostname })
273                    prevurl = "%s?%s" % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode(dico))
274                    self.report.append('<a href="%s">%s</a>' % (prevurl, _("Previous page")))
275                self.body = "\n".join(self.report)   
276        except :
277                self.body += '<p><font color="red">%s</font></p>' % self.crashed("CGI Error").replace("\n", "<br />")
[1172]278           
[1049]279if __name__ == "__main__" :
[2018]280    os.environ["LC_ALL"] = getLanguagePreference()
281    admin = PyKotaReportGUI(lang=os.environ["LC_ALL"], charset=getCharsetPreference())
[2210]282    admin.deferredInit()
[1049]283    admin.form = cgi.FieldStorage()
284    admin.guiAction()
285    admin.guiDisplay()
[1113]286    try :
287        admin.storage.close()
288    except (TypeError, NameError, AttributeError) :   
289        pass
290       
291    sys.exit(0)
Note: See TracBrowser for help on using the browser.