root / pykota / branches / specialauth / cgi-bin / printquota.cgi @ 3574

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

Changed copyright years.

  • 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, 2007 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;charset=%s
40
41<html>
42  <head>
43    <title>%s</title>
44    <link rel="stylesheet" type="text/css" href="/pykota.css" />
45  </head>
46  <body>
47    <!-- %s %s -->
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.charset, _("PyKota Reports"), \
100                        self.language, self.charset, \
101                        self.config.getLogoLink(), \
102                        self.config.getLogoURL(), version.__version__, \
103                        self.config.getLogoLink(), \
104                        version.__version__, _("PyKota Reports"), \
105                        _("Report"))
106        print self.body
107        print footer % (_("Report"), version.__doc__, version.__years__, version.__author__, version.__gplblurb__)
108       
109    def error(self, message) :
110        """Adds an error message to the GUI's body."""
111        if message :
112            self.body = '<p><font color="red">%s</font></p>\n%s' % (message, self.body)
113       
114    def htmlListPrinters(self, selected=[], mask="*") :   
115        """Displays the printers multiple selection list."""
116        printers = self.storage.getMatchingPrinters(mask)
117        selectednames = [p.Name for p in selected]
118        message = '<table><tr><td valign="top">%s :</td><td valign="top"><select name="printers" multiple="multiple">' % _("Printer")
119        for printer in printers :
120            if printer.Name in selectednames :
121                message += '<option value="%s" selected="selected">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
122            else :
123                message += '<option value="%s">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
124        message += '</select></td></tr></table>'
125        return message
126       
127    def htmlUGNamesInput(self, value="*") :   
128        """Input field for user/group names wildcard."""
129        return _("User / Group names mask") + (' : <input type="text" name="ugmask" size="20" value="%s" /> <em>e.g. <strong>jo*</strong></em>' % (value or "*"))
130       
131    def htmlGroupsCheckbox(self, isgroup=0) :
132        """Groups checkbox."""
133        if isgroup :
134            return _("Groups report") + ' : <input type="checkbox" checked="checked" name="isgroup" />'
135        else :   
136            return _("Groups report") + ' : <input type="checkbox" name="isgroup" />'
137           
138    def guiAction(self) :
139        """Main function"""
140        printers = ugmask = isgroup = None
141        remuser = os.environ.get("REMOTE_USER", "root")   
142        # special hack to accomodate mod_auth_ldap Apache module
143        try :
144            remuser = remuser.split("=")[1].split(",")[0]
145        except IndexError :   
146            pass
147        self.body = "<p>%s</p>\n" % _("Please click on the above button")
148        if self.form.has_key("report") :
149            if self.form.has_key("printers") :
150                printersfield = self.form["printers"]
151                if type(printersfield) != type([]) :
152                    printersfield = [ printersfield ]
153                printers = [self.storage.getPrinter(p.value) for p in printersfield]
154            else :   
155                printers = self.storage.getMatchingPrinters("*")
156            if remuser == "root" :
157                if self.form.has_key("ugmask") :     
158                    ugmask = self.form["ugmask"].value
159                else :     
160                    ugmask = "*"
161            else :       
162                if self.form.has_key("isgroup") :   
163                    user = self.storage.getUser(remuser)
164                    if user.Exists :
165                        ugmask = " ".join([ g.Name for g in self.storage.getUserGroups(user) ])
166                    else :   
167                        ugmask = remuser # result will probably be empty, we don't care
168                else :   
169                    ugmask = remuser
170            if self.form.has_key("isgroup") :   
171                isgroup = 1
172            else :   
173                isgroup = 0
174        self.body += self.htmlListPrinters(printers or [])           
175        self.body += "<br />"
176        self.body += self.htmlUGNamesInput(ugmask)
177        self.body += "<br />"
178        self.body += self.htmlGroupsCheckbox(isgroup)
179        try :
180            if not self.form.has_key("history") :
181                if printers and ugmask :
182                    self.reportingtool = openReporter(admin, "html", printers, ugmask.split(), isgroup)
183                    self.body += "%s" % self.reportingtool.generateReport()
184            else :       
185                if remuser != "root" :
186                    username = remuser
187                elif self.form.has_key("username") :   
188                    username = self.form["username"].value
189                else :   
190                    username = None
191                if username is not None :   
192                    user = self.storage.getUser(username)
193                else :   
194                    user = None
195                if self.form.has_key("printername") :
196                    printer = self.storage.getPrinter(self.form["printername"].value)
197                else :   
198                    printer = None
199                if self.form.has_key("datelimit") :   
200                    datelimit = self.form["datelimit"].value
201                else :   
202                    datelimit = None
203                if self.form.has_key("hostname") :   
204                    hostname = self.form["hostname"].value
205                else :   
206                    hostname = None
207                if self.form.has_key("billingcode") :   
208                    billingcode = self.form["billingcode"].value
209                else :   
210                    billingcode = None
211                self.report = ["<h2>%s</h2>" % _("History")]   
212                history = self.storage.retrieveHistory(user=user, printer=printer, hostname=hostname, billingcode=billingcode, end=datelimit)
213                if not history :
214                    self.report.append("<h3>%s</h3>" % _("Empty"))
215                else :
216                    self.report.append('<table class="pykotatable" border="1">')
217                    headers = [_("Date"), _("Action"), _("User"), _("Printer"), \
218                               _("Hostname"), _("JobId"), _("Number of pages"), \
219                               _("Cost"), _("Copies"), _("Number of bytes"), \
220                               _("Printer's internal counter"), _("Title"), _("Filename"), \
221                               _("Options"), _("MD5Sum"), _("Billing code"), \
222                               _("Precomputed number of pages"), _("Precomputed cost"), _("Pages details") + " " + _("(not supported yet)")]
223                    self.report.append('<tr class="pykotacolsheader">%s</tr>' % "".join(["<th>%s</th>" % h for h in headers]))
224                    oddeven = 0
225                    for job in history :
226                        oddeven += 1
227                        if job.JobAction == "ALLOW" :   
228                            if oddeven % 2 :
229                                oddevenclass = "odd"
230                            else :   
231                                oddevenclass = "even"
232                        else :
233                            oddevenclass = (job.JobAction or "UNKNOWN").lower()
234                        username_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "username" : job.UserName}), job.UserName)
235                        printername_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "printername" : job.PrinterName}), job.PrinterName)
236                        if job.JobHostName :
237                            hostname_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "hostname" : job.JobHostName}), job.JobHostName)
238                        else :   
239                            hostname_url = None
240                        if job.JobBillingCode :
241                            billingcode_url = '<a href="%s?%s">%s</a>' % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode({"history" : 1, "billingcode" : job.JobBillingCode}), job.JobBillingCode)
242                        else :   
243                            billingcode_url = None
244                        curdate = DateTime.ISO.ParseDateTime(str(job.JobDate)[:19])
245                        self.report.append('<tr class="%s">%s</tr>' % \
246                                              (oddevenclass, \
247                                               "".join(["<td>%s</td>" % (h or "&nbsp;") \
248                                                  for h in (str(curdate)[:19], \
249                                                            _(job.JobAction), \
250                                                            username_url, \
251                                                            printername_url, \
252                                                            hostname_url, \
253                                                            job.JobId, \
254                                                            job.JobSize, \
255                                                            job.JobPrice, \
256                                                            job.JobCopies, \
257                                                            job.JobSizeBytes, \
258                                                            job.PrinterPageCounter, \
259                                                            job.JobTitle, \
260                                                            job.JobFileName, \
261                                                            job.JobOptions, \
262                                                            job.JobMD5Sum, \
263                                                            billingcode_url, \
264                                                            job.PrecomputedJobSize, \
265                                                            job.PrecomputedJobPrice, \
266                                                            job.JobPages)])))
267                    self.report.append('</table>')
268                    dico = { "history" : 1,
269                             "datelimit" : "%04i-%02i-%02i %02i:%02i:%02i" \
270                                                         % (curdate.year, \
271                                                            curdate.month, \
272                                                            curdate.day, \
273                                                            curdate.hour, \
274                                                            curdate.minute, \
275                                                            curdate.second),
276                           }
277                    if user and user.Exists :
278                        dico.update({ "username" : user.Name })
279                    if printer and printer.Exists :
280                        dico.update({ "printername" : printer.Name })
281                    if hostname :   
282                        dico.update({ "hostname" : hostname })
283                    prevurl = "%s?%s" % (os.environ.get("SCRIPT_NAME", ""), urllib.urlencode(dico))
284                    self.report.append('<a href="%s">%s</a>' % (prevurl, _("Previous page")))
285                self.body = "\n".join(self.report)   
286        except :
287                self.body += '<p><font color="red">%s</font></p>' % self.crashed("CGI Error").replace("\n", "<br />")
288           
289if __name__ == "__main__" :
290    admin = PyKotaReportGUI(lang=getLanguagePreference(), 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.