Code

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