"""Session store using the shelve module."""
import os
import shelve
import threading
from MiscUtils import NoDefault
from SessionStore import maxPickleProtocol, SessionStore
class SessionShelveStore(SessionStore):
"""A session store implemented with a shelve object.
To use this store, set SessionStore in Application.config to 'Shelve'.
"""
_filename = 'Session.Store'
def __init__(self, app, restoreFiles=True, filename=None):
"""Initialize the session shelf.
If restoreFiles is true, existing shelve file(s) will be reused.
"""
SessionStore.__init__(self, app)
filename = os.path.join(app._sessionDir, filename or self._filename)
flag = restoreFiles and 'c' or 'n'
self._store = shelve.open(filename,
flag=flag, protocol=maxPickleProtocol)
self._lock = threading.RLock()
def __len__(self):
"""Return the number of sessions."""
return len(self._store)
def __getitem__(self, key):
"""Get a session item, reading it from the store."""
return self._store[key]
def __setitem__(self, key, value):
"""Set a session item, writing it to the store."""
dirty = value.isDirty()
if self._alwaysSave or dirty:
self._lock.acquire()
try:
if dirty:
value.setDirty(False)
try:
self._store[key] = value
except Exception:
if dirty:
value.setDirty()
raise
finally:
self._lock.release()
def __delitem__(self, key):
"""Delete a session item from the store."""
self._lock.acquire()
try:
session = self[key]
if not session.isExpired():
session.expiring()
del self._store[key]
finally:
self._lock.release()
def __contains__(self, key):
"""Check whether the session store has a given key."""
return key in self._store
def __iter__(self):
"""Return an iterator over the stored session keys."""
return iter(self._store)
def keys(self):
"""Return a list with the keys of all the stored sessions."""
return self._store.keys()
def clear(self):
"""Clear the session store, removing all of its items."""
self._store.clear()
def setdefault(self, key, default=None):
"""Return value if key available, else default (also setting it)."""
self._lock.acquire()
try:
return self._store.setdefault(key, default)
finally:
self._lock.release()
def pop(self, key, default=NoDefault):
"""Return value if key available, else default (also remove key)."""
self._lock.acquire()
try:
if default is NoDefault:
return self._store.pop(key)
else:
return self._store.pop(key, default)
finally:
self._lock.release()
def storeSession(self, session):
"""Save potentially changed session in the store."""
key = session.identifier()
if key not in self or self[key] is not session:
self[key] = session
def storeAllSessions(self):
"""Permanently save all sessions in the store.
Should be used (only) when the application server is shut down.
"""
self._store.close()
def cleanStaleSessions(self, task=None):
"""Clean stale sessions."""
SessionStore.cleanStaleSessions(self, task)
self.intervalSweep()
def intervalSweep(self):
"""The session sweeper interval function."""
self._store.sync()