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

Revision 2953, 13.9 kB (checked in by jerome, 18 years ago)

Fixed date formatting problems with MySQL.

  • 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, 2006 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.pykota.com/">%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 job.JobAction == "ALLOW" :   
227                            if oddeven % 2 :
228                                oddevenclass = "odd"
229                            else :   
230                                oddevenclass = "even"
231                        else :
232                            oddevenclass = (job.JobAction or "UNKNOWN").lower()
233                        username_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "username" : job.UserName}), job.UserName)
234                        printername_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "printername" : job.PrinterName}), job.PrinterName)
235                        if job.JobHostName :
236                            hostname_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "hostname" : job.JobHostName}), job.JobHostName)
237                        else :   
238                            hostname_url = None
239                        if job.JobBillingCode :
240                            billingcode_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "billingcode" : job.JobBillingCode}), job.JobBillingCode)
241                        else :   
242                            billingcode_url = None
243                        curdate = DateTime.ISO.ParseDateTime(str(job.JobDate))
244                        self.report.append('<tr class="%s">%s</tr>' % \
245                                              (oddevenclass, \
246                                               "".join(["<td>%s</td>" % (h or "&nbsp;") \
247                                                  for h in (str(curdate)[:19], \
248                                                            _(job.JobAction), \
249                                                            username_url, \
250                                                            printername_url, \
251                                                            hostname_url, \
252                                                            job.JobId, \
253                                                            job.JobSize, \
254                                                            job.JobPrice, \
255                                                            job.JobCopies, \
256                                                            job.JobSizeBytes, \
257                                                            job.PrinterPageCounter, \
258                                                            job.JobTitle, \
259                                                            job.JobFileName, \
260                                                            job.JobOptions, \
261                                                            job.JobMD5Sum, \
262                                                            billingcode_url, \
263                                                            job.PrecomputedJobSize, \
264                                                            job.PrecomputedJobPrice, \
265                                                            job.JobPages)])))
266                    self.report.append('</table>')
267                    dico = { "history" : 1,
268                             "datelimit" : "%04i-%02i-%02i %02i:%02i:%02i" \
269                                                         % (curdate.year, \
270                                                            curdate.month, \
271                                                            curdate.day, \
272                                                            curdate.hour, \
273                                                            curdate.minute, \
274                                                            curdate.second),
275                           }
276                    if user and user.Exists :
277                        dico.update({ "username" : user.Name })
278                    if printer and printer.Exists :
279                        dico.update({ "printername" : printer.Name })
280                    if hostname :   
281                        dico.update({ "hostname" : hostname })
282                    prevurl = "%s?%s" % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode(dico))
283                    self.report.append('<a href="%s">%s</a>' % (prevurl, _("Previous page")))
284                self.body = "\n".join(self.report)   
285        except :
286                self.body += '<p><font color="red">%s</font></p>' % self.crashed("CGI Error").replace("\n", "<br />")
287           
288if __name__ == "__main__" :
289    os.environ["LC_ALL"] = getLanguagePreference()
290    admin = PyKotaReportGUI(lang=os.environ["LC_ALL"], charset=getCharsetPreference())
291    admin.deferredInit()
292    admin.form = cgi.FieldStorage()
293    admin.guiAction()
294    admin.guiDisplay()
295    try :
296        admin.storage.close()
297    except (TypeError, NameError, AttributeError) :   
298        pass
299       
300    sys.exit(0)
Note: See TracBrowser for help on using the browser.