root / pykota / trunk / cgi-bin / pykotme.cgi @ 3549

Revision 3549, 7.9 kB (checked in by jerome, 14 years ago)

Removed support for the MaxJobSize? attribute for users group print quota
entries : I couldn't see a real use for this at the moment, and it would
complexify the code. This support might reappear later however. Added full
support for the MaxJobSize? attribute for user print quota entries,
editable with edpykota's new --maxjobsize command line switch. Changed
the internal handling of the MaxJobSize? attribute for printers :
internally 0 used to mean unlimited, it now allows one to forbid
printing onto a particular printer. The database upgrade script (only
for PostgreSQL) takes care of this.
IMPORTANT : the database schema changes. A database upgrade script is
provided for PostgreSQL only. The LDAP schema doesn't change to not
break any existing LDAP directory, so the pykotaMaxJobSize attribute is
still allowed on group print quota entries, but never used.
Seems to work as expected, for a change :-)
Fixes #15.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Rev
Line 
1#! /usr/bin/python
2# -*- coding: utf-8 -*-
3
4# PyKota Print Quotes generator
5#
6# PyKota - Print Quotas for CUPS
7#
8# (c) 2003-2009 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 3 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, see <http://www.gnu.org/licenses/>.
21#
22# $Id$
23#
24#
25
26import sys
27import os
28import cgi
29import urllib
30import cStringIO
31from xml.sax import saxutils
32
33import pykota.appinit
34
35from pykota import version, utils
36from pykota.tool import PyKotaTool
37from pykota.errors import PyKotaToolError
38
39from pkpgpdls import analyzer, pdlparser
40
41
42header = """Content-type: text/html;charset=%s
43
44<html>
45  <head>
46    <title>%s</title>
47    <link rel="stylesheet" type="text/css" href="/pykota.css" />
48  </head>
49  <body>
50    <p>
51      <form action="pykotme.cgi" method="POST" enctype="multipart/form-data">
52        <table>
53          <tr>
54            <td>
55              <p>
56                <a href="%s"><img src="%s?version=%s" alt="PyKota's Logo" /></a>
57                <br />
58                <a href="%s">PyKota v%s</a>
59              </p>
60            </td>
61            <td colspan="2">
62              <h1>%s</h1>
63            </td>
64          </tr>
65          <tr>
66            <td colspan="3" align="center">
67              <input type="submit" name="report" value="%s" />
68            </td>
69          </tr>
70        </table>"""
71
72footer = """
73        <table>
74          <tr>
75            <td colspan="3" align="center">
76              <input type="submit" name="report" value="%s" />
77            </td>
78          </tr>
79        </table>
80      </form>
81    </p>
82    <hr width="25%%" />
83    <p>
84      <font size="-2">
85        <a href="http://www.pykota.com/">%s</a>
86        &copy; %s %s
87        <br />
88        <pre>
89%s
90        </pre>
91      </font>
92    </p>
93  </body>
94</html>"""
95
96class PyKotMeGUI(PyKotaTool) :
97    """PyKota Quote's Generator GUI"""
98    def guiDisplay(self) :
99        """Displays the administrative interface."""
100        global header, footer
101        content = [ header % (self.charset, _("PyKota Quotes"), \
102                        self.config.getLogoLink(), \
103                        self.config.getLogoURL(), version.__version__, \
104                        self.config.getLogoLink(), \
105                        version.__version__, _("PyKota Quotes"), \
106                        _("Quote")) ]
107        content.append(self.body)
108        content.append(footer % (_("Quote"),
109                                 version.__doc__,
110                                 version.__years__,
111                                 version.__author__,
112                                 saxutils.escape(version.__gplblurb__)))
113        for c in content :
114            sys.stdout.write(c.encode(self.charset, "replace"))
115        sys.stdout.flush()
116
117    def error(self, message) :
118        """Adds an error message to the GUI's body."""
119        if message :
120            self.body = '<p><font color="red">%s</font></p>\n%s' % (message, self.body)
121
122    def htmlListPrinters(self, selected=[], mask="*") :
123        """Displays the printers multiple selection list."""
124        printers = self.storage.getMatchingPrinters(mask)
125        selectednames = [p.Name for p in selected]
126        message = '<table><tr><td valign="top">%s :</td><td valign="top"><select name="printers" multiple="multiple">' % _("Printer")
127        for printer in printers :
128            if printer.Name in selectednames :
129                message += '<option value="%s" selected="selected">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
130            else :
131                message += '<option value="%s">%s (%s)</option>' % (printer.Name, printer.Name, printer.Description)
132        message += '</select></td></tr></table>'
133        return message
134
135    def guiAction(self) :
136        """Main function"""
137        printers = inputfile = None
138        self.body = "<p>%s</p>\n" % _("Please click on the above button")
139        if self.form.has_key("report") :
140            if self.form.has_key("printers") :
141                printersfield = self.form["printers"]
142                if type(printersfield) != type([]) :
143                    printersfield = [ printersfield ]
144                printers = [self.storage.getPrinter(p.value) for p in printersfield]
145            else :
146                printers = self.storage.getMatchingPrinters("*")
147            if self.form.has_key("inputfile") :
148                inputfile = self.form["inputfile"].value
149
150        if os.environ.get("REMOTE_USER") is not None :
151            self.body += self.htmlListPrinters(printers or [])
152            self.body += "<br />"
153        self.body += _("Filename") + " : "
154        self.body += '<input type="file" size="64" name="inputfile" />'
155        self.body += "<br />"
156        if inputfile :
157            try :
158                parser = analyzer.PDLAnalyzer(cStringIO.StringIO(inputfile))
159                jobsize = parser.getJobSize()
160            except pdlparser.PDLParserError, msg :
161                self.body += '<p><font color="red">%s</font></p>' % msg
162                jobsize = 0 # unknown file format ?
163            else :
164                self.body += "<p>%s</p>" % (_("Job size : %i pages") % jobsize)
165
166            remuser = os.environ.get("REMOTE_USER")
167            # special hack to accomodate mod_auth_ldap Apache module
168            try :
169                remuser = remuser.split("=")[1].split(",")[0]
170            except :
171                pass
172            if not remuser :
173                self.body += "<p>%s</p>" % _("The exact cost of a print job can only be determined for a particular user. Please retry while logged-in.")
174            else :
175                try :
176                    user = self.storage.getUser(remuser)
177                    if user.Exists :
178                        if user.LimitBy == "noprint" :
179                            self.body += "<p>%s</p>" % _("Your account settings forbid you to print at this time.")
180                        else :
181                            for printer in printers :
182                                upquota = self.storage.getUserPQuota(user, printer)
183                                if upquota.Exists :
184                                    if (printer.MaxJobSize and (jobsize > printer.MaxJobSize)) \
185                                            or (upquota.MaxJobSize and (jobsize > upquota.MaxJobSize)) :
186                                        msg = _("You are not allowed to print so many pages on printer %s at this time.") % printer.Name
187                                    else :
188                                        cost = upquota.computeJobPrice(jobsize)
189                                        msg = _("Cost on printer %s : %.2f") % (printer.Name, cost)
190                                        if printer.PassThrough :
191                                            msg = "%s (%s)" % (msg, _("won't be charged, printer is in passthrough mode"))
192                                        elif user.LimitBy == "nochange" :
193                                            msg = "%s (%s)" % (msg, _("won't be charged, your account is immutable"))
194                                    self.body += "<p>%s</p>" % msg
195                except :
196                    self.body += '<p><font color="red">%s</font></p>' % self.crashed("CGI Error").replace("\n", "<br />")
197
198if __name__ == "__main__" :
199    utils.reinitcgilocale()
200    admin = PyKotMeGUI()
201    admin.deferredInit()
202    admin.form = cgi.FieldStorage()
203    admin.guiAction()
204    admin.guiDisplay()
205    try :
206        admin.storage.close()
207    except (TypeError, NameError, AttributeError) :
208        pass
209
210    sys.exit(0)
Note: See TracBrowser for help on using the browser.