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

Revision 2586, 13.6 kB (checked in by jerome, 19 years ago)

Now includes a snippet of the GNU GPL at the bottom of CGI pages

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