root / pykota / trunk / bin / pykota @ 825

Revision 825, 6.0 kB (checked in by jalet, 21 years ago)

Correctly maps PyKota's log levels to syslog log levels

  • 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
3# PyKota accounting filter
4#
5# PyKota - Print Quotas for CUPS
6#
7# (c) 2003 Jerome Alet <alet@librelogiciel.com>
8# You're welcome to redistribute this software under the
9# terms of the GNU General Public Licence version 2.0
10# or, at your option, any higher version.
11#
12# You can read the complete GNU GPL in the file COPYING
13# which should come along with this software, or visit
14# the Free Software Foundation's WEB site http://www.fsf.org
15#
16# $Id$
17#
18# $Log$
19# Revision 1.12  2003/02/27 23:48:41  jalet
20# Correctly maps PyKota's log levels to syslog log levels
21#
22# Revision 1.11  2003/02/27 22:55:20  jalet
23# WARN log priority doesn't exist.
24#
25# Revision 1.10  2003/02/27 22:43:21  jalet
26# Missing import
27#
28# Revision 1.9  2003/02/27 22:40:26  jalet
29# Correctly handles cases where the printer is off.
30#
31# Revision 1.8  2003/02/09 12:56:53  jalet
32# Internationalization begins...
33#
34# Revision 1.7  2003/02/07 10:23:48  jalet
35# Avoid a possible future name clash
36#
37# Revision 1.6  2003/02/06 22:54:33  jalet
38# warnpykota should be ok
39#
40# Revision 1.5  2003/02/05 22:45:25  jalet
41# Forgotten import
42#
43# Revision 1.4  2003/02/05 22:42:51  jalet
44# Typo
45#
46# Revision 1.3  2003/02/05 22:38:39  jalet
47# Typo
48#
49# Revision 1.2  2003/02/05 22:16:20  jalet
50# DEVICE_URI is undefined outside of CUPS, i.e. for normal command line tools
51#
52# Revision 1.1  2003/02/05 21:28:17  jalet
53# Initial import into CVS
54#
55#
56#
57
58import sys
59import os
60
61from pykota.tool import PyKotaTool, PyKotaToolError
62from pykota.requester import openRequester, PyKotaRequesterError
63
64class PyKotaFilter(PyKotaTool) :   
65    """Class for the PyKota filter."""
66    def __init__(self, username) :
67        PyKotaTool.__init__(self, isfilter=1)
68        self.username = username
69        self.requester = openRequester(self.config, self.printername)
70        self.printerhostname = self.getPrinterHostname()
71   
72    def getPrinterHostname(self) :
73        """Returns the printer hostname."""
74        device_uri = os.environ.get("DEVICE_URI", "")
75        # TODO : check this for more complex urls than ipp://myprinter.dot.com:631/printers/lp
76        try :
77            (backend, destination) = device_uri.split(":", 1) 
78        except ValueError :   
79            raise PyKotaToolError, "Invalid DEVICE_URI : %s\n" % device_uri
80        while destination.startswith("/") :
81            destination = destination[1:]
82        return destination.split("/")[0].split(":")[0]
83       
84    def filterInput(self, inputfile) :
85        """Transparent filter."""
86        mustclose = 0   
87        if inputfile is not None :   
88            infile = open(inputfile, "rb")
89            mustclose = 1
90        else :   
91            infile = sys.stdin
92        data = infile.read(256*1024)   
93        while data :
94            sys.stdout.write(data)
95            data = infile.read(256*1024)
96        if mustclose :   
97            infile.close()
98           
99def main() :   
100    """Do it, and do it right !"""
101    #
102    # This is a CUPS filter, so we should act and die like a CUPS filter when needed
103    narg = len(sys.argv)
104    if narg not in (6, 7) :   
105        sys.stderr.write("ERROR: %s job-id user title copies options [file]\n" % sys.argv[0])
106        return 1
107    elif narg == 7 :   
108        # input file
109        inputfile = sys.argv[6]
110    else :   
111        # stdin
112        inputfile = None
113       
114    #   
115    # According to CUPS documentation, the username is the third command line argument
116    username = sys.argv[2].strip()   
117   
118    # Initializes the current tool
119    kotafilter = PyKotaFilter(username)   
120   
121    # Get the page counter directly from the printer itself
122    try :
123        counterbeforejob = kotafilter.requester.getPrinterPageCounter(kotafilter.printerhostname) # TODO use printername instead, make them match from CUPS' config files
124    except PyKotaRequesterError, msg :
125        # can't get actual page counter, assume printer is off, but warns in log
126        kotafilter.logger.log_message(msg, "warn")
127        printerIsOff = 1
128    else :   
129        printerIsOff = 0
130       
131    # Get the last page counter and last username from the Quota Storage backend
132    pgc = kotafilter.storage.getPrinterPageCounter(kotafilter.printername)   
133    if pgc is None :
134        # The printer is unknown from the Quota Storage perspective
135        # we let the job pass through, but log a warning message
136        kotafilter.logger.log_message(_("Printer %s not registered in the PyKota system") % kotafilter.printername)
137    else :   
138        # get last values from Quota Storage
139        (lastpagecounter, lastusername) = (pgc["pagecounter"], pgc["lastusername"])
140       
141        # if printer is off then we assume the correct counter value is the last one
142        if printerIsOff :
143            counterbeforejob = lastpagecounter
144           
145        # Update the last page counter and last username in the Quota Storage backend
146        # set them to current user and
147        kotafilter.storage.updatePrinterPageCounter(kotafilter.printername, username, counterbeforejob) # TODO : allow or deny users not in quota system, and die cleanly if needed
148       
149        # Is the current user allowed to print at all ?
150        action = kotafilter.warnUserPQuota(username)
151        if action == "DENY" :
152            # No, just die cleanly
153            return 1
154           
155        # Yes     
156        if (lastpagecounter is None) or (lastusername is None) :
157            lastusername = username
158            lastpagecounter = counterbeforejob
159        jobsize = (counterbeforejob - lastpagecounter)   
160        if jobsize >= 0:
161            kotafilter.storage.updateUserPQuota(lastusername, kotafilter.printername, jobsize)
162            kotafilter.warnUserPQuota(lastusername)
163        else :   
164            kotafilter.logger.log_message(_("Error in page count value %i for user %s on printer %s") % (jobsize, kotafilter.printername, lastusername), "error")
165       
166    # pass the job untouched to the underlying layer
167    kotafilter.filterInput(inputfile)     
168   
169    return 0
170
171if __name__ == "__main__" :   
172    sys.exit(main() or 0)
Note: See TracBrowser for help on using the browser.