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

Revision 2578, 13.4 kB (checked in by jerome, 18 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
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      </font>
86    </p>
87  </body>
88</html>""" 
89
90class PyKotaReportGUI(PyKotaTool) :
91    """PyKota Administrative GUI"""
92    def guiDisplay(self) :
93        """Displays the administrative interface."""
94        global header, footer
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"))
101        print self.body
102        print footer % (_("Report"), version.__doc__, version.__years__, version.__author__)
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]
113        message = '<table><tr><td valign="top">%s :</td><td valign="top"><select name="printers" multiple="multiple">' % _("Printer")
114        for printer in printers :
115            if printer.Name in selectednames :
116                message += '<option value="%s" selected="selected">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
117            else :
118                message += '<option value="%s">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
119        message += '</select></td></tr></table>'
120        return message
121       
122    def htmlUGNamesInput(self, value="*") :   
123        """Input field for user/group names wildcard."""
124        return _("User / Group names mask") + (' : <input type="text" name="ugmask" size="20" value="%s" /> <em>e.g. <strong>jo*</strong></em>' % (value or "*"))
125       
126    def htmlGroupsCheckbox(self, isgroup=0) :
127        """Groups checkbox."""
128        if isgroup :
129            return _("Groups report") + ' : <input type="checkbox" checked="checked" name="isgroup" />'
130        else :   
131            return _("Groups report") + ' : <input type="checkbox" name="isgroup" />'
132           
133    def guiAction(self) :
134        """Main function"""
135        printers = ugmask = isgroup = None
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
142        self.body = "<p>%s</p>\n" % _("Please click on the above button")
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) ])
161                    else :   
162                        ugmask = remuser # result will probably be empty, we don't care
163                else :   
164                    ugmask = remuser
165            if self.form.has_key("isgroup") :   
166                isgroup = 1
167            else :   
168                isgroup = 0
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)
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 :   
189                    user = None
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")]   
207                history = self.storage.retrieveHistory(user, printer, hostname, billingcode, end=datelimit)
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"), \
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)")]
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], \
244                                                            _(job.JobAction), \
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, \
259                                                            job.PrecomputedJobSize, \
260                                                            job.PrecomputedJobPrice, \
261                                                            job.JobPages)])))
262                    self.report.append('</table>')
263                    d = DateTime.ISO.ParseDateTime(job.JobDate)       
264                    dico = { "history" : 1,
265                             "datelimit" : "%04i%02i%02i %02i:%02i:%02i" % (d.year, d.month, d.day, d.hour, d.minute, d.second),
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 />")
278           
279if __name__ == "__main__" :
280    os.environ["LC_ALL"] = getLanguagePreference()
281    admin = PyKotaReportGUI(lang=os.environ["LC_ALL"], charset=getCharsetPreference())
282    admin.deferredInit()
283    admin.form = cgi.FieldStorage()
284    admin.guiAction()
285    admin.guiDisplay()
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.