Logo Search packages:      
Sourcecode: karrigell version File versions  Download package

k_session.py

00001 """Session management
New in version 2.1 : sessions can be persistent, if the
persistentSession in section [Server] of the configuration file
is set to 1
In this case, session information is stored in a shelve file, indexed
by the sessionId (a unique 8-characters string). In this case, only 
built-in types are accepted as attributes to the session object
"""

import os
import shelve
import cgi
from types import *
import k_utils, k_config

def isBuiltinType(val):
    if type(val) in [StringType,IntType,LongType,FloatType,NoneType,
        TypeType, BooleanType, ComplexType, UnicodeType]:
        return True,None
    elif type(val) in [ListType,TupleType]:
        for item in val:
            if not isBuiltinType(item)[0]:
                return False,isBuiltinType(item)[1]
        return True,None
    elif type(val)==DictType:
        for (k,v) in val.items():
            if not isBuiltinType(k)[0]:
                return False,isBuiltinType(k)[1]
            elif not isBuiltinType(v)[0]:
                return False,isBuiltinType(v)[1]
        return True,None
    elif isinstance(val,SessionElement):
        return True,None
    else:
        return False,type(val)

# structure holding session info
# a dictionary or a shelve file according to the persistentSession option
if k_config.persistentSession:
    sessionFile=os.path.join(k_config.rootDir,"sessions.dat")
    sessionDict=shelve.open(sessionFile,"n",writeback=True)
    sessions=sessionDict.keys()         # list held to avoid overflow
else:
    sessionDict={}
    sessions=[]         # list held to avoid overflow
maxSessions=1000    # maximum number of simultaneous sessions

Errors=k_utils.LimitedDict(100) # used for IO errors in karrigellRequestHandler

00050 class SessionElement(object):
    """A SessionElement object has a sessionId attribute and a close() method 
    which erases the item in sessionDict and creates a Set-Cookie header to 
    erase the corresponding cookie
    When a new SessionElement is created a new item is appended to the sessions 
    list. If this list is bigger than the maximum (stored in the maxSessions 
    global variable) then the first element in the sessions list (that is, the 
    oldest recorded session) is deleted. This should avoid the risk of memory 
    overflow
    
    If the session is persistent, only built-in types are accepted as attributes
    of the session object
    """

    def __init__(self,sessionId):
        global sessions,sessionDict
        self.sessionId=sessionId
        sessions.append(sessionId)
        if len(sessions)>maxSessions:
            removeOldestSession()

00071     def __setattr__(self,name,value):
        """Override setattr so that the session object is only made of built-in types"""
        if k_config.persistentSession:
            isBuiltin,typeVal=isBuiltinType(value)
            if not isBuiltin:
                errMsg="In persistent sessions, the session object "
                errMsg+="can only contain built-in types, not %s" %typeVal
                raise TypeError, errMsg
                
        object.__setattr__(self,name,value)

    def close(self):
        del sessionDict[self.sessionId]

dummy=SessionElement(0)

def removeOldestSession():
    global sessions,sessionDict
    try:
        oldestId=sessions[0]
        oldest=sessionDict[oldestId]
        del sessionDict[oldestId]
        if hasattr(oldest,"_attributes"): 
            for attr in oldest._attributes:
                del sessionDict[oldestId+attr]
    except:
        pass
    sessions=sessions[1:]

def getSessionObject(sessionId):
    try:
        res=sessionDict[sessionId]
        # for persistent session, get attributes
        # this may fail for instances of user-defined classes
        if k_config.persistentSession and hasattr(res,"_attributes"):
            for attr in res._attributes:
                try:
                    setattr(res,attr,sessionDict[sessionId+attr])
                except:
                    pass
    except KeyError:
        res=SessionElement(sessionId)
        sessionDict[sessionId]=res
    return res

def store(sessionId,sessionObject):
    global sessionDict
    if k_config.persistentSession:
        if sessionDict.has_key(sessionId):
            # if session was not closed
            # store basic attributes in the shelve file
            sessionDict[sessionId]=sessionObject
        sessionDict.close()
        sessionDict=shelve.open(sessionFile,"c",writeback=True)

if __name__=="__main__":
    sessionDict=shelve.open("sessions.dat","c",writeback=True)
    for k,v in sessionDict.items():
        print
        print k
        for k in dir(v):
            if not k.startswith("__"):
                print "    %s : %s" %(k,getattr(v,k))
    

Generated by  Doxygen 1.6.0   Back to index