def __init__(self, **kwargs): if 'prefix' in kwargs: self.prefix = kwargs['prefix'] del kwargs['prefix'] else: self.prefix = '' self.prefix = str(self.prefix) self.kv = KVClient(**kwargs)
class Client(object): u'''不能从KVClient继承,因为sae线上的kvdb需要分配server,而本地的不需要, 继承之后,在__init__的参数server不能正确传入 ''' def __init__(self, json_k_suffix, autosave=False): self._suffix = json_k_suffix self._autosave = autosave self.kv = Kv() def _do(self, key, value, func): if self._autosave: # kvdb在dev_server源码里面reload的时候不会保存数据到磁盘造成丢失, # 这里在调试模式下解决,线上环境时可删除,以提高运行速率 try: import sae.kvdb import os yes = os.environ.get('sae.run_main', '1') os.environ['sae.run_main'] = yes sae.kvdb._save_cache() except AttributeError: pass return value if not key.endswith(self._suffix) else func(value) def get(self, key, default=None): '''如果是json数据,那么返回解析为python对象后的数据''' if isinstance(key, unicode): key = key.encode('u8') value = self._do(key, self.kv.get(key), loads) return value if value is not None else default def set(self, key, value, min_compress_len=0): '''如果是json数据,那么先将python对象转换为json字符串''' if isinstance(key, unicode): key = key.encode('u8') value = self._do(key, value, dumps) return self.kv.set(key, value, min_compress_len) def add(self, key, value, min_compress_len=0): '''如果是json数据,那么先将python对象转换为json字符串''' if isinstance(key, unicode): key = key.encode('u8') value = self._do(key, value, dumps) return self.kv.add(key, value, min_compress_len)
def init(): from sae.kvdb import KVClient from pabo.main import settings import pabo.utils as utils kv = KVClient() ''' _site_info = kv.get(settings.K_SITE_INFO) _site_info['navs'][1]['link'] = '/archives' kv.set(settings.K_SITE_INFO, _site_info) ''' # 如果初始化过了就不要初始化了 if kv.get(settings.K_ADMIN_INFO) is not None: pass return kv.add = kv.set # 初始化默认分类 default = {settings.DEFAULT_CLS: u'默认分类'} kv.add(settings.K_ART_CLS, default) # 初始化文章索引 kv.add(settings.K_ARTS, '') # 初始化用户名(admin)和密码(a123) pwd = '@a123456' pwd = utils.md5(pwd + settings.COOKIE_SECRET) kv.add(settings.K_ADMIN_INFO, { 'name': 'admin', 'pwd': pwd, 'email': '*****@*****.**' }) # 初始化站点信息[不要超过4M] _site_info = { # 用于登录的网址,起一个别人不容易知道的网址 'login_url': '/login' if settings.DEBUG else '/must_not_be_guessed', 'title': u'Pabo Blog', 'subtitle': u'知识就是力量', 'keywords': u'博客 python tornado sae pabo 开源', # 网站关键字 'description': u'Pabo是一个利用python tornado web server搭建于sae上面的博客程序. 采用KVDB存储全站数据.', # 给搜索引擎用的 'theme': 'default', # 网站主题样式 'admin_theme': 'default', # 后台管理主题样式 # 友链 'links': { 'http://pabo.sinaapp.com': 'Pabo Blog', 'http://www.baidu.com': u'百度一下,你就知道', }, 'author': { 'name': u'书记', 'intro': u'书记,专注Web前端技术的凡夫俗子。', }, # 注: 请不要修改链接link值 'navs': [ { 'link': '/', 'label': u'首页', 'title': u'Pabo Blog首页' }, { 'link': '/archives', 'label': u'归档', 'title': u'文章归档' }, { 'link': '/message', 'label': u'留言', 'title': u'访客留言' }, { 'link': '/rss', 'label': u'订阅', 'title': u'RSS订阅' }, #{'link': '/about', 'label': u'关于', 'title': u'关于'}, ], 'app': 5, # article per page # 是否预览友链(如果友链多了,可能会比较卡) # XXX 如果友链那边设置了'X-Frame-Options'(如设为'SAMEORIGIN'), # 那么iframe将不能显示. 'links_preview': False, # 是否显示登录链接[安全起见,最好设置为False] 'show_login': settings.DEBUG, 'rss_full': False, # rss是否全文输出 # url显示类型,将按照顺序加载,如果加载失败,将自动尝试后面一种显示类型 # XXX 目前暂时用short # 可以根据情况变换4种类型的顺序 # short是短网址,一般为5个小写字母;(推荐使用) # digit则是文章的id, 速度最快; # english: Google翻译标题作为网址(可能不能正常访问Google导致翻译失败); # pinyin: 将文章标题转换为拼音.(产生的url可能会很长) 'url_show_order': ['short', 'digit', 'english', 'pinyin'], 'admin': { 'url': '/admin', 'title': u'后台管理', 'navs': [ # 不要修改link的值 { 'link': '/admin/stats', 'label': u'概览', 'icon': 'home' }, { 'icon': 'book', 'label': u'文章', 'sub': [ { 'link': '/admin/article/add', 'label': u'发表文章' }, { 'link': '/admin/articles/manage', 'label': u'管理文章' }, ] }, { 'link': '/admin/classes', 'label': u'分类', 'icon': 'th-list' }, { 'link': '/admin/attachments', 'label': u'附件', 'icon': 'paper-clip' }, { 'link': '/admin/friends', 'label': u'友链', 'icon': 'link' }, { 'link': '/admin/settings', 'label': u'设置', 'icon': 'cog' }, { 'link': '/admin/kv', 'label': u'KVDB', 'icon': 'hdd' }, ], 'default': '/admin/stats', # 登录后台后默认显示的页面 }, 'baidu_statistics': ''' <script> var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://"); document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3Fb665710f3241366f461da2dfe6af1dda' type='text/javascript'%3E%3C/script%3E")); </script>''', } kv.add(settings.K_SITE_INFO, _site_info) _stats_info = { 'uip': 0, # 独立ip 'pv': 0, # pv 'rss': 0, # 订阅数 } kv.add(settings.K_STATS_INFO, _stats_info) kv.disconnect_all()
# coding:utf-8 import os.path as osp import pabo.main.settings as settings from pabo.utils import template, crypto from sae.kvdb import KVClient __all__ = ['kv', 'render', 'cryptor', 'site_info', 'login_url'] kv = KVClient() # 加密解密 cryptor = crypto.SimpleCrypto(settings.COOKIE_SECRET) # 网站信息 site_info = lambda: kv.get(settings.K_SITE_INFO) _site_info = site_info() _theme = _site_info.get('theme', 'default') _admin = _site_info.get('admin_theme', 'default') admin_url = _site_info['admin']['url'] login_url = _site_info['login_url'] # jinja2 _extra = dict( site_info=site_info, settings=settings, ) if settings.DEBUG: _extra.update(__builtins__) render = template.PaboBlogRender( template_path=[
# coding:utf-8 import os.path as osp import pabo.main.settings as settings from pabo.utils import template, crypto from sae.kvdb import KVClient __all__ = ['kv', 'render', 'cryptor', 'site_info', 'login_url'] kv = KVClient() # 加密解密 cryptor = crypto.SimpleCrypto(settings.COOKIE_SECRET) # 网站信息 site_info = lambda: kv.get(settings.K_SITE_INFO) _site_info = site_info() _theme = _site_info.get('theme', 'default') _admin = _site_info.get('admin_theme', 'default') admin_url = _site_info['admin']['url'] login_url = _site_info['login_url'] # jinja2 _extra = dict( site_info=site_info, settings=settings, ) if settings.DEBUG:
def __init__(self, json_k_suffix, autosave=False): self._suffix = json_k_suffix self._autosave = autosave self.kv = Kv()
charset='utf8') try: import sae.const except ImportError: import cmemcached from config import MEMCACHED_ADDR kw = {} kw['comp_threshold'] = 4096 mc = cmemcached.Client(MEMCACHED_ADDR) else: import pylibmc mc = pylibmc.Client() try: from sae.kvdb import KVClient kv = KVClient() except ImportError: from kvstore import kv from zorm_sae.mc_connection import init_mc import zorm_sae.config zorm_sae.config.mc = mc = init_mc(mc, disable_local_cached=DISABLE_LOCAL_CACHED) from zorm_sae.mc import McCacheM, McCache, McNum, McCache, McLimitA, McCacheA, McLimitM if __name__ == "__main__": pass
try: import sae.const except ImportError: import cmemcached from config import MEMCACHED_ADDR kw = {} kw['comp_threshold'] = 4096 mc = cmemcached.Client(MEMCACHED_ADDR) else: import pylibmc mc = pylibmc.Client() try: from sae.kvdb import KVClient kv = KVClient() _set_ = kv.set def set(key, val, time=0, min_compress_len=4096): _set_(key, val, time, min_compress_len) kv.set = set except ImportError: from kvstore import kv from zorm_sae.mc_connection import init_mc import zorm_sae.config zorm_sae.config.mc = mc = init_mc( mc, disable_local_cached=DISABLE_LOCAL_CACHED )
class SAEKvdb(object): ''' A bridge for pyutils kvdb wrapper to access SAE KVDB. e.g. from pyutils import KVDBWrapper from sae_kvdb import SAEKvdb kvclient = KVDBWrapper(SAEKvdb, prefix='PRE:', ...) kvclient.set(key,value) kvclient.get(key) ''' def __init__(self, **kwargs): if 'prefix' in kwargs: self.prefix = kwargs['prefix'] del kwargs['prefix'] else: self.prefix = '' self.prefix = str(self.prefix) self.kv = KVClient(**kwargs) def info(self): return self.kv.get_info() def get(self, key, **kwargs): k = self.gen_key(key) return self.kv.get(k) def set(self, key, value, **kwargs): k = self.gen_key(key) return self.kv.set(k, value, **kwargs) def delete(self, key, **kwargs): k = self.gen_key(key) return self.kv.delete(k, **kwargs) def exist(self, key, **kwargs): k = self.gen_key(key) existed = not self.kv.add(k, '') if not existed: self.kv.delete(k) return existed def scan(self, cursor='', count=20, **kwargs): ''' Retrieve keys by given arguments :param kwargs: 'count' for retrieve count; 'cursor' is the key for next time retrieve :return: ''' return self.kv.getkeys_by_prefix(prefix=self.prefix, marker=cursor, limit=count, **kwargs) def scanv(self, cursor='', count=20, **kwargs): ''' Retrieve key-values by given arguments :param kwargs: 'count' for retrieve count; 'cursor' is the key for next time retrieve :return: ''' return self.kv.get_by_prefix(prefix=self.prefix, marker=cursor, limit=count, **kwargs) def mget(self, keys, **kwargs): return self.kv.get_multi(keys, key_prefix=self.prefix) def gen_key(self, key): k = self.prefix + str(key) return k
def init(): from sae.kvdb import KVClient from pabo.main import settings import pabo.utils as utils kv = KVClient() ''' _site_info = kv.get(settings.K_SITE_INFO) _site_info['navs'][1]['link'] = '/archives' kv.set(settings.K_SITE_INFO, _site_info) ''' # There is no need to initialize if it has if kv.get(settings.K_ADMIN_INFO) is not None: pass return kv.add = kv.set # default classificaiton default = {settings.DEFAULT_CLS: u'Default'} kv.add(settings.K_ART_CLS, default) # 初始化文章索引 kv.add(settings.K_ARTS, '') # 初始化用户名(admin)和密码(a123) pwd = '@a123456' pwd = utils.md5(pwd + settings.COOKIE_SECRET) kv.add(settings.K_ADMIN_INFO, {'name': 'admin', 'pwd': pwd, 'email': '*****@*****.**'}) # 初始化站点信息[不要超过4M] _site_info = { # 用于登录的网址,起一个别人不容易知道的网址 'login_url': '/login' if settings.DEBUG else '/must_not_be_guessed', 'title': u'Absolute Spirits', 'subtitle': u'Stay hungry, stay foolish.', 'keywords': u'blog python tornado sae opensource', # 网站关键字 'description': u'Pabo是一个利用python tornado web server搭建于sae上面的博客程序. 采用KVDB存储全站数据.', # 给搜索引擎用的 'theme': 'default', # 网站主题样式 'admin_theme': 'default', # 后台管理主题样式 # 友链 'links': { 'http://pabo.sinaapp.com': 'Pabo Blog', }, 'author': { 'name': u'SweenEy', 'intro': u'Be a craftsman', }, # 注: 请不要修改链接link值 'navs': [ {'link': '/', 'label': u'Home', 'title': u'Home page'}, {'link': '/archives', 'label': u'Archive', 'title': u'Article archive'}, # {'link': '/message', 'label': u'Comment', 'title': u'Comment'}, {'link': '/rss', 'label': u'RSS', 'title': u'RSS'}, # {'link': '/about', 'label': u'关于', 'title': u'关于'}, ], 'app': 5, # article per page # 是否预览友链(如果友链多了,可能会比较卡) # XXX 如果友链那边设置了'X-Frame-Options'(如设为'SAMEORIGIN'), # 那么iframe将不能显示. 'links_preview': False, # 是否显示登录链接[安全起见,最好设置为False] 'show_login': settings.DEBUG, 'rss_full': False, # rss是否全文输出 # url显示类型,将按照顺序加载,如果加载失败,将自动尝试后面一种显示类型 # XXX 目前暂时用short # 可以根据情况变换4种类型的顺序 # short是短网址,一般为5个小写字母;(推荐使用) # digit则是文章的id, 速度最快; # english: Google翻译标题作为网址(可能不能正常访问Google导致翻译失败); # pinyin: 将文章标题转换为拼音.(产生的url可能会很长) 'url_show_order': ['short', 'digit', 'english', 'pinyin'], 'admin': { 'url': '/admin', 'title': u'Admin', 'navs': [ # 不要修改link的值 {'link': '/admin/stats', 'label': u'概览', 'icon': 'home'}, {'icon': 'book', 'label': u'文章', 'sub':[ {'link': '/admin/article/add', 'label': u'发表文章'}, {'link': '/admin/articles/manage', 'label': u'管理文章'}, ]}, {'link': '/admin/classes', 'label': u'分类', 'icon': 'th-list'}, {'link': '/admin/attachments', 'label': u'附件', 'icon': 'paper-clip'}, {'link': '/admin/friends', 'label': u'友链', 'icon': 'link'}, {'link': '/admin/settings', 'label': u'设置', 'icon': 'cog'}, {'link': '/admin/kv', 'label': u'KVDB', 'icon': 'hdd'}, ], 'default': '/admin/stats', # 登录后台后默认显示的页面 }, 'baidu_statistics': ''' <script> var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://"); document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3Fb665710f3241366f461da2dfe6af1dda' type='text/javascript'%3E%3C/script%3E")); </script>''', } kv.add(settings.K_SITE_INFO, _site_info) _stats_info = { 'uip': 0, # 独立ip 'pv': 0, # pv 'rss': 0, # 订阅数 } kv.add(settings.K_STATS_INFO, _stats_info) kv.disconnect_all()