root / pykota / trunk / pykota / storage.py @ 1043

Revision 1043, 11.2 kB (checked in by jalet, 21 years ago)

Should be ready for testing :-)

  • 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 and LPRng
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.16  2003/06/25 19:52:31  jalet
24# Should be ready for testing :-)
25#
26# Revision 1.15  2003/06/25 14:10:58  jalet
27# Exception raising for now.
28#
29# Revision 1.14  2003/06/25 14:10:01  jalet
30# Hey, it may work (edpykota --reset excepted) !
31#
32# Revision 1.13  2003/06/10 16:37:54  jalet
33# Deletion of the second user which is not needed anymore.
34# Added a debug configuration field in /etc/pykota.conf
35# All queries can now be sent to the logger in debug mode, this will
36# greatly help improve performance when time for this will come.
37#
38# Revision 1.12  2003/04/23 22:13:57  jalet
39# Preliminary support for LPRng added BUT STILL UNTESTED.
40#
41# Revision 1.11  2003/04/10 21:47:20  jalet
42# Job history added. Upgrade script neutralized for now !
43#
44# Revision 1.10  2003/03/29 13:45:27  jalet
45# GPL paragraphs were incorrectly (from memory) copied into the sources.
46# Two README files were added.
47# Upgrade script for PostgreSQL pre 1.01 schema was added.
48#
49# Revision 1.9  2003/02/17 22:55:01  jalet
50# More options can now be set per printer or globally :
51#
52#       admin
53#       adminmail
54#       gracedelay
55#       requester
56#
57# the printer option has priority when both are defined.
58#
59# Revision 1.8  2003/02/17 22:05:50  jalet
60# Storage backend now supports admin and user passwords (untested)
61#
62# Revision 1.7  2003/02/10 12:07:31  jalet
63# Now repykota should output the recorded total page number for each printer too.
64#
65# Revision 1.6  2003/02/09 13:05:43  jalet
66# Internationalization continues...
67#
68# Revision 1.5  2003/02/08 22:39:46  jalet
69# --reset command line option added
70#
71# Revision 1.4  2003/02/08 09:59:59  jalet
72# Added preliminary base class for all storages
73#
74# Revision 1.3  2003/02/05 22:10:29  jalet
75# Typos
76#
77# Revision 1.2  2003/02/05 22:02:22  jalet
78# __import__ statement didn't work as expected
79#
80# Revision 1.1  2003/02/05 21:28:17  jalet
81# Initial import into CVS
82#
83#
84#
85
86class PyKotaStorageError(Exception):
87    """An exception for Quota Storage related stuff."""
88    def __init__(self, message = ""):
89        self.message = message
90        Exception.__init__(self, message)
91    def __repr__(self):
92        return self.message
93    __str__ = __repr__
94       
95class StorageObject :
96    """Object present in the Quota Storage."""
97    def __init__(self, parent) :
98        "Initialize minimal data."""
99        self.parent = parent
100        self.ident = None
101        self.Exists = 0
102       
103class StorageUser(StorageObject) :       
104    """User class."""
105    def __init__(self, parent, name) :
106        StorageObject.__init__(self, parent)
107        self.Name = name
108        self.LimitBy = None
109        self.AccountBalance = None
110        self.LifeTimePaid = None
111       
112    def consumeAccountBalance(self, amount) :     
113        """Consumes an amount of money from the user's account balance."""
114        newbalance = float(self.AccountBalance or 0.0) - amount
115        self.parent.writeUserAccountBalance(self, newbalance)
116        self.AccountBalance = newbalance
117       
118    def setAccountBalance(self, balance, lifetimepaid) :   
119        """Sets the user's account balance in case he pays more money."""
120        self.parent.writeUserAccountBalance(self, balance, lifetimepaid)
121        self.AccountBalance = balance
122        self.LifeTimePaid = lifetimepaid
123       
124    def setLimitBy(self, limitby) :   
125        """Sets the user's limiting factor."""
126        limitby = limitby.lower()
127        if limitby in ["quota", "balance"] :
128            self.parent.writeUserLimitBy(self, limitby)
129            self.LimitBy = limitby
130       
131    def delete(self) :   
132        """Deletes an user from the Quota Storage."""
133        self.parent.beginTransaction()
134        try :
135            self.parent.deleteUser(self)
136        except PyKotaStorageError, msg :   
137            self.parent.rollbackTransaction()
138            raise PyKotaStorageError, msg
139        else :   
140            self.parent.commitTransaction()
141       
142class StorageGroup(StorageObject) :       
143    """User class."""
144    def __init__(self, parent, name) :
145        StorageObject.__init__(self, parent)
146        self.Name = name
147        self.LimitBy = None
148        self.AccountBalance = None
149        self.LifeTimePaid = None
150       
151    def setLimitBy(self, limitby) :   
152        """Sets the user's limiting factor."""
153        limitby = limitby.lower()
154        if limitby in ["quota", "balance"] :
155            self.parent.writeGroupLimitBy(self, limitby)
156            self.LimitBy = limitby
157       
158    def delete(self) :   
159        """Deletes a group from the Quota Storage."""
160        self.parent.beginTransaction()
161        try :
162            self.parent.deleteGroup(self)
163        except PyKotaStorageError, msg :   
164            self.parent.rollbackTransaction()
165            raise PyKotaStorageError, msg
166        else :   
167            self.parent.commitTransaction()
168       
169class StoragePrinter(StorageObject) :
170    """Printer class."""
171    def __init__(self, parent, name) :
172        StorageObject.__init__(self, parent)
173        self.Name = name
174        self.PricePerPage = None
175        self.PricePerJob = None
176        self.LastJob = None
177       
178    def addJobToHistory(self, jobid, user, pagecounter, action, jobsize=None) :   
179        """Adds a job to the printer's history."""
180        self.parent.writeJobNew(self, user, jobid, pagecounter, action, jobsize)
181        # TODO : update LastJob object ? Probably not needed.
182       
183    def setPrices(self, priceperpage = None, priceperjob = None) :   
184        """Sets the printer's prices."""
185        if priceperpage is None :
186            priceperpage = self.PricePerPage
187        else :   
188            self.PricePerPage = float(priceperpage)
189        if priceperjob is None :   
190            priceperjob = self.PricePerJob
191        else :   
192            self.PricePerJob = float(priceperjob)
193        self.parent.writePrinterPrices(self)
194       
195class StorageUserPQuota(StorageObject) :
196    """User Print Quota class."""
197    def __init__(self, parent, user, printer) :
198        StorageObject.__init__(self, parent)
199        self.User = user
200        self.Printer = printer
201        self.PageCounter = None
202        self.LifePageCounter = None
203        self.SoftLimit = None
204        self.HardLimit = None
205        self.DateLimit = None
206       
207    def setDateLimit(self, datelimit) :   
208        """Sets the date limit for this quota."""
209        date = "%04i-%02i-%02i %02i:%02i:%02i" % (datelimit.year, datelimit.month, datelimit.day, datelimit.hour, datelimit.minute, datelimit.second)
210        self.parent.writeUserPQuotaDateLimit(self, date)
211        self.DateLimit = date
212       
213    def setLimits(self, softlimit, hardlimit) :   
214        """Sets the soft and hard limit for this quota."""
215        self.parent.writeUserPQuotaLimits(self, softlimit, hardlimit)
216        self.SoftLimit = softlimit
217        self.HardLimit = hardlimit
218       
219    def reset(self) :   
220        """Resets page counter to 0."""
221        self.parent.writeUserPQuotaPagesCounters(self, 0, int(self.LifePageCounter or 0))
222        self.PageCounter = 0
223       
224    def increasePagesUsage(self, nbpages) :
225        """Increase the value of used pages and money."""
226        if nbpages :
227            jobprice = (float(self.Printer.PricePerPage or 0.0) * nbpages) + float(self.Printer.PricePerJob or 0.0)
228            newpagecounter = int(self.PageCounter or 0) + nbpages
229            newlifepagecounter = int(self.LifePageCounter or 0) + nbpages
230            self.parent.beginTransaction()
231            try :
232                if jobprice : # optimization : don't access the database if unneeded.
233                    self.User.consumeAccountBalance(jobprice)
234                self.parent.writeUserPQuotaPagesCounters(self, newpagecounter, newlifepagecounter)
235            except PyKotaStorageError, msg :   
236                self.parent.rollbackTransaction()
237                raise PyKotaStorageError, msg
238            else :   
239                self.parent.commitTransaction()
240                self.PageCounter = newpagecounter
241                self.LifePageCounter = newlifepagecounter
242       
243class StorageGroupPQuota(StorageObject) :
244    """Group Print Quota class."""
245    def __init__(self, parent, group, printer) :
246        StorageObject.__init__(self, parent)
247        self.Group = group
248        self.Printer = printer
249        self.PageCounter = None
250        self.LifePageCounter = None
251        self.SoftLimit = None
252        self.HardLimit = None
253        self.DateLimit = None
254       
255    def setDateLimit(self, datelimit) :   
256        """Sets the date limit for this quota."""
257        date = "%04i-%02i-%02i %02i:%02i:%02i" % (datelimit.year, datelimit.month, datelimit.day, datelimit.hour, datelimit.minute, datelimit.second)
258        self.parent.writeGroupPQuotaDateLimit(self, date)
259        self.DateLimit = date
260       
261    def setLimits(self, softlimit, hardlimit) :   
262        """Sets the soft and hard limit for this quota."""
263        self.parent.writeGroupPQuotaLimits(self, softlimit, hardlimit)
264        self.SoftLimit = softlimit
265        self.HardLimit = hardlimit
266       
267class StorageLastJob(StorageObject) :
268    """Printer's Last Job class."""
269    def __init__(self, parent, printer) :
270        StorageObject.__init__(self, parent)
271        self.Printer = printer
272        self.JobId = None
273        self.User = None
274        self.PrinterPageCounter = None
275        self.JobSize = None
276        self.JobAction = None
277        self.JobDate = None
278       
279    def setSize(self, jobsize) :
280        """Sets the last job's size."""
281        self.parent.writeLastJobSize(self, jobsize)
282        self.JobSize = jobsize
283   
284def openConnection(pykotatool) :
285    """Returns a connection handle to the appropriate Quota Storage Database."""
286    backendinfo = pykotatool.config.getStorageBackend()
287    backend = backendinfo["storagebackend"]
288    try :
289        if not backend.isalpha() :
290            # don't trust user input
291            raise ImportError
292        #   
293        # TODO : descending compatibility
294        #
295        if backend == "postgresql" :
296            backend = "pgstorage"       # TODO : delete, this is for descending compatibility only
297        exec "from pykota.storages import %s as storagebackend" % backend.lower()   
298    except ImportError :
299        raise PyKotaStorageError, _("Unsupported quota storage backend %s") % backend
300    else :   
301        host = backendinfo["storageserver"]
302        database = backendinfo["storagename"]
303        admin = backendinfo["storageadmin"]
304        adminpw = backendinfo["storageadminpw"]
305        return getattr(storagebackend, "Storage")(pykotatool, host, database, admin, adminpw)
Note: See TracBrowser for help on using the browser.