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

Revision 1041, 10.9 kB (checked in by jalet, 21 years ago)

Hey, it may work (edpykota --reset excepted) !

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