root / pykota / trunk / bin / pykota @ 1205

Revision 1205, 11.4 kB (checked in by jalet, 20 years ago)

Missing import in pykota filter

  • 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/env python
2# -*- coding: ISO-8859-15 -*-
3
4# PyKota accounting filter
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003 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# $Log$
26# Revision 1.46  2003/11/24 14:25:02  jalet
27# Missing import in pykota filter
28#
29# Revision 1.45  2003/11/19 23:19:37  jalet
30# Code refactoring work.
31# Explicit redirection to /dev/null has to be set in external policy now, just
32# like in external mailto.
33#
34# Revision 1.44  2003/11/08 16:05:31  jalet
35# CUPS backend added for people to experiment.
36#
37# Revision 1.43  2003/11/06 22:33:25  jalet
38# French variable name
39#
40# Revision 1.42  2003/10/08 21:41:38  jalet
41# External policies for printers works !
42# We can now auto-add users on first print, and do other useful things if needed.
43#
44# Revision 1.41  2003/10/07 09:07:27  jalet
45# Character encoding added to please latest version of Python
46#
47# Revision 1.40  2003/09/04 08:38:56  jalet
48# Added an exception catch to ensure clean close of database even in
49# case of TypeError too.
50#
51# Revision 1.39  2003/08/18 16:35:28  jalet
52# New pychecker pass, on the tools this time.
53#
54# Revision 1.38  2003/08/18 16:20:59  jalet
55# Improvement of the printing system detection code.
56#
57# Revision 1.37  2003/07/29 20:55:17  jalet
58# 1.14 is out !
59#
60# Revision 1.36  2003/07/10 06:09:52  jalet
61# Incorrect documentation string
62#
63# Revision 1.35  2003/06/25 14:10:01  jalet
64# Hey, it may work (edpykota --reset excepted) !
65#
66# Revision 1.34  2003/06/13 18:54:17  jalet
67# Bug with remote jobs and LPRng fixed.
68#
69# Revision 1.33  2003/05/28 13:51:38  jalet
70# Better handling of errors
71#
72# Revision 1.32  2003/05/27 23:00:20  jalet
73# Big rewrite of external accounting methods.
74# Should work well now.
75#
76# Revision 1.31  2003/04/30 13:36:39  jalet
77# Stupid accounting method was added.
78#
79# Revision 1.30  2003/04/29 22:03:38  jalet
80# Better error handling.
81#
82# Revision 1.29  2003/04/29 18:37:54  jalet
83# Pluggable accounting methods (actually doesn't support external scripts)
84#
85# Revision 1.28  2003/04/26 08:41:24  jalet
86# Small code reorganisation (UNTESTED) to allow pluggable accounting
87# methods in the future.
88#
89# Revision 1.27  2003/04/25 09:23:47  jalet
90# Debug message passed through !
91#
92# Revision 1.26  2003/04/25 08:23:23  jalet
93# Multiple tries to get the printer's internal page counter, waits for
94# one minute maximum for the printer to warm up, actually.
95#
96# Revision 1.25  2003/04/24 11:53:48  jalet
97# Default policy for unknown users/groups is to DENY printing instead
98# of the previous default to ALLOW printing. This is to solve an accuracy
99# problem. If you set the policy to ALLOW, jobs printed by in nexistant user
100# (from PyKota's POV) will be charged to the next user who prints on the
101# same printer.
102#
103# Revision 1.24  2003/04/23 22:13:56  jalet
104# Preliminary support for LPRng added BUT STILL UNTESTED.
105#
106# Revision 1.23  2003/04/15 11:30:57  jalet
107# More work done on money print charging.
108# Minor bugs corrected.
109# All tools now access to the storage as priviledged users, repykota excepted.
110#
111# Revision 1.22  2003/04/15 11:09:04  jalet
112# Small bug was fixed when a printer was never used and its internal
113# page counter is not accessible.
114#
115# Revision 1.21  2003/04/12 17:20:14  jalet
116# Better formula for HP workaround
117#
118# Revision 1.20  2003/04/12 16:58:28  jalet
119# The workaround for HP printers was not correct, and there's probably no
120# correct way to workaround the problem because we can't save the internal
121# page counter in real time. The last job's size is unconditionnally set to
122# 5 pages in this case.
123#
124# Revision 1.19  2003/04/11 08:56:49  jalet
125# Comment
126#
127# Revision 1.18  2003/04/11 08:50:39  jalet
128# Workaround for the HP "feature" of saving the page counter to NVRAM
129# only every time 10 new pages are printed...
130# Workaround for printers with volatile page counters.
131#
132# Revision 1.17  2003/04/10 21:47:20  jalet
133# Job history added. Upgrade script neutralized for now !
134#
135# Revision 1.16  2003/04/08 20:38:08  jalet
136# The last job Id is saved now for each printer, this will probably
137# allow other accounting methods in the future.
138#
139# Revision 1.15  2003/03/29 13:45:27  jalet
140# GPL paragraphs were incorrectly (from memory) copied into the sources.
141# Two README files were added.
142# Upgrade script for PostgreSQL pre 1.01 schema was added.
143#
144# Revision 1.14  2003/03/07 22:16:57  jalet
145# Algorithmically incorrect : last user quota wasn't updated if current
146# user wasn't allowed to print.
147#
148# Revision 1.13  2003/02/27 23:59:28  jalet
149# Stupid bug wrt exception handlingand value conversion
150#
151# Revision 1.12  2003/02/27 23:48:41  jalet
152# Correctly maps PyKota's log levels to syslog log levels
153#
154# Revision 1.11  2003/02/27 22:55:20  jalet
155# WARN log priority doesn't exist.
156#
157# Revision 1.10  2003/02/27 22:43:21  jalet
158# Missing import
159#
160# Revision 1.9  2003/02/27 22:40:26  jalet
161# Correctly handles cases where the printer is off.
162#
163# Revision 1.8  2003/02/09 12:56:53  jalet
164# Internationalization begins...
165#
166# Revision 1.7  2003/02/07 10:23:48  jalet
167# Avoid a possible future name clash
168#
169# Revision 1.6  2003/02/06 22:54:33  jalet
170# warnpykota should be ok
171#
172# Revision 1.5  2003/02/05 22:45:25  jalet
173# Forgotten import
174#
175# Revision 1.4  2003/02/05 22:42:51  jalet
176# Typo
177#
178# Revision 1.3  2003/02/05 22:38:39  jalet
179# Typo
180#
181# Revision 1.2  2003/02/05 22:16:20  jalet
182# DEVICE_URI is undefined outside of CUPS, i.e. for normal command line tools
183#
184# Revision 1.1  2003/02/05 21:28:17  jalet
185# Initial import into CVS
186#
187#
188#
189
190import sys
191import os
192
193from pykota.tool import PyKotaFilterOrBackend, PyKotaToolError
194from pykota.config import PyKotaConfigError
195from pykota.storage import PyKotaStorageError
196from pykota.accounter import PyKotaAccounterError
197from pykota.requester import PyKotaRequesterError
198
199class PyKotaFilter(PyKotaFilterOrBackend) :       
200    """A class for the pykota filter."""
201    def acceptJob(self) :       
202        """Returns the exit code needed by the printing backend to accept the job and print it."""
203        if self.printingsystem == "CUPS" :
204            return 0
205        elif self.printingsystem == "LPRNG" :   
206            return 0
207        else :   
208            # UNKNOWN
209            return -1
210           
211    def removeJob(self) :           
212        """Returns the exit code needed by the printing backend to refuse the job and remove it."""
213        if self.printingsystem == "CUPS" :
214            return 1
215        elif self.printingsystem == "LPRNG" :   
216            return 3
217        else :   
218            # UNKNOWN
219            return -1
220           
221def main(thefilter) :   
222    """Do it, and do it right !"""
223    #
224    # If this is a CUPS filter, we should act and die like a CUPS filter when needed
225    if thefilter.printingsystem == "CUPS" :
226        if len(sys.argv) not in (6, 7) :   
227            sys.stderr.write("ERROR: %s job-id user title copies options [file]\n" % sys.argv[0])
228            return thefilter.removeJob()
229   
230    # Get the last page counter and last username from the Quota Storage backend
231    printer = thefilter.storage.getPrinter(thefilter.printername)
232    if not printer.Exists :
233        # The printer is unknown from the Quota Storage perspective
234        # we let the job pass through, but log a warning message
235        thefilter.logger.log_message(_("Printer %s not registered in the PyKota system") % thefilter.printername, "warn")
236    else :   
237        for dummy in range(2) :
238            user = thefilter.storage.getUser(thefilter.username)
239            if user.Exists :
240                break
241            else :   
242                # The user is unknown from the Quota Storage perspective
243                # Depending on the default policy for this printer, we
244                # either let the job pass through or reject it, but we
245                # log a message in any case.
246                (policy, args) = thefilter.config.getPrinterPolicy(thefilter.printername)
247                if policy == "ALLOW" :
248                    action = "POLICY_ALLOW"
249                elif policy == "EXTERNAL" :   
250                    commandline = thefilter.formatCommandLine(args, user, printer)
251                    thefilter.logger.log_message(_("User %s not registered in the PyKota system, applying external policy (%s) for printer %s") % (thefilter.username, commandline, thefilter.printername), "info")
252                    if os.system(commandline) :
253                        thefilter.logger.log_message(_("External policy %s for printer %s produced an error. Job rejected. Please check PyKota's configuration files.") % (commandline, thefilter.printername), "error")
254                        return thefilter.removeJob()
255                    else :   
256                        # here we try a second time, because the goal
257                        # of the external action was to add the user
258                        # in the database.
259                        continue 
260                else :   
261                    action = "POLICY_DENY"
262                thefilter.logger.log_message(_("User %s not registered in the PyKota system, applying default policy (%s) for printer %s") % (thefilter.username, action, thefilter.printername), "warn")
263                if action == "POLICY_DENY" :
264                    return thefilter.removeJob()
265                # when we get there, the printer policy allows the job to pass
266                break   
267                   
268        # if user exists, do accounting
269        if user.Exists :
270            # Now does the accounting and act depending on the result
271            action = thefilter.accounter.doAccounting(printer, user)
272       
273            # if not allowed to print then die, else proceed.
274            if action == "DENY" :
275                # No, just die cleanly
276                return thefilter.removeJob()
277        elif policy == "EXTERNAL" :               
278            thefilter.logger.log_message(_("External policy %s for printer %s couldn't add user %s. Job rejected.") % (commandline, thefilter.printername, thefilter.username), "error")
279            return thefilter.removeJob()
280       
281    # pass the job untouched to the underlying layer
282    thefilter.accounter.filterInput(thefilter.inputfile)     
283   
284    return thefilter.acceptJob()
285
286if __name__ == "__main__" :   
287    retcode = -1
288    try :
289        # Initializes the current tool
290        kotafilter = PyKotaFilter()   
291        retcode = main(kotafilter)
292    except (PyKotaToolError, PyKotaConfigError, PyKotaStorageError, PyKotaAccounterError, PyKotaRequesterError, AttributeError, KeyError, IndexError, ValueError, TypeError, IOError), msg :
293        sys.stderr.write("ERROR : PyKota filter failed (%s)\n" % msg)
294        sys.stderr.flush()
295        try :
296            retcode = kotafilter.removeJob()
297        except :
298            retcode = -1
299
300    try :
301        kotafilter.storage.close()
302    except (TypeError, NameError, AttributeError) :   
303        pass
304       
305    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.