Code

applied patch 688595
[roundup.git] / roundup / backends / sessions.py
1 #$Id: sessions.py,v 1.4 2003-02-25 10:19:32 richard 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     def __init__(self, config):
19         self.config = config
20         self.dir = config.DATABASE
21         # ensure files are group readable and writable
22         os.umask(0002)
24     def clear(self):
25         path = os.path.join(self.dir, self.name)
26         if os.path.exists(path):
27             os.remove(path)
28         elif os.path.exists(path+'.db'):    # dbm appends .db
29             os.remove(path+'.db')
31     def determine_db_type(self, path):
32         ''' determine which DB wrote the class file
33         '''
34         db_type = ''
35         if os.path.exists(path):
36             db_type = whichdb.whichdb(path)
37             if not db_type:
38                 raise hyperdb.DatabaseError, "Couldn't identify database type"
39         elif os.path.exists(path+'.db'):
40             # if the path ends in '.db', it's a dbm database, whether
41             # anydbm says it's dbhash or not!
42             db_type = 'dbm'
43         return db_type
45     def get(self, infoid, value):
46         db = self.opendb('c')
47         try:
48             if db.has_key(infoid):
49                 values = marshal.loads(db[infoid])
50             else:
51                 return None
52             return values.get(value, None)
53         finally:
54             db.close()
56     def getall(self, infoid):
57         db = self.opendb('c')
58         try:
59             return marshal.loads(db[infoid])
60         finally:
61             db.close()
63     def set(self, infoid, **newvalues):
64         db = self.opendb('c')
65         try:
66             if db.has_key(infoid):
67                 values = marshal.loads(db[infoid])
68             else:
69                 values = {}
70             values.update(newvalues)
71             db[infoid] = marshal.dumps(values)
72         finally:
73             db.close()
75     def list(self):
76         db = self.opendb('r')
77         try:
78             return db.keys()
79         finally:
80             db.close()
82     def destroy(self, infoid):
83         db = self.opendb('c')
84         try:
85             if db.has_key(infoid):
86                 del db[infoid]
87         finally:
88             db.close()
90     def opendb(self, mode):
91         '''Low-level database opener that gets around anydbm/dbm
92            eccentricities.
93         '''
94         # figure the class db type
95         path = os.path.join(os.getcwd(), self.dir, self.name)
96         db_type = self.determine_db_type(path)
98         # new database? let anydbm pick the best dbm
99         if not db_type:
100             return anydbm.open(path, 'c')
102         # open the database with the correct module
103         dbm = __import__(db_type)
104         return dbm.open(path, mode)
106     def commit(self):
107         pass
109 class Sessions(BasicDatabase):
110     name = 'sessions'
112 class OneTimeKeys(BasicDatabase):
113     name = 'otks'