zvoase (owner)

Forks

Revisions

gist: 30356 Download_button fork
public
Public Clone URL: git://gist.github.com/30356.git
Embed All Files: show embed
couchdb_session.py #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
try:
    import cPickle as pickle
except ImportError:
    import pickle
 
from couchdb import client
from django.conf import settings
from django.contrib.sessions.backends.base import SessionBase
 
class SessionStore(SessionBase):
    
    """A CouchDB-based session store."""
    
    def __init__(self, session_key=None):
        # This implies two new settings; COUCHDB_URI and COUCHDB_SESSION_DB.
        # The first is mandatory, the second optional.
        self.server = client.Server(getattr(settings, 'COUCHDB_URI'))
        self.database = self.server[getattr(settings, 'COUCHDB_SESSION_DB',
            'django_sessions')]
        self._doc_cache = {}
        super(SessionStore, self).__init__(session_key)
    
    def load(self):
        # If we already have a cached version, then check that it's the right
        # revision (to avoid conflicts).
        if self._doc_cache:
            cache_rev = self._doc_cache.rev
            doc_rev = self._get_server_rev()
            # In the case that it's the correct version, unpickle the data and
            # return it.
            if cache_rev >= doc_rev:
                session_data = {}
                for key, value in self._doc_cache.items():
                    if key in ['_rev', '_id']:
                        continue
                    session_data[key] = pickle.loads(value)
                return session_data
        # Otherwise, if we have an older version, update the current version
        # and run this method again.
        elif self.session_key:
            self._doc_cache = self.database[self.session_key]
            return self.load()
        # If all else fails, make a new session.
        else:
            self.create()
            self._doc_cache = {}
            return self.load()
    
    def create(self):
        # The unique session key is automatically generated by the database.
        self.session_key = self.database.create({})
        self.save()
    
    def save(self):
        session_data = self._get_session(no_load=False)
        doc_data = {}
        for key, value in session_data.items():
            if key in ['_rev', '_id']:
                continue
            doc_data[key] = pickle.dumps(value)
        self.database[self.session_key] = doc_data
    
    def exists(self, session_key):
        return session_key in self.database
    
    def delete(self, session_key=None):
        if not session_key and not self.session_key:
            return
        session_key = session_key or self.session_key
        self.database.delete(self.database[session_key])
    
    def _get_server_rev(self):
        map_fun = '''
function (doc) {
emit(doc._rev, null);
}'''
        return list(db.query(map_fun, key=self.session_key))[0].value