Last active
August 29, 2015 14:16
-
-
Save huaxinjiayou/de157d68aca9b7373525 to your computer and use it in GitHub Desktop.
tornado session 和 flash 实现,参考了 https://gist.github.com/ayang/1735032
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*-coding:utf-8-*- | |
import tornado.web | |
from frame.region import region | |
from frame.region import Session | |
from frame.region import Flash | |
import services.user | |
class BaseRequestHandler(tornado.web.RequestHandler): | |
# 这个函数的返回值,会体现在模板的 current_user 中 | |
def get_current_user(self): | |
uid = self.session['uid'] | |
return services.user.find_by_id(uid) if uid else None | |
def logout(self): | |
self.session.clear() | |
def __init__(self, *argc, **argkw): | |
super(BaseRequestHandler, self).__init__(*argc, **argkw) | |
self.region = region | |
self.request.flash = self.flash.get() | |
@property | |
def session(self): | |
session_id = self.get_secure_cookie('sid') | |
session = Session(session_id) | |
if not session_id: | |
self.set_secure_cookie('sid', session.session_id) | |
return session | |
@property | |
def flash(self): | |
return Flash(self.session) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*-coding:utf-8-*- | |
from uuid import uuid4 | |
from dogpile.cache import make_region | |
import config | |
region = make_region( | |
key_mangler=lambda key: 'ncms:tornado:' + key | |
).configure( | |
'dogpile.cache.redis', | |
arguments={ | |
'host': config.redis['host'], | |
'port': config.redis['port'], | |
'db': config.redis['db'], | |
'distributed_lock': True | |
} | |
) | |
class Session(object): | |
# 缓存池,主要用于: | |
# A 页面 redict 到 B 页面,B 的 __init__ 比 A 的 __del__ 先执行,造成 session 数据不同步 | |
pool = {} | |
def __init__(self, session_id=None): | |
self._session_id = session_id if session_id else uuid4().get_hex() | |
# 先从 redis 中读取,再从类池中读取,最后再新建 | |
session_data = region.get(self._session_id) | |
if not session_data and self._session_id in Session.pool: | |
session_data = Session.pool[self._session_id] | |
self._session_data = session_data if session_data else dict() | |
Session.pool[self._session_id] = self._session_data | |
self.dirty = False | |
def clear(self): | |
region.delete(self._session_id) | |
@property | |
def session_id(self): | |
return self._session_id | |
def clear(self, key=None): | |
if key: | |
if key in self._session_data: | |
self.__delitem__(key) | |
return | |
region.delete(self._session_id) | |
if self._session_id in Session.pool: | |
del Session.pool[self._session_id] | |
self._session_data = dict() | |
Session.pool[self._session_id] = self._session_data | |
def __getitem__(self, key): | |
if key in self._session_data: | |
return self._session_data[key] | |
def __setitem__(self, key, value): | |
self._session_data[key] = value | |
self._dirty() | |
def __delitem__(self, key): | |
if key in self._session_data: | |
del self._session_data[key] | |
self._dirty() | |
def __len__(self): | |
return len(self._session_data) | |
def __contains__(self, key): | |
return key in self._session_data | |
def __iter__(self): | |
for key in self._session_data: | |
yield key | |
def __repr__(self): | |
return self._session_data.__repr__() | |
def __del__(self): | |
if self.dirty: | |
self._save() | |
if self._session_id in Session.pool: | |
del Session.pool[self._session_id] | |
def _dirty(self): | |
self.dirty = True | |
def _save(self): | |
region.set(self._session_id, self._session_data) | |
self.dirty = False | |
class Flash: | |
def __init__(self, session): | |
self.session = session | |
def set(self, key, value): | |
data = self.session['ncms.flash.data'] | |
data = data if data else dict() | |
data[key] = value | |
self.session['ncms.flash.data'] = data | |
def get(self): | |
data = self.session['ncms.flash.data'] | |
self.session.clear('ncms.flash.data') | |
return data if data else dict() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment