1 import threading, time, pickle, random, os
4 __all__ = ["db", "get"]
9 ret += "%02X" % (ord(byte),)
14 for i in xrange(length):
15 nonce += chr(random.randint(0, 255))
18 class session(object):
19 def __init__(self, expire = 86400 * 7):
20 self.id = hexencode(gennonce(16))
22 self.lock = threading.Lock()
23 self.ctime = self.atime = self.mtime = int(time.time())
39 def __getitem__(self, key):
42 def get(self, key, default = None):
43 return self.dict.get(key, default)
45 def __setitem__(self, key, value):
46 self.dict[key] = value
47 if hasattr(value, "sessdirty"):
52 def __delitem__(self, key):
53 old = self.dict.pop(key)
58 def __contains__(self, key):
59 return key in self.dict
61 def __getstate__(self):
63 for k, v in self.__dict__.items():
64 if k == "lock": continue
68 def __setstate__(self, st):
71 self.lock = threading.Lock()
74 def __init__(self, cookiename = "wrwsess", path = "/"):
76 self.cookiename = cookiename
78 self.lock = threading.Lock()
80 self.freezetime = 3600
83 now = int(time.time())
86 for sess in self.live.itervalues():
87 if sess.atime + self.freezetime < now:
92 if sess.atime + sess.expire < now:
97 del self.live[sess.id]
104 if len(self.live) == 0:
110 def fetch(self, req):
111 now = int(time.time())
112 sessid = cookie.get(req, self.cookiename)
114 if self.cthread is None:
115 self.cthread = threading.Thread(target = self.cleanloop)
116 self.cthread.setDaemon(True)
121 elif sessid in self.live:
122 sess = self.live[sessid]
124 sess = self.thaw(sessid)
125 self.live[sessid] = sess
126 if sess.atime + sess.expire < now:
131 self.live[sess.id] = sess
132 req.oncommit(self.addcookie)
133 req.oncommit(self.ckfreeze)
136 def addcookie(self, req):
137 sess = req.item(self.fetch)
138 cookie.add(req, self.cookiename, sess.id, self.path)
140 def ckfreeze(self, req):
141 sess = req.item(self.fetch)
148 def thaw(self, sessid):
151 def freeze(self, sess):
155 def __init__(self, backdb, *args, **kw):
156 super(backeddb, self).__init__(*args, **kw)
159 def thaw(self, sessid):
160 data = self.backdb[sessid]
162 return pickle.loads(data)
166 def freeze(self, sess):
167 self.backdb[sess.id] = pickle.dumps(sess)
170 class dirback(object):
171 def __init__(self, path):
174 def __getitem__(self, key):
176 with open(os.path.join(self.path, key)) as inf:
181 def __setitem__(self, key, value):
182 if not os.path.exists(self.path):
183 os.makedirs(self.path)
184 with open(os.path.join(self.path, key), "w") as out:
187 default = backeddb(dirback(os.path.join("/tmp", "wrwsess-" + str(os.getuid()))))
190 return req.item(default.fetch)