In configure we do not need to set_config()
[cascardo/ipsilon.git] / ipsilon / util / sessions.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2014  Ipsilon project Contributors, for licensee see COPYING
4
5 import base64
6 from cherrypy.lib.sessions import Session
7 from ipsilon.util.data import SqlStore, SqlQuery
8 import threading
9 try:
10     import cPickle as pickle
11 except ImportError:
12     import pickle
13
14
15 SESSION_COLUMNS = ['id', 'data', 'expiration_time']
16
17
18 class SqlSession(Session):
19
20     dburi = None
21     _db = None
22     _proto = 2
23     locks = {}
24
25     @classmethod
26     def setup(cls, **kwargs):
27         """Initialization from cherrypy"""
28
29         for k, v in kwargs.items():
30             if k == 'storage_dburi':
31                 cls.dburi = v
32
33         cls._db = SqlStore(cls.dburi)
34
35     def _exists(self):
36         q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
37         result = q.select({'id': self.id})
38         return True if result.fetchone() else False
39
40     def _load(self):
41         q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
42         result = q.select({'id': self.id})
43         r = result.fetchone()
44         if r:
45             data = str(base64.b64decode(r[1]))
46             return pickle.loads(data)
47
48     def _save(self, expiration_time):
49         q = None
50         try:
51             q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS, trans=True)
52             q.delete({'id': self.id})
53             data = pickle.dumps((self._data, expiration_time), self._proto)
54             q.insert((self.id, base64.b64encode(data), expiration_time))
55             q.commit()
56         except Exception:  # pylint: disable=broad-except
57             if q:
58                 q.rollback()
59             raise
60
61     def _delete(self):
62         q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
63         q.delete({'id': self.id})
64
65     # copy what RamSession does for now
66     def acquire_lock(self):
67         """Acquire an exclusive lock on the currently-loaded session data."""
68         self.locked = True
69         self.locks.setdefault(self.id, threading.RLock()).acquire()
70
71     def release_lock(self):
72         """Release the lock on the currently-loaded session data."""
73         self.locks[self.id].release()
74         self.locked = False