root / pykota / trunk / pykota / storages / sql.py @ 887

Revision 887, 10.3 kB (checked in by jalet, 21 years ago)

The last job Id is saved now for each printer, this will probably
allow other accounting methods in the future.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# PyKota
2#
3# PyKota : Print Quotas for CUPS
4#
5# (c) 2003 Jerome Alet <alet@librelogiciel.com>
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19#
20# $Id$
21#
22# $Log$
23# Revision 1.21  2003/04/08 20:38:08  jalet
24# The last job Id is saved now for each printer, this will probably
25# allow other accounting methods in the future.
26#
27# Revision 1.20  2003/03/29 13:45:27  jalet
28# GPL paragraphs were incorrectly (from memory) copied into the sources.
29# Two README files were added.
30# Upgrade script for PostgreSQL pre 1.01 schema was added.
31#
32# Revision 1.19  2003/02/27 08:41:49  jalet
33# DATETIME is not supported anymore in PostgreSQL 7.3 it seems, but
34# TIMESTAMP is.
35#
36# Revision 1.18  2003/02/10 12:07:31  jalet
37# Now repykota should output the recorded total page number for each printer too.
38#
39# Revision 1.17  2003/02/10 08:41:36  jalet
40# edpykota's --reset command line option resets the limit date too.
41#
42# Revision 1.16  2003/02/08 22:39:46  jalet
43# --reset command line option added
44#
45# Revision 1.15  2003/02/08 22:12:09  jalet
46# Life time counter for users and groups added.
47#
48# Revision 1.14  2003/02/07 22:13:13  jalet
49# Perhaps edpykota is now able to add printers !!! Oh, stupid me !
50#
51# Revision 1.13  2003/02/07 00:08:52  jalet
52# Typos
53#
54# Revision 1.12  2003/02/06 23:20:03  jalet
55# warnpykota doesn't need any user/group name argument, mimicing the
56# warnquota disk quota tool.
57#
58# Revision 1.11  2003/02/06 15:05:13  jalet
59# self was forgotten
60#
61# Revision 1.10  2003/02/06 15:03:11  jalet
62# added a method to set the limit date
63#
64# Revision 1.9  2003/02/06 14:52:35  jalet
65# Forgotten import
66#
67# Revision 1.8  2003/02/06 14:49:04  jalet
68# edpykota should be ok now
69#
70# Revision 1.7  2003/02/06 14:28:59  jalet
71# edpykota should be ok, minus some typos
72#
73# Revision 1.6  2003/02/06 09:19:02  jalet
74# More robust behavior (hopefully) when the user or printer is not managed
75# correctly by the Quota System : e.g. cupsFilter added in ppd file, but
76# printer and/or user not 'yet?' in storage.
77#
78# Revision 1.5  2003/02/05 23:26:22  jalet
79# Incorrect handling of grace delay
80#
81# Revision 1.4  2003/02/05 23:02:10  jalet
82# Typo
83#
84# Revision 1.3  2003/02/05 23:00:12  jalet
85# Forgotten import
86# Bad datetime conversion
87#
88# Revision 1.2  2003/02/05 22:28:38  jalet
89# More robust storage
90#
91# Revision 1.1  2003/02/05 21:28:17  jalet
92# Initial import into CVS
93#
94#
95#
96
97import fnmatch
98
99class SQLStorage :   
100    def getMatchingPrinters(self, printerpattern) :
101        """Returns the list of all printers tuples (name, pagecounter) which match a certain pattern for the printer name."""
102        printerslist = []
103        # We 'could' do a SELECT printername FROM printers WHERE printername LIKE ...
104        # but we don't because other storages semantics may be different, so every
105        # storage should use fnmatch to match patterns and be storage agnostic
106        result = self.doQuery("SELECT printername, pagecounter FROM printers;")
107        result = self.doParseResult(result)
108        if result is not None :
109            for printer in result :
110                if fnmatch.fnmatchcase(printer["printername"], printerpattern) :
111                    printerslist.append((printer["printername"], printer["pagecounter"]))
112        return printerslist       
113           
114    def addPrinter(self, printername) :       
115        """Adds a printer to the quota storage."""
116        self.doQuery("INSERT INTO printers (printername) VALUES (%s);" % self.doQuote(printername))
117       
118    def getPrinterUsers(self, printername) :       
119        """Returns the list of usernames which uses a given printer."""
120        result = self.doQuery("SELECT DISTINCT username FROM users WHERE id IN (SELECT userid FROM userpquota WHERE printerid IN (SELECT printerid FROM printers WHERE printername=%s)) ORDER BY username;" % self.doQuote(printername))
121        result = self.doParseResult(result)
122        if result is None :
123            return []
124        else :   
125            return [record["username"] for record in result]
126       
127    def getPrinterGroups(self, printername) :       
128        """Returns the list of groups which uses a given printer."""
129        result = self.doQuery("SELECT DISTINCT groupname FROM groups WHERE id IN (SELECT groupid FROM grouppquota WHERE printerid IN (SELECT printerid FROM printers WHERE printername=%s));" % self.doQuote(printername))
130        result = self.doParseResult(result)
131        if result is None :
132            return []
133        else :   
134            return [record["groupname"] for record in result]
135       
136    def getUserId(self, username) :
137        """Returns a userid given a username."""
138        result = self.doQuery("SELECT id FROM users WHERE username=%s;" % self.doQuote(username))
139        try :
140            return self.doParseResult(result)[0]["id"]
141        except TypeError :      # Not found
142            return
143           
144    def getPrinterId(self, printername) :       
145        """Returns a printerid given a printername."""
146        result = self.doQuery("SELECT id FROM printers WHERE printername=%s;" % self.doQuote(printername))
147        try :
148            return self.doParseResult(result)[0]["id"]
149        except TypeError :      # Not found   
150            return
151           
152    def getPrinterPageCounter(self, printername) :
153        """Returns the last page counter value for a printer given its name."""
154        result = self.doQuery("SELECT pagecounter, lastjobid, lastusername FROM printers WHERE printername=%s;" % self.doQuote(printername))
155        try :
156            return self.doParseResult(result)[0]
157        except TypeError :      # Not found
158            return
159       
160    def updatePrinterPageCounter(self, printername, username, pagecount, jobid) :
161        """Updates the last page counter information for a printer given its name, last username, pagecount and jobid."""
162        return self.doQuery("UPDATE printers SET pagecounter=%s, lastusername=%s, lastjobid=%s WHERE printername=%s;" % (self.doQuote(pagecount), self.doQuote(username), self.doQuote(jobid), self.doQuote(printername)))
163       
164    def addUserPQuota(self, username, printername) :
165        """Initializes a user print quota on a printer, adds the printer and the user to the quota storage if needed."""
166        (userid, printerid) = self.getUPIds(username, printername)
167        if printerid is None :   
168            self.addPrinter(printername)        # should we still add it ?
169        if userid is None :   
170            self.doQuery("INSERT INTO users (username) VALUES (%s);" % self.doQuote(username))
171        (userid, printerid) = self.getUPIds(username, printername)
172        if (userid is not None) and (printerid is not None) :
173            return self.doQuery("INSERT INTO userpquota (userid, printerid) VALUES (%s, %s);" % (self.doQuote(userid), self.doQuote(printerid)))
174       
175    def getUPIds(self, username, printername) :   
176        """Returns a tuple (userid, printerid) given a username and a printername."""
177        return (self.getUserId(username), self.getPrinterId(printername))
178       
179    def getUserPQuota(self, username, printername) :
180        """Returns the Print Quota information for a given (username, printername)."""
181        (userid, printerid) = self.getUPIds(username, printername)
182        if (userid is not None) and (printerid is not None) :
183            result = self.doQuery("SELECT lifepagecounter, pagecounter, softlimit, hardlimit, datelimit FROM userpquota WHERE userid=%s AND printerid=%s;" % (self.doQuote(userid), self.doQuote(printerid)))
184            try :
185                return self.doParseResult(result)[0]
186            except TypeError :      # Not found   
187                pass
188       
189    def setUserPQuota(self, username, printername, softlimit, hardlimit) :
190        """Sets soft and hard limits for a user quota on a specific printer given (username, printername)."""
191        (userid, printerid) = self.getUPIds(username, printername)
192        if (userid is not None) and (printerid is not None) :
193            self.doQuery("UPDATE userpquota SET softlimit=%s, hardlimit=%s, datelimit=NULL WHERE userid=%s AND printerid=%s;" % (self.doQuote(softlimit), self.doQuote(hardlimit), self.doQuote(userid), self.doQuote(printerid)))
194       
195    def resetUserPQuota(self, username, printername) :   
196        """Resets the page counter to zero. Life time page counter is kept unchanged."""
197        (userid, printerid) = self.getUPIds(username, printername)
198        if (userid is not None) and (printerid is not None) :
199            self.doQuery("UPDATE userpquota SET pagecounter=0, datelimit=NULL WHERE userid=%s AND printerid=%s;" % (self.doQuote(userid), self.doQuote(printerid)))
200       
201    def setDateLimit(self, username, printername, datelimit) :
202        """Sets the limit date for a soft limit to become an hard one given (username, printername)."""
203        (userid, printerid) = self.getUPIds(username, printername)
204        if (userid is not None) and (printerid is not None) :
205            self.doQuery("UPDATE userpquota SET datelimit=%s::TIMESTAMP WHERE userid=%s AND printerid=%s;" % (self.doQuote("%04i-%02i-%02i %02i:%02i:%02i" % (datelimit.year, datelimit.month, datelimit.day, datelimit.hour, datelimit.minute, datelimit.second)), self.doQuote(userid), self.doQuote(printerid)))
206       
207    def updateUserPQuota(self, username, printername, pagecount) :
208        """Updates the used user Quota information given (username, printername) and a job size in pages."""
209        (userid, printerid) = self.getUPIds(username, printername)
210        if (userid is not None) and (printerid is not None) :
211            self.doQuery("UPDATE userpquota SET lifepagecounter=lifepagecounter+(%s), pagecounter=pagecounter+(%s) WHERE userid=%s AND printerid=%s;" % (self.doQuote(pagecount), self.doQuote(pagecount), self.doQuote(userid), self.doQuote(printerid)))
212       
Note: See TracBrowser for help on using the browser.