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

Revision 2229, 12.6 kB (checked in by jerome, 19 years ago)

Improved stability and allowed tracebacks in CGI scripts.
Improved pykotme.cgi to display the cost of print jobs when the user is logged-in.

  • 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22#
23# $Id$
24#
25#
26
27import sys
28import os
29import cgi
30import urllib
31
32from pykota import version
33from pykota.tool import PyKotaTool, PyKotaToolError
34from pykota.reporter import PyKotaReporterError, openReporter
35from pykota.cgifuncs import getLanguagePreference, getCharsetPreference
36
37header = """Content-type: text/html
38
39<?xml version="1.0" encoding="%s"?>
40<html>
41  <head>
42    <title>%s</title>
43    <link rel="stylesheet" type="text/css" href="/pykota.css" />
44  </head>
45  <body>
46    <form action="printquota.cgi" method="POST">
47      <table>
48        <tr>
49          <td>
50            <p>
51              <a href="http://www.librelogiciel.com/software/"><img src="http://www.librelogiciel.com/software/PyKota/pykota.png?version=%s" alt="PyKota's Logo" /></a>
52              <br />
53              <a href="http://www.librelogiciel.com/software/">PyKota v%s</a>
54            </p>
55          </td>
56          <td colspan="2">
57            <h1>%s</h1>
58          </td>
59        </tr>
60        <tr>
61          <td colspan="3" align="center">
62            <input type="submit" name="report" value="%s" />
63          </td>
64        </tr>
65      </table>"""
66   
67footer = """
68      <table>
69        <tr>
70          <td colspan="3" align="center">
71            <input type="submit" name="report" value="%s" />
72          </td>
73        </tr>
74      </table> 
75    </form>
76  </body>
77</html>""" 
78
79class PyKotaReportGUI(PyKotaTool) :
80    """PyKota Administrative GUI"""
81    def guiDisplay(self) :
82        """Displays the administrative interface."""
83        global header, footer
84        print header % (self.getCharset(), _("PyKota Reports"), version.__version__, version.__version__, _("PyKota Reports"), _("Report"))
85        print self.body
86        print footer % _("Report")
87       
88    def error(self, message) :
89        """Adds an error message to the GUI's body."""
90        if message :
91            self.body = '<p><font color="red">%s</font></p>\n%s' % (message, self.body)
92       
93    def htmlListPrinters(self, selected=[], mask="*") :   
94        """Displays the printers multiple selection list."""
95        printers = self.storage.getMatchingPrinters(mask)
96        selectednames = [p.Name for p in selected]
97        message = '<table><tr><td valign="top">%s :</td><td valign="top"><select name="printers" multiple="multiple">' % _("Printer")
98        for printer in printers :
99            if printer.Name in selectednames :
100                message += '<option value="%s" selected="selected">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
101            else :
102                message += '<option value="%s">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
103        message += '</select></td></tr></table>'
104        return message
105       
106    def htmlUGNamesInput(self, value="*") :   
107        """Input field for user/group names wildcard."""
108        return _("User / Group names mask") + (' : <input type="text" name="ugmask" size="20" value="%s" /> <em>e.g. <strong>jo*</strong></em>' % (value or "*"))
109       
110    def htmlGroupsCheckbox(self, isgroup=0) :
111        """Groups checkbox."""
112        if isgroup :
113            return _("Groups report") + ' : <input type="checkbox" checked="checked" name="isgroup" />'
114        else :   
115            return _("Groups report") + ' : <input type="checkbox" name="isgroup" />'
116           
117    def guiAction(self) :
118        """Main function"""
119        printers = ugmask = isgroup = None
120        remuser = os.environ.get("REMOTE_USER", "root")   
121        # special hack to accomodate mod_auth_ldap Apache module
122        try :
123            remuser = remuser.split("=")[1].split(",")[0]
124        except IndexError :   
125            pass
126        self.body = "<p>%s</p>\n" % _("Please click on the above button")
127        if self.form.has_key("report") :
128            if self.form.has_key("printers") :
129                printersfield = self.form["printers"]
130                if type(printersfield) != type([]) :
131                    printersfield = [ printersfield ]
132                printers = [self.storage.getPrinter(p.value) for p in printersfield]
133            else :   
134                printers = self.storage.getMatchingPrinters("*")
135            if remuser == "root" :
136                if self.form.has_key("ugmask") :     
137                    ugmask = self.form["ugmask"].value
138                else :     
139                    ugmask = "*"
140            else :       
141                if self.form.has_key("isgroup") :   
142                    user = self.storage.getUser(remuser)
143                    if user.Exists :
144                        ugmask = " ".join([ g.Name for g in self.storage.getUserGroups(user) ])
145                    else :   
146                        ugmask = remuser # result will probably be empty, we don't care
147                else :   
148                    ugmask = remuser
149            if self.form.has_key("isgroup") :   
150                isgroup = 1
151            else :   
152                isgroup = 0
153        self.body += self.htmlListPrinters(printers or [])           
154        self.body += "<br />"
155        self.body += self.htmlUGNamesInput(ugmask)
156        self.body += "<br />"
157        self.body += self.htmlGroupsCheckbox(isgroup)
158        try :
159            if not self.form.has_key("history") :
160                if printers and ugmask :
161                    self.reportingtool = openReporter(admin, "html", printers, ugmask.split(), isgroup)
162                    self.body += "%s" % self.reportingtool.generateReport()
163            else :       
164                if remuser != "root" :
165                    username = remuser
166                elif self.form.has_key("username") :   
167                    username = self.form["username"].value
168                else :   
169                    username = None
170                if username is not None :   
171                    user = self.storage.getUser(username)
172                else :   
173                    user =None
174                if self.form.has_key("printername") :
175                    printer = self.storage.getPrinter(self.form["printername"].value)
176                else :   
177                    printer = None
178                if self.form.has_key("datelimit") :   
179                    datelimit = self.form["datelimit"].value
180                else :   
181                    datelimit = None
182                if self.form.has_key("hostname") :   
183                    hostname = self.form["hostname"].value
184                else :   
185                    hostname = None
186                if self.form.has_key("billingcode") :   
187                    billingcode = self.form["billingcode"].value
188                else :   
189                    billingcode = None
190                self.report = ["<h2>%s</h2>" % _("History")]   
191                history = self.storage.retrieveHistory(user, printer, datelimit, hostname, billingcode)
192                if not history :
193                    self.report.append("<h3>%s</h3>" % _("Empty"))
194                else :
195                    self.report.append('<table class="pykotatable" border="1">')
196                    headers = [_("Date"), _("Action"), _("User"), _("Printer"), \
197                               _("Hostname"), _("JobId"), _("JobSize"), \
198                               _("JobPrice"), _("Copies"), _("JobBytes"), \
199                               _("PageCounter"), _("Title"), _("Filename"), \
200                               _("Options"), _("MD5Sum"), _("BillingCode"), \
201                               _("Pages")]
202                    self.report.append('<tr class="pykotacolsheader">%s</tr>' % "".join(["<th>%s</th>" % h for h in headers]))
203                    oddeven = 0
204                    for job in history :
205                        oddeven += 1
206                        if oddeven % 2 :
207                            oddevenclass = "odd"
208                        else :   
209                            oddevenclass = "even"
210                        if job.JobAction == "DENY" :
211                            oddevenclass = "deny"
212                        elif job.JobAction == "WARN" :   
213                            oddevenclass = "warn"
214                        username_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "username" : job.UserName}), job.UserName)
215                        printername_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "printername" : job.PrinterName}), job.PrinterName)
216                        if job.JobHostName :
217                            hostname_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "hostname" : job.JobHostName}), job.JobHostName)
218                        else :   
219                            hostname_url = None
220                        if job.JobBillingCode :
221                            billingcode_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "billingcode" : job.JobBillingCode}), job.JobBillingCode)
222                        else :   
223                            billingcode_url = None
224                        self.report.append('<tr class="%s">%s</tr>' % \
225                                              (oddevenclass, \
226                                               "".join(["<td>%s</td>" % (h or "&nbsp;") \
227                                                  for h in (job.JobDate[:19], \
228                                                            job.JobAction, \
229                                                            username_url, \
230                                                            printername_url, \
231                                                            hostname_url, \
232                                                            job.JobId, \
233                                                            job.JobSize, \
234                                                            job.JobPrice, \
235                                                            job.JobCopies, \
236                                                            job.JobSizeBytes, \
237                                                            job.PrinterPageCounter, \
238                                                            job.JobTitle, \
239                                                            job.JobFileName, \
240                                                            job.JobOptions, \
241                                                            job.JobMD5Sum, \
242                                                            billingcode_url, \
243                                                            job.JobPages)])))
244                    self.report.append('</table>')
245                    dico = { "history" : 1,
246                             "datelimit" : job.JobDate,
247                           }
248                    if user and user.Exists :
249                        dico.update({ "username" : user.Name })
250                    if printer and printer.Exists :
251                        dico.update({ "printername" : printer.Name })
252                    if hostname :   
253                        dico.update({ "hostname" : hostname })
254                    prevurl = "%s?%s" % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode(dico))
255                    self.report.append('<a href="%s">%s</a>' % (prevurl, _("Previous page")))
256                self.body = "\n".join(self.report)   
257        except :
258                self.body += '<p><font color="red">%s</font></p>' % self.crashed("CGI Error").replace("\n", "<br />")
259           
260if __name__ == "__main__" :
261    os.environ["LC_ALL"] = getLanguagePreference()
262    admin = PyKotaReportGUI(lang=os.environ["LC_ALL"], charset=getCharsetPreference())
263    admin.deferredInit()
264    admin.form = cgi.FieldStorage()
265    admin.guiAction()
266    admin.guiDisplay()
267    try :
268        admin.storage.close()
269    except (TypeError, NameError, AttributeError) :   
270        pass
271       
272    sys.exit(0)
Note: See TracBrowser for help on using the browser.