Code

documentation cleanup
[roundup.git] / roundup / backends / sessions.py
1 #$Id: sessions.py,v 1.7 2004-02-11 23:55:09 richard Exp $
2 """This module defines a very basic store that's used by the CGI interface
3 to store session and one-time-key information.
5 Yes, it's called "sessions" - because originally it only defined a session
6 class. It's now also used for One Time Key handling too.
7 """
8 __docformat__ = 'restructuredtext'
10 import anydbm, whichdb, os, marshal
12 class BasicDatabase:
13     ''' Provide a nice encapsulation of an anydbm store.
15         Keys are id strings, values are automatically marshalled data.
16     '''
17     _db_type = None
19     def __init__(self, config):
20         self.config = config
21         self.dir = config.DATABASE
22         # ensure files are group readable and writable
23         os.umask(0002)
25     def clear(self):
26         path = os.path.join(self.dir, self.name)
27         if os.path.exists(path):
28             os.remove(path)
29         elif os.path.exists(path+'.db'):    # dbm appends .db
30             os.remove(path+'.db')
32     def cache_db_type(self, path):
33         ''' determine which DB wrote the class file, and cache it as an
34             attribute of __class__ (to allow for subclassed DBs to be
35             different sorts)
36         '''
37         db_type = ''
38         if os.path.exists(path):
39             db_type = whichdb.whichdb(path)
40             if not db_type:
41                 raise hyperdb.DatabaseError, "Couldn't identify database type"
42         elif os.path.exists(path+'.db'):
43             # if the path ends in '.db', it's a dbm database, whether
44             # anydbm says it's dbhash or not!
45             db_type = 'dbm'
46         self.__class__._db_type = db_type
48     def get(self, infoid, value):
49         db = self.opendb('c')
50         try:
51             if db.has_key(infoid):
52                 values = marshal.loads(db[infoid])
53             else:
54                 return None
55             return values.get(value, None)
56         finally:
57             db.close()
59     def getall(self, infoid):
60         db = self.opendb('c')
61         try:
62             return marshal.loads(db[infoid])
63         finally:
64             db.close()
66     def set(self, infoid, **newvalues):
67         db = self.opendb('c')
68         try:
69             if db.has_key(infoid):
70                 values = marshal.loads(db[infoid])
71             else:
72                 values = {}
73             values.update(newvalues)
74             db[infoid] = marshal.dumps(values)
75         finally:
76             db.close()
78     def list(self):
79         db = self.opendb('r')
80         try:
81             return db.keys()
82         finally:
83             db.close()
85     def destroy(self, infoid):
86         db = self.opendb('c')
87         try:
88             if db.has_key(infoid):
89                 del db[infoid]
90         finally:
91             db.close()
93     def opendb(self, mode):
94         '''Low-level database opener that gets around anydbm/dbm
95            eccentricities.
96         '''
97         # figure the class db type
98         path = os.path.join(os.getcwd(), self.dir, self.name)
99         if self._db_type is None:
100             self.cache_db_type(path)
102         db_type = self._db_type
104         # new database? let anydbm pick the best dbm
105         if not db_type:
106             return anydbm.open(path, 'c')
108         # open the database with the correct module
109         dbm = __import__(db_type)
110         return dbm.open(path, mode)
112     def commit(self):
113         pass
115 class Sessions(BasicDatabase):
116     name = 'sessions'
118 class OneTimeKeys(BasicDatabase):
119     name = 'otks'