#!/usr/bin/env python # -*- coding: utf-8 -*- import datetime from collections import namedtuple import threading import logging from django.conf import settings from gm_rpcd import all from gm_rpcd.all import RPCDFaultException from gm_rpcd.features.raven import get_raven_client from gm_types.error import ERROR from gm_types.passport import USER_INFO_DETAIL_LEVEL from helios.rpc import RPCFaultException from helios.rpc import create_default_invoker from gm_logging.utils import get_exception_logging_func _base_invoker = create_default_invoker( debug=settings.DEBUG ).with_config( dump_curl=True ) exception_logger = logging.getLogger('exception_logger') __local = threading.local() def get_rpc_invoker(): return _base_invoker rpc_client = get_rpc_invoker() def gen(code, **kwargs): if code != 0: raise RPCDFaultException( code=code, message=ERROR.getDesc(code), ) return { "error": 0, "message": '', "data": kwargs, } _sentry_client = get_raven_client() # 从gm-logging中取得通用的logging_exception方法,logging_excepiton的原型如下: # logging_exception(exception_logger, sentry_client=None, send_to_sentry=True, **kwargs) logging_exception = get_exception_logging_func(exception_logger, _sentry_client) User = namedtuple('User', 'id user_id person_id nick_name portrait last_name') def _format_user(user_data): user_data['id'] = user_data['user_id'] u = User(**user_data) __local.user = u return u # TODO: threadlocal 清理 def get_current_user(): if hasattr(__local, 'user'): return __local.user # check if session_id exist if not all.context.session_id: return result = all.context.passport if result: try: u = _format_user(result) return u except: logging_exception() try: result = all.context.rpc['passport/info/by_session'](detail_level=USER_INFO_DETAIL_LEVEL.BASIC).unwrap() u = _format_user(result) return u except RPCFaultException: pass except: logging_exception() return def get_current_user_by_session_key(session_key): rpc = rpc_client.with_config(session_key=session_key) r = rpc['passport/info/by_session']() result = r.unwrap_or(None) if not result: __local.user = None return result['id'] = result['user_id'] u = User(**result) __local.user = u return u def get_current_user_by_rpcd_request(request): # try get userinfo from request.passport passport = request.passport if passport: try: u = _format_user(passport) return u except: logging_exception() return get_current_user_by_session_key(request.session_id) def get_humanize_datetime(d): """humanize datetime """ now = datetime.datetime.now() if d.year == now.year: if d.month == now.month: if d.day == now.day: return u'今天' else: return u'{}天前'.format(now.day - d.day) else: return d.strftime('%m-%d') else: return d.strftime('%Y-%m-%d') class RPCMixin(object): @staticmethod def get_rpc_invoker(): return get_rpc_invoker() @classmethod def call_rpc(cls, api_endpoint, **kwargs): """call rpc. get rpc invoker from current ctx, this method only support call rpc sequentially. """ r = cls.get_rpc_invoker() result = r[api_endpoint](**kwargs) return result.unwrap() def assert_uint(v, default=0): if isinstance(v, int): return max(0, v) else: return default def assert_str(v, default=''): if isinstance(v, (str, unicode)): return v else: return default