Ejemplo n.º 1
0
    def write_log(params):
        """
        写入日志
        :param params:
        :return:
        """
        try:
            log_id = params.get('log_id', '')
            model = ModelBase()
            logger = Logs().logger
            path = ''
            method = ''
            stack_back = inspect.currentframe()
            for i in range(len(inspect.stack())):
                stack_back = stack_back.f_back

                if stack_back and stack_back.f_locals.get('service_path', ''):
                    path = stack_back.f_locals.get('service_path', '')
                    method = stack_back.f_locals.get('method', '')
                    break
            if not log_id:
                insert_params = {
                    'transfer_method': params['transfer_method'],
                    'addr': params['addr'],
                    'path': path,
                    'method': method,
                    'params': params['params'],
                    'result': '',
                }
                # 没有log_id则插入
                key = 'transfer_method, addr, path, method, params, result'
                val = '%s, %s, %s, %s, %s, %s'
                value_tuple = (insert_params['transfer_method'], insert_params['addr'], insert_params['path'],
                               insert_params['method'], insert_params['params'], insert_params['result'])

                result = model.insert('tbl_thirdpart_connection_logs', {
                    model.sql_constants.KEY: key,
                    model.sql_constants.VAL: val
                }, tuple(value_tuple))
                return result['last_id']

            else:
                # 有log_id则更新
                update_params = {
                    'id': log_id,
                    'result': params['result']
                }
                fields = [
                    'result = %s'
                ]
                condition = ' id = %s '
                value_tuple = (update_params['result'], update_params['id'])
                return model.update('tbl_thirdpart_connection_logs', {
                    model.sql_constants.FIELDS: fields,
                    model.sql_constants.CONDITION: condition
                }, value_tuple)
        except Exception, e:
            logger.error('HTTP.POST Exception: %s, path: %s, method: %s, params: %s' % (
                e, 'tools.httputils', 'write_log', params))
            return None
Ejemplo n.º 2
0
@file: common_util.py
@time: 17/4/24 上午11:31
"""
import json
import cgi
import time
import hashlib
import random
import traceback
import re
from html.parser import HTMLParser
from source.properties import Properties
from tools.logs import Logs

properties = Properties()
logger = Logs().logger


class CommonUtil(object):
    @staticmethod
    def get_loader_version(path=None):
        """
        获取调用者的Version
        """
        version = None
        if path:
            version = re.findall(r"^v(.+?)\.", path)
            if version:
                version = 'v' + version[0]

        if not version:
Ejemplo n.º 3
0
class AsyncModelBase(SqlBuilder):
    async_pools = pools.Pool(dict(
        host=properties.get('jdbc', 'DB_HOST'),
        port=int(properties.get('jdbc', 'DB_PORT')),
        user=properties.get('jdbc', 'DB_USER'),
        passwd=properties.get('jdbc', 'DB_PASS'),
        db=properties.get('jdbc', 'DB_BASE'),
        charset='utf8',
        autocommit=False,
        cursorclass=tornado_mysql.cursors.DictCursor),
                             max_idle_connections=5,
                             max_open_connections=100)

    tx = None
    sql_builder_orm = None
    if not sql_builder_orm:
        sql_builder_orm = SqlBuilderOrm()

    redis = RedisBase()
    # redis = AsyncRedis()
    json = json
    cache_key_predix = CacheKeyPredix
    properties = properties
    date_encoder = CJsonEncoder
    util = CommonUtil
    logger = Logs().logger

    @tornado.gen.coroutine
    def do_sqls(self, params_list):
        # 执行多条sql
        sql = ''
        tx = None
        result = None
        try:
            tx = yield self.async_pools.begin()
            for params in params_list:

                sql_type = params[self.sql_constants.SQL_TYPE]
                table_name = params[self.sql_constants.TABLE_NAME]
                dict_data = params[self.sql_constants.DICT_DATA]
                value_tuple = params[self.sql_constants.VALUE_TUPLE]

                if sql_type == self.sql_constants.INSERT:
                    #  创建
                    sql = self.build_insert(table_name, dict_data)
                elif sql_type == self.sql_constants.BATCH_INSERT:
                    # 批量创建
                    sql = self.build_batch_insert(table_name, dict_data)
                elif sql_type == self.sql_constants.UPDATE:
                    # 更新
                    sql = self.build_update(table_name, dict_data)
                elif sql_type == self.sql_constants.DELETE:
                    # 删除
                    sql = self.build_delete(table_name, dict_data)

                yield tx.execute(sql, value_tuple)
            if params_list:
                yield tx.commit()
                # result = self._gr(self.sql_constants.SUCCESS.copy())
                result = self._gr(True)
        except Exception, e:
            yield tx.rollback()
            self.logger.exception(e)
            print sql
            raise self._gr(None)
        raise result
Ejemplo n.º 4
0
class AsyncModelBase(SqlBuilder):
    async_pools = pools.Pool(
        dict(host=properties.get('jdbc', 'DB_HOST'),
             port=int(properties.get('jdbc', 'DB_PORT')),
             user=properties.get('jdbc', 'DB_USER'),
             passwd=properties.get('jdbc', 'DB_PASS'),
             db=properties.get('jdbc', 'DB_BASE'),
             charset='utf8',
             autocommit=False,
             cursorclass=tornado_mysql.cursors.DictCursor),
        max_idle_connections=5,
        max_open_connections=int(properties.get('jdbc', 'MAX_CONNECTIONS')),
        max_recycle_sec=int(properties.get('jdbc', 'MAX_RECYCLE_SEC')))

    tx = None
    sql_builder_orm = None
    if not sql_builder_orm:
        sql_builder_orm = SqlBuilderOrm()

    # redis = RedisBase()
    redis = AsyncRedis()
    json = json
    cache_key_predix = CacheKeyPredix
    properties = properties
    date_encoder = CJsonEncoder
    util = CommonUtil
    date_utils = DateUtils
    logger = Logs().logger
    constants = constants.Constants

    @tornado.gen.coroutine
    def do_sqls(self, params_list):
        # 执行多条sql
        sql = ''
        tx = None
        result = None
        try:
            tx = yield self.async_pools.begin()
            for params in params_list:

                sql_type = params[self.sql_constants.SQL_TYPE]
                table_name = params[self.sql_constants.TABLE_NAME]
                dict_data = params[self.sql_constants.DICT_DATA]
                value_tuple = params[self.sql_constants.VALUE_TUPLE]

                if sql_type == self.sql_constants.INSERT:
                    #  创建
                    sql = self.build_insert(table_name, dict_data)
                elif sql_type == self.sql_constants.BATCH_INSERT:
                    # 批量创建
                    sql = self.build_batch_insert(table_name, dict_data)
                elif sql_type == self.sql_constants.UPDATE:
                    # 更新
                    sql = self.build_update(table_name, dict_data)
                elif sql_type == self.sql_constants.DELETE:
                    # 删除
                    sql = self.build_delete(table_name, dict_data)

                yield tx.execute(sql, value_tuple)
            if params_list:
                yield tx.commit()
                # result = self._gr(self.sql_constants.SUCCESS.copy())
                result = self._gr(True)
        except Exception as e:
            yield tx.rollback()
            self.logger.exception(e)
            self.logger.info(sql)
            raise self._gr(None)
        raise result

    @tornado.gen.coroutine
    def page_find(self, table_name, params, value_tuple):
        """
        分页查询
        :param params: 
        :return: 
        """
        # 分页查询
        sql = self.build_paginate(table_name, params)
        sql_count = self.build_get_rows(table_name, params)
        result = None
        try:
            cursor = yield self.async_pools.execute(sql, value_tuple)
            dict_list = cursor.fetchall()

            cursor = yield self.async_pools.execute(sql_count, value_tuple)
            dic_rows = cursor.fetchone()
            result = {
                'list':
                dict_list,
                'row_count':
                dic_rows[self.sql_constants.ROW_COUNT] if dic_rows else 0
            }
        except Exception as e:
            self.logger.info(sql)
            self.logger.info(sql_count)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def get_rows(self, table_name, params, value_tuple):
        """
        统计数量
        :param params: 
        :return: 
        """
        sql_count = self.build_get_rows(table_name, params)
        result = 0
        try:
            cursor = yield self.async_pools.execute(sql_count, value_tuple)
            dic_rows = cursor.fetchone()

            result = dic_rows[self.sql_constants.ROW_COUNT] if dic_rows else 0
        except Exception as e:
            self.logger.info(sql_count)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def find(self, table_name, params={}, value_tuple=(), str_type='one'):
        """
        查询
        :param params: 
        :return: 
        """
        sql = self.build_select(table_name, params)
        result = False
        try:
            cursor = yield self.async_pools.execute(sql, value_tuple)
            if str_type == self.sql_constants.LIST:
                result = cursor.fetchall()
            else:
                result = cursor.fetchone()
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def insert(self, table_name, params, value_tuple, auto_commit=True):
        """
        创建
        :param params: 
        :return: 
        """
        sql = self.build_insert(table_name, params)
        result = None
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)
            id = cursor.lastrowid
            result = self.sql_constants.SUCCESS.copy()
            result['last_id'] = id
            result['affected_rows'] = cursor.rowcount
        except Exception as e:
            self.tx.rollback()
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def batch_insert(self, table_name, params, value_tuple, auto_commit=True):
        """
        批量插入
        :param table_name: 
        :param params: 
        :param value_tuple: 
        :param auto_commit: 
        :return: 
        """
        result = None
        sql = self.build_batch_insert(table_name, params)
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)
            result = self.sql_constants.SUCCESS.copy()
            result['affected_rows'] = cursor.rowcount
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def update(self, table_name, params, value_tuple, auto_commit=True):
        """
        更新
        :param params: 
        :return: 
        """
        result = None
        sql = self.build_update(table_name, params)
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)
            # result = self.sql_constants.SUCCESS.copy()
            # result['affected_rows'] = cursor.rowcount
            result = cursor.rowcount
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def delete(self, table_name, params, value_tuple, auto_commit=True):
        """`
        删除
        :param params: 
        :return: 
        """
        sql = self.build_delete(table_name, params)
        result = None
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)
            # result = self.sql_constants.SUCCESS
            # result['affected_rows'] = cursor.rowcount
            result = cursor.rowcount
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)

        raise self._gr(result)

    def _gr(self, result):
        """
        异步返回结果
        :param result: 
        :return: 
        """
        return tornado.gen.Return(result)

    @tornado.gen.coroutine
    def find_orm(self, table_name, dict_data, params, str_type='one'):
        """
        orm查询语句
        :param table_name: 
        :param dict_data: 
        :param params: 
        :param str_type: 
        :return: 
        """
        sql, value_tuple = self.sql_builder_orm.build_select(
            table_name, dict_data, params)
        result = False
        try:
            cursor = yield self.async_pools.execute(sql, value_tuple)
            if str_type == self.sql_constants.LIST:
                result = cursor.fetchall()
            else:
                result = cursor.fetchone()
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def insert_orm(self, table_name, dict_data, params, auto_commit=True):
        """
        创建
        :param params: 
        :return: 
        """
        sql, value_tuple = self.sql_builder_orm.build_insert(
            table_name, dict_data, params)
        result = None
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)

            result = {'last_id': cursor.lastrowid}
        except Exception as e:
            self.tx.rollback()
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def update_orm(self, table_name, dict_data, params, auto_commit=True):
        """
        更新
        :param params: 
        :return: 
        """
        result = None
        sql, value_tuple = self.sql_builder_orm.build_update(
            table_name, dict_data, params)
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)
            result = self.sql_constants.SUCCESS
            result['affected_rows'] = cursor.rowcount
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def delete_orm(self, table_name, dict_data, params, auto_commit=True):
        """`
        删除
        :param params: 
        :return: 
        """
        sql, value_tuple = self.sql_builder_orm.build_delete(
            table_name, dict_data, params)
        result = None
        if not self.tx:
            self.tx = yield self.async_pools.begin()
        try:
            if auto_commit:
                cursor = yield self.tx.execute(sql, value_tuple)
                yield self.tx.commit()
                self.tx = None
            else:
                cursor = yield self.tx.execute(sql, value_tuple)
            # result = self.sql_constants.SUCCESS
            # result['affected_rows'] = cursor.rowcount
            result = cursor.rowcount
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def page_find_orm(self, table_name, dict_data, params):
        """
        分页查询
        :param params: 
        :return: 
        """
        # 分页查询
        sql, value_tuple = self.sql_builder_orm.build_paginate(
            table_name, dict_data, params)
        sql_count, count_value_tuple = self.sql_builder_orm.build_count(
            table_name, dict_data, params)
        result = None
        try:
            cursor = yield self.async_pools.execute(sql, value_tuple)
            dict_list = cursor.fetchall()

            cursor = yield self.async_pools.execute(sql_count,
                                                    count_value_tuple)
            dic_rows = cursor.fetchone()
            result = {
                'list':
                dict_list,
                'row_count':
                dic_rows[self.sql_constants.ROW_COUNT] if dic_rows else 0
            }
        except Exception as e:
            self.logger.info(sql)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def get_rows_orm(self, table_name, dict_data, params):
        """
        统计数量
        :param params: 
        :return: 
        """
        sql_count, value_tuple = self.sql_builder_orm.build_count(
            table_name, dict_data, params)
        result = 0
        try:
            cursor = yield self.async_pools.execute(sql_count, value_tuple)
            dic_rows = cursor.fetchone()

            result = dic_rows[self.sql_constants.ROW_COUNT] if dic_rows else 0
        except Exception as e:
            self.logger.info(sql_count)
            self.logger.exception(e)
        raise self._gr(result)

    @tornado.gen.coroutine
    def do_sqls_orm(self, params_list):
        # 执行多条sql
        sql = ''
        tx = None
        result = None
        try:
            tx = yield self.async_pools.begin()
            for params in params_list:

                sql_type = params[self.sql_constants.SQL_TYPE]
                table_name = params[self.sql_constants.TABLE_NAME]
                dict_data = params[self.sql_constants.DICT_DATA]
                value_params = params[self.sql_constants.VALUE_PARAMS]

                if sql_type == self.sql_constants.INSERT:
                    #  创建
                    sql, value_tuple = self.sql_builder_orm.build_insert(
                        table_name, dict_data, value_params)
                elif sql_type == self.sql_constants.UPDATE:
                    # 更新
                    sql, value_tuple = self.sql_builder_orm.build_update(
                        table_name, dict_data, value_params)
                elif sql_type == self.sql_constants.DELETE:
                    # 删除
                    sql, value_tuple = self.sql_builder_orm.build_delete(
                        table_name, dict_data, value_params)

                yield tx.execute(sql, value_tuple)
            if params_list:
                yield tx.commit()
                result = self._gr(self.sql_constants.SUCCESS)
        except Exception as e:
            yield tx.rollback()
            self.logger.info(sql)
            self.logger.exception(e)
            raise self._gr(None)
        raise result

    @tornado.gen.coroutine
    def cache_get(self, key):
        result = yield self.redis.get(key)
        if result:
            expire = yield self.redis.ttl(key)
            if expire < int(
                    self.properties.get('expire', 'CACHE_REFRESH_EXPIRE')):
                yield self.redis.expire(
                    key, int(self.properties.get('expire', 'CACHE_EXPIRE')))
            try:
                result = json.loads(result)
            except Exception as e:
                yield self.redis.expire(key, 0)
                result = False
                self.logger.exception(e)
            raise self._gr(result)
        else:
            raise self._gr(False)

    @tornado.gen.coroutine
    def cache_set(self, key, value):
        try:
            value = json.dumps(value, cls=self.date_encoder)
            yield self.redis.set(key, value)
            yield self.redis.expire(
                key, int(self.properties.get('expire', 'CACHE_EXPIRE')))
            raise self._gr(True)
        except Exception as e:
            if isinstance(e, tornado.gen.Return):
                raise self._gr(e)
            self.logger.exception(e)
            raise self._gr(False)

    @tornado.gen.coroutine
    def cache_mget(self, keys):
        """
        批量获取缓存
        :param keys:
        :return:
        """
        values = yield self.redis.mget(keys)
        result = list()
        error_keys = list()
        for index in range(len(keys)):
            if values[index]:
                try:
                    # 更新缓存过期时间
                    result.append(json.loads(values[index]))
                    expire = yield self.redis.ttl(keys[index])
                    if expire < int(
                            self.properties.get('expire',
                                                'CACHE_REFRESH_EXPIRE')):
                        yield self.redis.expire(
                            keys[index],
                            int(self.properties.get('expire', 'CACHE_EXPIRE')))
                except Exception as e:
                    self.logger.exception(e)
                    error_keys.append(keys[index])
                    yield self.redis.expire(keys[index], 0)
            else:
                error_keys.append(keys[index])
        raise self._gr({'data': result, 'error': error_keys})

    @tornado.gen.coroutine
    def cache_del(self, *key):
        """
        删除缓存
        author: yuiitsu
        date: 2017-09-27
        :param key:
        :return:
        """
        if key:
            result = yield self.redis.delete(*key)
            raise self._gr(result)
Ejemplo n.º 5
0
class ServiceBase(object):
    time = time
    datetime = datetime
    json = json
    hashlib = hashlib
    error_code = Code
    properties = Properties()
    redis = AsyncRedis()
    http_utils = HttpUtils
    common_utils = CommonUtil
    logger = Logs().logger
    lang = LangManager()
    task = task
    schedule = schedule

    def import_model(self, model_name):
        """
        加载数据类
        :param model_name: string 数据类名
        :return:
        """
        try:
            version = self.common_utils.get_loader_version()
            model = importlib.import_module('src.module.' + version + '.' +
                                            model_name)
            return model.Model()
        except Exception as e:
            self.logger.exception(e)
            return None

    def do_service(self, service_path, method, params):
        """
        调用服务
        :param service_path: 
        :param method: 
        :param params: 
        :return: 
        """
        version = self.common_utils.get_loader_version(service_path)
        return serviceManager.do_service(service_path,
                                         method,
                                         params=params,
                                         version=version)

    @tornado.gen.coroutine
    def load_extensions(self, trigger_position, data):
        """
        加载扩展程序
        :param trigger_position:
        :param data:
        :return:
        """
        data['trigger_position'] = trigger_position
        result = yield self.do_service('v1.cfg.extensions.service', 'query',
                                       {'trigger_position': trigger_position})
        if result and 'code' in result and result['code'] == 0:
            # 发送消息
            for item in result['data']:
                service_path = item['package_path']
                method = item['method']
                yield self.task.add(service_path, method, data)

    def _e(self, error_key):
        """
        :param error_key: 
        :return: 
        """
        data = {}
        for key in self.error_code[error_key]:
            data[key] = self.error_code[error_key][key]

        return data

    def _gre(self, data):
        """
        tornado.gen.Return
        :rtype:
        :param data: 数据
        :return: 
        """
        return tornado.gen.Return(self._e(data))

    def _gree(self, error_key, customer_msg):
        """
        自定义扩展错误信息
        :param error_key: 
        :param customer_msg: 自定义额外错误信息
        :return: 
        """
        result = self._e(error_key)
        if customer_msg:
            result['msg'] += '({})'.format(customer_msg)
        return tornado.gen.Return(result)

    def _grs(self, data):
        """
        成功返回
        :param data: 
        :return: 
        """
        result = self._e('SUCCESS')
        result['data'] = data
        return tornado.gen.Return(result)

    def _gr(self, data):
        """
        tornado.gen.Return
        :param data: 数据
        :return: 
        """
        return tornado.gen.Return(data)

    @classmethod
    def params_set(cls, model=None, data=None):
        """
        数据对象设置
        :param model:
        :param data:
        :return:
        """
        def decorate(func):
            @wraps(func)
            @tornado.gen.coroutine
            def wrapper(*args, **kwargs):
                o = args[0]
                params = args[1]
                model_data = None
                if hasattr(o, model):
                    model_obj = getattr(o, model)
                    if hasattr(model_obj, data):
                        model_data = getattr(model_obj, data)

                new_args = args
                if model_data:
                    if isinstance(params, dict):
                        model_data.update(params)
                        new_args = (args[0], model_data)

                result = yield func(*new_args, **kwargs)

                return result

            return wrapper

        return decorate
Ejemplo n.º 6
0
pool_size = 3
try:
    pool_size = int(properties.get('task', 'POOL_NUM'))
except Exception, e:
    print e

redis = RedisBase()
task_redis = redis.get_conn()
error_redis = redis.get_conn()
cache_key = cachekey.TASK_DATA_LIST
error_cache_key = cachekey.ERROR_TASK_DATA_LIST
pool = threadpool.ThreadPool(pool_size)
service_manager = ServiceManager()
config = config
logger = Logs().get_logger()


def update_task(last_id):
    """
    更新任务完成状态
    :param last_id:
    :return:
    """
    model = ModelBase()
    fields = ['is_complete = 1']
    condition = ' id = %s '
    value_tuple = (last_id, )
    result = model.update(
        'tbl_task_job_logs', {
            model.sql_constants.FIELDS: fields,
Ejemplo n.º 7
0
import importlib

from base.service import ServiceBase
from source.async_model import AsyncModelBase
from source.async_redis import AsyncRedis
from tools.date_json_encoder import CJsonEncoder
from tools.date_utils import DateUtils
from tools.logs import Logs
from tools.cron_utils import CronUtils
from source.properties import Properties
from task.schedule.path_conf import CONF
import task

# redis = RedisBase()
redis = AsyncRedis()
logger = Logs().logger
cron_utils = CronUtils()
properties = Properties('schedule')

intervals = int(properties.get('schedule', 'intervals'))
run_time = int(properties.get('schedule', 'run_time'))
SCHEDULE_KEY = properties.get('schedule', 'schedule_key')
JOB_KEY = properties.get('schedule', 'job_key')
key_YYMMDDHHMM = '%Y%m%d%H%M'
key_YYMMDDHHMMSS = '%Y%m%d%H%M%S'


async def do_job_list(job_list, is_normal=True):
    """
    开协程执行定时任务
    job_list 需要执行的任务列表
Ejemplo n.º 8
0
class ServiceBase(object):
    dicConfig = config.CONF
    time = time
    datetime = datetime
    json = json
    hashlib = hashlib
    constants = Constants
    error_code = Code
    cache_key_predix = CacheKeyPredix
    properties = Properties()
    # redis = AsyncRedis()
    redis = RedisBase()
    httputils = HttpUtils
    date_utils = DateUtils
    common_utils = CommonUtil
    string_utils = StringUtils
    date_encoder = CJsonEncoder
    rsa_utils = RsaUtils
    excel_util = excel_util
    logger = Logs().logger
    language_code = {}
    power_tree = []
    power_path_list = []

    # tornado_redis = TornadoRedis()

    def md5(self, text):
        """
        md5加密
        :param text: 
        :return: 
        """
        result = hashlib.md5(text)
        return result.hexdigest()

    def import_model(self, model_name):
        """
        加载数据类
        :param model_name: string 数据类名
        :return: 
        """
        try:
            model = importlib.import_module('module.' + model_name)
            return model.Model()
        except Exception as e:
            return None

    def time_to_mktime(self, time_str, format_str):
        """
        将时间字符串转化成时间戳
        :param params: 
        :return: 
        """
        return time.mktime(time.strptime(time_str, format_str))

    def salt(self, salt_len=6, is_num=False):
        """ 
        密码加密字符串
        生成一个固定位数的随机字符串,包含0-9a-z
        @:param salt_len 生成字符串长度
        """

        if is_num:
            chrset = '0123456789'
        else:
            chrset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ'
        salt = []
        for i in range(salt_len):
            item = random.choice(chrset)
            salt.append(item)

        return ''.join(salt)

    def create_uuid(self):
        """
        创建随机字符串
        :return: 
        """
        m = hashlib.md5()
        m.update(bytes(str(time.time()) + self.salt(12)))
        return m.hexdigest()

    def loads_list(self, list_str):
        """
        转换字符串成列表
        :param list_str: 
        :return: 
        create:wsy 2017/7/31
        """
        try:
            data_list = self.json.loads(list_str)
        except Exception as e:
            data_list = []
        return data_list

    def loads_dic(self, dic_str):
        """
        转换字符串成字典
        :param dic_str: 
        :return: 
        create:wsy 2017/7/31
        """
        try:
            data_dic = self.json.loads(dic_str)
        except Exception as e:
            data_dic = {}
        return data_dic

    def escape_string(self, data, un=None):
        """
        特殊字符转义
        :param data: string, tuple, list, dict 转义数据
        :param un: 
        :return: 
        """
        if isinstance(data, str):
            return tornado.escape.xhtml_escape(data) if not un else tornado.escape.xhtml_unescape(data)
        elif isinstance(data, tuple) or isinstance(data, list):
            lisData = []
            for item in data:
                lisData.append(
                    tornado.escape.xhtml_escape(str(item)) if not un else tornado.escape.xhtml_unescape(str(item)))

            return lisData
        elif isinstance(data, dict):
            for key in data:
                data[key] = tornado.escape.xhtml_escape(str(data[key])) if not un else tornado.escape.xhtml_unescape(
                    str(data[key]))

            return data

    def do_service(self, service_path, method, params={}):
        """
        调用服务
        :param service_path: 
        :param method: 
        :param params: 
        :return: 
        """
        return serviceManager.do_service(service_path, method, params=params, version=config.CONF['version'])

    def do_model(self, model_path, method, params={}):
        """
        调用数据服务
        :param model_path: 
        :param method: 
        :param params: 
        :return: 
        """
        return modelManager.do_model(model_path, method, params=params, version=config.CONF['version'])

    def sign_params(self, params, secret_key):
        """
        验签
        :param params:
        :param secret_key:
        :return:
        """

        params_keys = []
        for (k, v) in params.items():
            if k != 'sign':
                params_keys.append(k)

        params_string = ''
        for key in sorted(params_keys):
            params_string += (key + '=' + params[key] + '&')
        params_string = self.md5(params_string + secret_key).upper()
        return params_string == params['sign'].upper()

    @tornado.gen.coroutine
    def load_extensions(self, trigger_position, data):
        """
        加载扩展程序
        :param trigger_position:
        :param data:
        :return:
        """
        result = yield self.do_service('cfg.extensions.service', 'query', {'trigger_position': trigger_position})
        if result and 'code' in result and result['code'] == 0:
            # 发送消息
            for item in result['data']:
                service_path = item['package_path']
                method = item['method']
                self.publish_message(service_path, method, data)

    def publish_message(self, service_path, method, params, task_key=None):
        """
        发消息到队列中心(redis)
        :return: 
        """
        self.logger.info('发消息 service: %s, method: %s, params: %s', service_path, method,
                         self.json.dumps(params, cls=self.date_encoder))
        try:
            if task_key is None:
                task_key = self.cache_key_predix.TASK_DATA_LIST
            result = self.redis.lpush(task_key, self.json.dumps({
                'service_path': service_path,
                'method': method,
                'params': params
            }, cls=self.date_encoder))
            return result
        except Exception as e:
            self.logger.error(e.args)
            return False

    def web_event(self, method, event_list, request, data, agent_status=''):
        """
        页面事件
        :param method:
        :param event_list:
        :param request:
        :param data:
        :param agent_status: 用于判断,是否要记录用户的访问信息,便于后面获取不到用户访问信息时使用,如支付回调
        :return:
        """
        t = time.time()
        cache_key = 'buyer:agent:' + agent_status
        if not request:
            request_str = self.redis.get(cache_key)
            request = self.json.loads(request_str)
        else:
            request_str = self.json.dumps(request)
            if agent_status:
                # self.redis.set_value(cache_key, request_str)
                self.redis.set(cache_key, request_str, 60 * 60)

        message_data = {
            'event_list': event_list,
            'request': request,
            'data': data,
            'time': t
        }

        self.logger.warning('web_event request: %s, data: %s , time: %s', request_str, self.json.dumps(message_data), t)

        return self.publish_message('task.statistics.yui.service', method, message_data)

    def _e(self, error_key):
        """
        :param error_key: 
        :return: 
        """
        data = {}
        for key in self.error_code[error_key]:
            data[key] = self.error_code[error_key][key]
        if error_key in self.language_code:
            data['msg'] = self.language_code[error_key]

        return data

    def _gre(self, data):
        """
        tornado.gen.Return
        :param data: 数据
        :return: 
        """
        return tornado.gen.Return(self._e(data))

    def _grs(self, data={}):
        """
        成功返回
        :param data: 
        :return: 
        """
        result = self._e('SUCCESS')
        result['data'] = data
        return tornado.gen.Return(result)

    def _gr(self, data):
        """
        tornado.gen.Return
        :param data: 数据
        :return: 
        """
        return tornado.gen.Return(data)

    def cache_get(self, key):
        result = self.redis.get(key)
        if result:
            expire = self.redis.ttl(key)
            if expire < self.properties.get('expire', 'CACHE_REFRESH_EXPIRE'):
                self.redis.expire(key, self.properties.get('expire', 'CACHE_EXPIRE'))
            try:
                result = json.loads(result)
            except Exception as e:
                self.redis.expire(key, 0)
                result = False
            return result
        else:
            return False

    def cache_set(self, key, value):
        try:
            value = json.dumps(value, cls=self.date_encoder)
            self.redis.set(key, value)
            self.redis.expire(key, self.properties.get('expire', 'CACHE_EXPIRE'))
        except Exception:
            return

    def get_path(self, data):
        """
        1 遍历用户权限树,如果有child,获得child的path,如果没有,返回power['path']
        2 递归的遍历child获得path,知道所有child为空
        3 将所有path加载到power_tree 列表中
        :param data: 用户权限树
        :return:
        """
        for power in data:
            if power['child']:
                self.power_path_list.append(str(power['path']))
                self.get_path(power['child'])
            else:
                self.power_path_list.append(str(power['path']))
        return self.power_path_list
Ejemplo n.º 9
0
class Base(Controller):

    json = json
    time = time
    logged_user = {}
    redis = RedisBase()
    # redis = AsyncRedis()
    user_data = {}
    buyer_user_data = {}
    version = config.CONF['version']
    cache_key_pre = CacheKeyPredix
    error_code = Code
    constants = Constants
    properties = Properties()
    logger = Logs().logger
    auth = None
    shop_id = '0'
    _params = {}

    # def initialize(self):
    #     """
    #     初始化
    #     初始化数据类
    #     """
    #     # Controller.config = config.CONF
    #     # Controller.initialize(self)
    #     # # self.view_data['title'] = self.config['title']
    #     # # 访问者身份标识
    #     # self.get_user_unique_code()
    #     # self._params = self.get_params()

    @tornado.gen.coroutine
    def prepare(self):
        """
        接受请求前置方法
            1.解析域名
            2.权限检查
        :return:
        """
        # 访问者身份标识
        self.get_user_unique_code()
        self._params = self.get_params()

        yield self.get_shop_host(self.request.host)
        if self.auth:
            if self.auth[0] is not None:
                auth_status = yield self.auth_check()
                if not auth_status:
                    self.finish()

                # 刷新token
                yield self.refresh_token()

    @tornado.gen.coroutine
    def auth_check(self):
        """ 
        登录认证
            根据控制器的权限设置,调用不同的权限检查
        """

        auth = self.auth
        # 如果没有设置权限,返回
        if not auth or not auth[0]:
            raise self._gr(True)

        is_auth_error = False
        is_login = True
        is_auth = True
        power_group = auth[0]
        for group in power_group:
            if group == 'buyer':
                # 买家
                buyer_token = self.params('buyer_token')
                if not buyer_token:
                    buyer_token = self.get_cookie('buyer_token')

                if not buyer_token:
                    is_login = False
                    break

                cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(
                    buyer_token)
                user_data = self.redis.hgetall(cache_key)
                self.buyer_user_data = user_data

            elif group == 'admin' or group == 'seller':
                sign = self.params('sign')
                if sign:
                    sign_token = yield self.sign_login()
                    if not sign_token:
                        token = self.params('token')
                        if not token:
                            token = self.get_cookie('token')

                        if not token:
                            is_login = False
                            break
                    else:
                        token = sign_token
                else:
                    token = self.params('token')
                    if not token:
                        token = self.get_cookie('token')

                    if not token:
                        is_login = False
                        break

                cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
                user_data = self.redis.hgetall(cache_key)
                self.user_data = user_data

            else:
                is_auth_error = True
                self.logger.exception('auth error')
                break

            if not user_data:
                is_login = False
                break

            if 'user_type' not in user_data:
                is_login = False
                break

            if user_data['user_type'] not in self.auth[0]:
                is_auth = False
                break

        if is_auth_error:
            self.error_out(self._e('AUTH_SET_ERROR'))
            raise self._gr(False)

        if not is_login:
            self.error_out(self._e('NOT_LOGIN'))
            raise self._gr(False)

        if not is_auth:
            self.error_out(self._e('AUTH_ERROR'))
            raise self._gr(False)

        raise self._gr(True)

    @tornado.gen.coroutine
    def create_token(self, params, user_type, expire=None):
        """
        创建token和cookie
        :param params:
        :param user_type:
        :param expire:
        :return:
        """
        if not user_type:
            raise self._gr({'code': -1, 'msg': ''})

        # 处理domain
        request = self.request
        host = request.host
        host_port = host.split(':')
        hosts = host_port[0].split('.')
        domain_base = '.'.join(hosts[-2:])

        # 根据用户类型,生成缓存KEY
        if user_type == 'admin':
            token = self.cache_key_pre.ADMIN_TOKEN + self.salt(salt_len=32)
            cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
            expire = expire if expire else int(
                self.properties.get('expire', 'ADMIN_EXPIRE'))
            cookie_key = 'token'
            params['user_type'] = self.constants.ADMIN_TYPE
        elif user_type == 'buyer':
            token = self.cache_key_pre.BUYER_TOKEN + self.salt(salt_len=32)
            cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(token)
            expire = expire if expire else int(
                self.properties.get('expire', 'BUYER_EXPIRE'))
            cookie_key = 'buyer_token'
            params['user_type'] = self.constants.BUYER_TYPE
        else:
            raise self._gr({'code': -1, 'msg': ''})

        # 创建缓存
        self.redis.hmset(cache_key, params)

        # 设置cookie
        if 'remember' in params and params['remember'] == '1':
            self.redis.expire(
                cache_key,
                int(self.properties.get('expire', 'ADMIN_EXPIRE_REMEMBER')))
            self.set_cookie(
                cookie_key,
                token,
                expires=time.time() +
                int(self.properties.get('expire', 'ADMIN_EXPIRE_REMEMBER')),
                domain=domain_base)
        else:
            self.redis.expire(cache_key, expire)
            self.set_cookie(cookie_key, token, domain=domain_base)

        raise self._gr({'token': token})

    @tornado.gen.coroutine
    def refresh_token(self):
        """
        刷新token
        :return:
        """
        auth = self.auth
        # 如果没有设置权限,返回
        if not auth or not auth[0]:
            raise self._gr(True)

        cache_key = ''
        expire = ''
        refresh_expire = ''
        power_group = auth[0]
        for group in power_group:
            if group == 'buyer':
                # 买家
                buyer_token = self.params('buyer_token')
                if not buyer_token:
                    buyer_token = self.get_cookie('buyer_token')

                if not buyer_token:
                    break

                cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(
                    buyer_token)
                expire = int(self.properties.get('expire', 'BUYER_EXPIRE'))
                refresh_expire = int(
                    self.properties.get('expire', 'BUYER_REFRESH_EXPIRE'))
            elif group == 'admin' or group == 'seller':
                token = self.params('token')
                if not token:
                    token = self.get_cookie('token')

                if not token:
                    break

                if self.params('sign'):
                    shop_id = self.params('shop_id')
                    token = 'sign:' + shop_id
                    # cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)

                cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
                expire = int(self.properties.get('expire', 'ADMIN_EXPIRE'))
                refresh_expire = int(
                    self.properties.get('expire', 'ADMIN_REFRESH_EXPIRE'))

        if cache_key and expire and refresh_expire:
            cache_data = self.redis.ttl(cache_key)
            if cache_data:
                left_seconds = int(cache_data)
                # 获取用户登录数据
                self.user_data = self.redis.hgetall(cache_key)
                if (expire - left_seconds) >= refresh_expire:
                    # 如果token的总生命秒数 - 剩余生命秒数 <= 刷新秒数,则重新设置token的生命秒数
                    self.redis.expire(cache_key, expire)

    @tornado.gen.coroutine
    def sign_login(self):
        """
        签名登录
            1.检查缓存是否有值,有值直接返回真
            2.如果没值,调用验签服务进行验签
            3.验签通过,生成缓存
        :return:
        """
        # 检查缓存是否有值
        shop_id = self.params('shop_id')
        token = 'sign:' + shop_id
        cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
        user_data = self.redis.hgetall(cache_key)
        if user_data:
            raise self._gr(token)

        sign = self.params('sign')
        sing_result = yield self.do_service('user.auth.sign.service',
                                            'sign_login', self.params())
        if sing_result['code'] != 0:
            raise self._gr(False)

        # 创建缓存
        self._params['sign'] = sign
        self.redis.hmset(
            cache_key, {
                'shop_id': shop_id,
                'user_type': self.constants.SELLER_TYPE,
                'admin_id': -1,
                'group_id': 0
            })

        # 设置cookie
        expire = int(self.properties.get('expire', 'ADMIN_EXPIRE'))
        self.redis.expire(cache_key, expire)

        raise self._gr(token)

    def md5(self, text):
        """ 
        MD5加密
        @:param text 需加密字符串
        @return 加密后字符串
        """
        result = hashlib.md5(text)
        return result.hexdigest()

    def create_uuid(self):
        """
        声称随机字符串
        :return: 
        """
        m = hashlib.md5()
        m.update(bytes(str(time.time()), encoding='utf-8'))
        return m.hexdigest()

    def sha1(self, text):
        """ 
        sha1 加密
        @:param text 需加密字符串
        @return 加密后字符串
        """
        return hashlib.sha1(text).hexdigest()

    def salt(self, salt_len=6, is_num=False):
        """ 
        密码加密字符串
        生成一个固定位数的随机字符串,包含0-9a-z
        @:param salt_len 生成字符串长度
        """

        if is_num:
            chrset = '0123456789'
        else:
            chrset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ'
        salt = []
        for i in range(salt_len):
            item = random.choice(chrset)
            salt.append(item)

        return ''.join(salt)

    def out(self, data):
        """ 
        输出结果
        :param code: 错误信息对象
        :param data: 返回数据字典
        """
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(self.json.dumps(data, cls=CJsonEncoder))

    def error_out(self, error, data=''):
        """
        错误输出
        :param error: 错误信息对象
        :param data: 返回数据字典
        :return: 
        """
        out = error
        if data:
            out['data'] = data

        self.write(out)

    def clear_template_cache(self):
        """ 清除模板缓存
        """

        self._template_loaders.clear()

    @tornado.gen.coroutine
    def get(self):
        """
        重写父类get方法,接受GET请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    @tornado.gen.coroutine
    def post(self):
        """
        重写父类post方法,接受POST请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    @tornado.gen.coroutine
    def get_shop_host(self, host):
        """
        根据二级域名获取店铺ID
        规则:
        只有当有二级域名,且不为www时执行查找,先从缓存中获取,再从数据库中获取
        :param host:
        :return:
        """
        is_use_domain = 'False'
        try:
            is_use_domain = self.properties.get('domain', 'is_use')
        except Exception, e:
            print e
        if host and cmp(is_use_domain, 'True') == 0:
            hosts = host.split('.')
            if len(hosts) > 1 and cmp(hosts[0], 'www') != 0 and cmp(
                    hosts[0], 'wxauth') != 0:
                second_domain = hosts[0]
                if second_domain:
                    # 获取缓存中的数据
                    cache_key = self.cache_key_pre.DOAMIN_SHOP_ID + second_domain
                    shop_id = self.redis.get(cache_key)
                    if not shop_id:
                        # 获取数据库中的数据
                        result = yield self.do_service(
                            'channel.shop.service', 'query_shop_id',
                            {'domain': second_domain})
                        if result and result['code'] == 0:
                            shop_id = result['data']['shop_id']
                            # 设置缓存数据
                            self.redis.set(cache_key, shop_id, 604800)
                    else:
                        # 获取缓存剩余过期秒数,如果小于3天,则重新设置过期时间
                        expire_second = self.redis.ttl(cache_key)
                        if int(expire_second) <= 10800:
                            self.redis.expire(cache_key, 604800)

                    if shop_id:
                        self.shop_id = shop_id
                        # 给参数对象添加shop_id
                        # params = self.params()
                    self._params['shop_id'] = shop_id
Ejemplo n.º 10
0
class RedisBase(object):

    pool = redis.ConnectionPool(host=properties.get("redis", "REDIS_HOST"),
                                port=properties.get("redis", "REDIS_PORT"),
                                password=properties.get("redis", "REDIS_PASS"),
                                decode_responses=True,
                                max_connections=1000)

    logger = Logs().logger

    def get_conn(self):
        return redis.StrictRedis(connection_pool=self.pool)

    def set_value(self, key, value):
        try:
            resource = self.get_conn()
            resource.set(key, value)
        except Exception as e:
            self.logger.exception(e)

    def set(self, key, value, second=0):
        try:
            resource = self.get_conn()
            if second > 0:
                resource.setex(key, second, value)
            else:
                resource.set(key, value)
        except Exception as e:
            self.logger.exception(e)

    def get(self, key):
        try:
            resource = self.get_conn()
            return resource.get(key)
        except Exception as e:
            self.logger.exception(e)

    def delete(self, *key):
        result = None
        try:
            resource = self.get_conn()
            result = resource.delete(*key)
        except Exception as e:
            self.logger.exception(e)
        return result

    def hmset(self, key, value, second=0):
        try:
            resource = self.get_conn()
            with resource.pipeline() as pipe:
                pipe.hmset(key, value)
                if second > 0:
                    pipe.expire(key, int(second))
                pipe.execute()
        except Exception as e:
            self.logger.exception(e)

    def hgetall(self, key):
        try:
            resource = self.get_conn()
            return resource.hgetall(key)
        except Exception as e:
            self.logger.exception(e)

    def mget(self, key):
        try:
            resource = self.get_conn()
            return resource.mget(key)
        except Exception as e:
            self.logger.exception(e)

    def ttl(self, key):
        try:
            resource = self.get_conn()
            return resource.ttl(key)
        except Exception as e:
            self.logger.exception(e)

    def expire(self, key, second=0):
        try:
            resource = self.get_conn()
            return resource.expire(key, int(second))
        except Exception as e:
            self.logger.exception(e)

    def incr(self, key, amount=1):
        try:
            resource = self.get_conn()
            return resource.incr(key, amount)
        except Exception as e:
            self.logger.exception(e)

    def decr(self, key, amount=1):
        try:
            resource = self.get_conn()
            return resource.decr(key, amount)
        except Exception as e:
            self.logger.exception(e)

    def sadd(self, key, value):
        try:
            resource = self.get_conn()
            return resource.sadd(key, value)
        except Exception as e:
            self.logger.exception(e)

    def srem(self, key, value):
        try:
            resource = self.get_conn()
            return resource.srem(key, value)
        except Exception as e:
            self.logger.exception(e)

    def smembers(self, key):
        try:
            resource = self.get_conn()
            return resource.smembers(key)
        except Exception as e:
            self.logger.exception(e)

    def spop(self, key):
        try:
            resource = self.get_conn()
            return resource.spop(key)
        except Exception as e:
            self.logger.exception(e)

    def srem(self, key, value):
        try:
            resource = self.get_conn()
            return resource.srem(key, value)
        except Exception as e:
            self.logger.exception(e)

    def lpush(self, key, value):
        try:
            resource = self.get_conn()
            return resource.lpush(key, value)
        except Exception as e:
            self.logger.exception(e)

    def rpush(self, key, value):
        try:
            resource = self.get_conn()
            return resource.rpush(key, value)
        except Exception as e:
            self.logger.exception(e)

    def rpop(self, key):
        try:
            resource = self.get_conn()
            return resource.rpop(key)
        except Exception as e:
            self.logger.exception(e)
            raise e

    def llen(self, key):
        try:
            resource = self.get_conn()
            return resource.llen(key)
        except Exception as e:
            self.logger.exception(e)

    def lrange(self, key, start, end):
        try:
            resource = self.get_conn()
            return resource.lrange(key, start, end)
        except Exception as e:
            self.logger.exception(e)

    def hincrby(self, key, field, increment=1):
        try:
            resource = self.get_conn()
            return resource.hincrby(key, field, increment)
        except Exception as e:
            self.logger.exception(e)

    def hget(self, key, field):
        try:
            resource = self.get_conn()
            return resource.hget(key, field)
        except Exception as e:
            self.logger.exception(e)

    def hset(self, key, field, value):
        try:
            resource = self.get_conn()
            return resource.hset(key, field, value)
        except Exception as e:
            self.logger.exception(e)

    def hdel(self, key, field):
        try:
            resource = self.get_conn()
            return resource.hdel(key, field)
        except Exception as e:
            self.logger.exception(e)

    def scard(self, key):
        try:
            resource = self.get_conn()
            return resource.scard(key)
        except Exception as e:
            self.logger.exception(e)
Ejemplo n.º 11
0
class Base(Controller):

    json = json
    time = time
    redis = AsyncRedis()
    error_code = Code
    properties = Properties()
    logger = Logs().logger
    _params = {}

    @tornado.gen.coroutine
    def prepare(self):
        """
        接受请求前置方法
            1.解析域名
            2.检查IP限制
            3.权限检查
        :return:
        """
        self._params = self.get_params()

    def out(self, data):
        """ 
        输出结果
        :param data: 返回数据字典
        """
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(self.json.dumps(data, cls=CJsonEncoder))

    def error_out(self, error, data=''):
        """
        错误输出
        :param error: 错误信息对象
        :param data: 返回数据字典
        :return: 
        """
        out = error
        if data:
            out['data'] = data

        self.write(out)

    @tornado.gen.coroutine
    def get(self):
        """
        重写父类get方法,接受GET请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    @tornado.gen.coroutine
    def post(self):
        """
        重写父类post方法,接受POST请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    def do_service(self, service_path, method, params):
        """
        调用服务
        :param service_path: 
        :param method: 
        :param params: 
        :return: 
        """
        version = CommonUtil.get_loader_version(service_path)
        power_tree = self.settings['power_tree']
        return serviceManager.do_service(service_path,
                                         method,
                                         params=params,
                                         version=version,
                                         power=power_tree)

    def _e(self, error_key):
        """
        :param error_key:
        :return: 
        """
        data = {}
        for key in self.error_code[error_key]:
            data[key] = self.error_code[error_key][key]

        return data

    def _gr(self, data):
        """
        tornado.gen.Return
        :param data: 数据
        :return:
        """
        return tornado.gen.Return(data)

    def params(self, key=''):
        """
        获取参数中指定key的数据
        :param key:
        :return:
        """
        if not key:
            return self._params
        elif key not in self._params:
            return ''
        else:
            return self._params[key]

    def get_user_agent(self):
        """
        获取用户访问数据
        :return:
        """
        request = self.request
        if 'Remote_ip' in request.headers and request.headers['Remote_ip']:
            ip = request.headers['Remote_ip']
        elif 'X-Forward-For' in request.headers and request.headers[
                'X-Forward-For']:
            ip = request.headers['X-Forward-For']
        else:
            ip = request.remote_ip

        cookies = ''
        if request.cookies:
            for k, v in request.cookies.items():
                cookies += k + '=' + v.value + ';'

        try:
            user_agent = request.headers['User-Agent']
        except Exception as e:
            user_agent = ''

        return {'remote_ip': ip, 'user_agent': user_agent, 'cookies': cookies}
Ejemplo n.º 12
0
class Base(Controller):

    json = json
    time = time
    logged_user = {}
    # redis = RedisBase()
    redis = AsyncRedis()
    user_data = {}
    buyer_user_data = {}
    version = config.CONF['version']
    cache_key_pre = CacheKeyPredix
    error_code = Code
    constants = Constants
    properties = Properties()
    logger = Logs().logger
    auth = None
    shop_id = '0'
    _params = {}
    power_tree = []

    # def initialize(self):
    #     """
    #     初始化
    #     初始化数据类
    #     """
    #     # Controller.config = config.CONF
    #     # Controller.initialize(self)
    #     # # self.view_data['title'] = self.config['title']
    #     # # 访问者身份标识
    #     # self.get_user_unique_code()
    #     # self._params = self.get_params()

    @tornado.gen.coroutine
    def prepare(self):
        """
        接受请求前置方法
            1.解析域名
            2.检查IP限制
            3.权限检查
        :return:
        """
        # 访问者身份标识
        self.get_user_unique_code()
        self._params = self.get_params()

        # user_data_dict = yield self.__get_login_user_data()
        # # 1.
        # yield self.get_shop_host(self.request.host)

        # 2.检查IP限制
        # intercept_status = yield self.intercept_ip(user_data_dict)
        # if not intercept_status:
        #     self.finish()

        # 3.
        if self.auth:
            if self.auth[0] is not None:
                auth_status = yield self.auth_check(user_data_dict)
                if not auth_status:
                    self.finish()

                # 刷新token
                yield self.refresh_token()

    @tornado.gen.coroutine
    def intercept_ip(self, user_data_dict):
        """
        拦截IP 对C端拦截,B端不拦截
            1. 检查登录用户信息,如果有商户信息,所有请求不检查IP拦截
            2. 调用服务计算拦截
        :return:
        """
        # 判断是否有seller信息,如果有不检查IP
        seller_data = user_data_dict.get('seller', {})
        if seller_data:
            raise self._gr(True)

        # 调用IP拦截service
        result = yield self.do_service(
            'system.ip_country.service', 'intercept', {
                'shop_id': self._params.get('shop_id', ''),
                'ip': self.request.remote_ip
            })

        if result['code'] != 0:
            self.error_out(result)
            raise self._gr(False)

        raise self._gr(True)

    @tornado.gen.coroutine
    def auth_check(self, user_data_dict):
        """
        登录认证
            根据控制器的权限设置,调用不同的权限检查
        """
        # # 1.获取登录用户信息
        # user_data_dict = yield self.__get_login_user_data()

        auth = self.auth
        # 如果没有设置权限,返回
        if not auth or not auth[0]:
            raise self._gr(True)

        is_auth_error = False
        is_login = True
        is_auth = True
        power_group = auth[0]
        no_check_control = auth[1] if len(auth) > 1 else False
        # 2.根据控制器设置,进行检查
        for group in power_group:
            if group == 'buyer':
                # 买家
                user_data = user_data_dict.get('buyer', {})
                if user_data:
                    if 'user_type' not in user_data:
                        is_login = False
                        continue

                    if user_data['user_type'] not in self.auth[0]:
                        is_auth = False
                        continue

                    # 判断是否开始平台化,如果未开始,执行店铺检查
                    is_platform = self.properties.get('base', 'IS_PLATFORM')
                    if is_platform == 'False' and str(
                            user_data.get('shop_id', '0')) != str(
                                self.params('shop_id')):
                        is_login = False
                        continue
                    is_login = True
                    is_auth = True
                    break
                else:
                    is_login = False
                    continue

            elif group == 'admin' or group == 'seller':
                # 商户
                user_data = user_data_dict.get('seller', {})
                if not user_data:
                    is_login = False
                    continue

                if 'user_type' not in user_data:
                    is_login = False
                    continue
                if user_data['user_type'] not in self.auth[0]:
                    is_auth = False
                    continue

                check_power_result = yield self.__check_power(
                    user_data, no_check_control)
                if not check_power_result:
                    raise self._gr(False)
                is_login = True
                is_auth = True
                break

            elif group == 'platform':
                # 三方平台
                user_data = yield self.sign_auth_platform()
                if not user_data:
                    is_auth = False
                    continue
                if 'user_type' not in user_data:
                    is_login = False
                    continue
                if user_data['user_type'] not in self.auth[0]:
                    is_auth = False
                    continue

                self.user_data = user_data
                is_login = True
                is_auth = True
                break
            else:
                is_auth_error = True
                self.logger.exception('auth error')
                break

        if is_auth_error:
            self.error_out(self._e('AUTH_SET_ERROR'))
            raise self._gr(False)

        if not is_login:
            self.error_out(self._e('NOT_LOGIN'))
            raise self._gr(False)

        if not is_auth:
            self.error_out(self._e('AUTH_ERROR'))
            raise self._gr(False)

        raise self._gr(True)

    @tornado.gen.coroutine
    def __get_login_user_data(self):
        """
        获取用户的登录信息
        :return:
        """
        result = {}
        # 买家
        buyer_token = self.params('buyer_token') if self.params(
            'buyer_token') else self.get_cookie('buyer_token')
        if buyer_token:
            cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(buyer_token)
            user_data = yield self.redis.hgetall(cache_key)
            self.buyer_user_data = user_data
            result['buyer'] = user_data

        # 商户
        sign = self.params('sign')
        if sign:
            sign_token = yield self.sign_login()
            if not sign_token:
                token = self.params('token') if self.params(
                    'token') else self.get_cookie('token')
            else:
                token = sign_token
        else:
            token = self.params('token')
            if not token:
                token = self.get_cookie('token')

        if token:
            cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
            user_data = yield self.redis.hgetall(cache_key)
            self.user_data = user_data
            result['seller'] = user_data

        raise self._gr(result)

    @tornado.gen.coroutine
    def __check_power(self, user_data, no_check_control):
        """
        检查权限
        :param user_data:
        :param no_check_control:
        :return:
        """
        # 1 获取店铺权限
        # 2 group_id=0 超级管理员,查看用户请求power是否符合店铺权限
        # 3 group_id>0 普通管理员,查看用户请求power是否符合普通用户权限(shop_id)
        if not no_check_control:
            # 获取前端请求uri,替换api全段字段,用户请求权限
            base_url_prefix = self.properties.get('base', 'BASE_URL_PREFIX')\
                .replace('BASE_URL_PREFIX=', '').replace('\n', '')
            power = self.request.uri.replace(base_url_prefix, '')
            if 'group_id' in user_data and int(user_data['group_id']) >= 0:
                auth_error_flag = True

                # 管理员menu(每个用户真正的权限树,不管是超级管理员,还是普通管理员)
                menu_params = {
                    'shop_id': user_data['shop_id'],
                    'group_id': user_data['group_id'],
                }
                menu_result = yield self.do_service('user.auth.menu.service',
                                                    'query_menu',
                                                    params=menu_params)
                if menu_result['code'] != 0:
                    raise self._gr(menu_result)
                shop_power = self.get_path(menu_result['data'])

                # 检查请求url的power是否匹配用户权限树shop_power
                for power_tree in shop_power:
                    # 用shop_power 匹配 power
                    # shop_power: /user/auth/power
                    # power: /user/auth/power/query
                    pattern = re.compile(power_tree)
                    if pattern.match(power):
                        auth_error_flag = False
                        break
                # 检查权限
                if auth_error_flag:
                    self.error_out(self._e('AUTH_ERROR'))
                    raise self._gr(False)
            else:
                self.error_out(self._e('AUTH_ERROR'))
                raise self._gr(False)

        raise self._gr(True)

    @tornado.gen.coroutine
    def create_token(self, params, user_type, expire=None):
        """
        创建token和cookie
        :param params:
        :param user_type:
        :param expire:
        :return:
        """
        if not user_type:
            raise self._gr({'code': -1, 'msg': ''})

        # 处理domain
        request = self.request
        host = request.host
        host_port = host.split(':')
        hosts = host_port[0].split('.')

        if self.properties.get('domain', 'base'):
            domain_base = self.properties.get('domain', 'base')
        else:
            domain_base = '.'.join(hosts[-2:])

        # 根据用户类型,生成缓存KEY
        if user_type == 'admin':
            token = self.cache_key_pre.ADMIN_TOKEN + self.salt(salt_len=32)
            cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
            expire = expire if expire else int(
                self.properties.get('expire', 'ADMIN_EXPIRE'))
            cookie_key = 'token'
            params['user_type'] = self.constants.ADMIN_TYPE
        elif user_type == 'buyer':
            token = self.cache_key_pre.BUYER_TOKEN + self.salt(salt_len=32)
            cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(token)
            expire = expire if expire else int(
                self.properties.get('expire', 'BUYER_EXPIRE'))
            cookie_key = 'buyer_token'
            params['user_type'] = self.constants.BUYER_TYPE
        else:
            raise self._gr({'code': -1, 'msg': ''})

        # 创建缓存
        yield self.redis.hmset(cache_key, params)

        # 设置cookie
        if 'remember' in params and params['remember'] == '1':
            yield self.redis.expire(
                cache_key,
                int(self.properties.get('expire', 'ADMIN_EXPIRE_REMEMBER')))
            self.set_cookie(
                cookie_key,
                token,
                expires=time.time() +
                int(self.properties.get('expire', 'ADMIN_EXPIRE_REMEMBER')),
                domain=domain_base)
        else:
            yield self.redis.expire(cache_key, expire)
            self.set_cookie(cookie_key, token, domain=domain_base)

        raise self._gr({'code': 0, 'token': token})

    @tornado.gen.coroutine
    def refresh_token(self):
        """
        刷新token
        :return:
        """
        auth = self.auth
        # 如果没有设置权限,返回
        if not auth or not auth[0]:
            raise self._gr(True)

        power_group = auth[0]
        for group in power_group:
            if group == 'buyer':
                # 买家
                buyer_token = self.params('buyer_token')
                if not buyer_token:
                    buyer_token = self.get_cookie('buyer_token')

                if not buyer_token:
                    continue

                cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(
                    buyer_token)
                expire = int(self.properties.get('expire', 'BUYER_EXPIRE'))
                refresh_expire = int(
                    self.properties.get('expire', 'BUYER_REFRESH_EXPIRE'))

                self.__refresh_token_update(cache_key, expire, refresh_expire)

            elif group == 'admin' or group == 'seller':
                token = self.params('token')
                if not token:
                    token = self.get_cookie('token')

                if not token:
                    continue

                if self.params('sign'):
                    shop_id = self.params('shop_id')
                    token = 'sign:' + shop_id

                cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
                expire = int(self.properties.get('expire', 'ADMIN_EXPIRE'))
                refresh_expire = int(
                    self.properties.get('expire', 'ADMIN_REFRESH_EXPIRE'))

                self.__refresh_token_update(cache_key, expire, refresh_expire)

    @tornado.gen.coroutine
    def __refresh_token_update(self, cache_key, expire, refresh_expire):
        """
        更新token有效期
        :param cache_key:
        :param expire:
        :param refresh_expire:
        :return:
        """
        if cache_key and expire and refresh_expire:
            cache_data = yield self.redis.ttl(cache_key)
            if cache_data:
                left_seconds = int(cache_data)
                # 获取用户登录数据
                # self.user_data = yield self.redis.hgetall(cache_key)
                if (expire - left_seconds) >= refresh_expire:
                    # 如果token的总生命秒数 - 剩余生命秒数 >= 刷新秒数,则重新设置token的生命秒数
                    yield self.redis.expire(cache_key, expire)

    @tornado.gen.coroutine
    def sign_login(self):
        """
        签名登录
            1.验签
            2.验签通过,检查缓存是否有值 ,有值 直接返回真
            3.如果没值,生成缓存
        :return:
        """
        # 验签
        sign = self.params('sign')
        sing_result = yield self.do_service('user.auth.sign.service',
                                            'sign_login', self.params())
        if sing_result['code'] != 0:
            raise self._gr(False)

        # 检查缓存是否有值
        shop_id = self.params('shop_id')
        token = 'sign:' + shop_id
        cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(token)
        user_data = yield self.redis.hgetall(cache_key)
        if user_data:
            raise self._gr(token)

        # 创建缓存
        yield self.redis.hmset(
            cache_key, {
                'shop_id': shop_id,
                'user_type': self.constants.SELLER_TYPE,
                'admin_id': -1,
                'group_id': 0
            })

        # 设置cookie
        expire = int(self.properties.get('expire', 'ADMIN_EXPIRE'))
        yield self.redis.expire(cache_key, expire)

        raise self._gr(token)

    @tornado.gen.coroutine
    def sign_auth_platform(self):
        """
        平台授权认证
            1.检查token参数,如果有token,根据token获取缓存数据,没有token或缓存数据不存在,进行验签
            2.验签,检查sign参数,如果没有,返回授权失败,有,进行验签
            3.创建登录缓存,返回登录信息及token
        :return:
        """
        # 1.
        token = self.params('token')
        if token:
            cache_key = self.cache_key_pre.PLATFORM_TOKEN + token
            user_data = yield self.redis.hgetall(cache_key)
            if user_data:
                raise self._gr(user_data)

        # 2.
        # psign 为 platform 验签的 sign
        psign = self.params('psign')
        if not psign:
            raise self._gr(False)

        sing_result = yield self.do_service('user.auth.sign.service',
                                            'sign_auth_platform',
                                            self.params())
        if sing_result['code'] != 0:
            raise self._gr(False)

        # 3.
        app_id = self.params('app_id')
        token = self.md5('sign:' + app_id)
        cache_key = self.cache_key_pre.PLATFORM_TOKEN + token
        user_data = {
            'app_id': app_id,
            'user_type': self.constants.PLATFORM_TYPE,
            'token': token,
            'admin_id': -1,
            'shop_id': app_id
        }
        yield self.redis.hmset(cache_key, user_data)

        expire = int(self.properties.get('expire', 'ADMIN_EXPIRE'))
        yield self.redis.expire(cache_key, expire)

        raise self._gr(user_data)

    @tornado.gen.coroutine
    def get_user_data(self):
        user_data = None
        params = self.params()

        if self.get_cookie('buyer_token'):
            cache_key = self.cache_key_pre.BUYER_TOKEN + self.md5(
                self.get_cookie('buyer_token'))
            user_data = yield self.redis.hgetall(cache_key)

        elif self.get_cookie('token'):
            cache_key = self.cache_key_pre.ADMIN_TOKEN + self.md5(
                self.get_cookie('token'))
            user_data = yield self.redis.hgetall(cache_key)

        if 'sign' in params:
            user_data = yield self.sign_auth_platform()
        raise self._gr(user_data)

    def md5(self, text):
        """ 
        MD5加密
        @:param text 需加密字符串
        @return 加密后字符串
        """
        result = hashlib.md5(text.encode('utf-8'))
        return result.hexdigest()

    def create_uuid(self):
        """
        声称随机字符串
        :return: 
        """
        m = hashlib.md5()
        m.update(bytes(str(time.time()), encoding='utf-8'))
        return m.hexdigest()

    def sha1(self, text):
        """ 
        sha1 加密
        @:param text 需加密字符串
        @return 加密后字符串
        """
        return hashlib.sha1(text).hexdigest()

    def salt(self, salt_len=6, is_num=False):
        """ 
        密码加密字符串
        生成一个固定位数的随机字符串,包含0-9a-z
        @:param salt_len 生成字符串长度
        """

        if is_num:
            chrset = '0123456789'
        else:
            chrset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ'
        salt = []
        for i in range(salt_len):
            item = random.choice(chrset)
            salt.append(item)

        return ''.join(salt)

    def out(self, data):
        """ 
        输出结果
        :param data: 返回数据字典
        """
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(self.json.dumps(data, cls=CJsonEncoder))

    def error_out(self, error, data=''):
        """
        错误输出
        :param error: 错误信息对象
        :param data: 返回数据字典
        :return: 
        """
        out = error
        if data:
            out['data'] = data

        self.write(out)

    def clear_template_cache(self):
        """ 清除模板缓存
        """

        self._template_loaders.clear()

    @tornado.gen.coroutine
    def get(self):
        """
        重写父类get方法,接受GET请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    @tornado.gen.coroutine
    def post(self):
        """
        重写父类post方法,接受POST请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    @tornado.gen.coroutine
    def get_shop_host(self, host):
        """
        根据自定义域名/二级域名获取店铺ID
        规则:
            1. 检查访问无名是否为系统域名或其二级域名,是使用二级域名,不是使用自定义域名
            2. 根据二级域名或自定义域名获取店铺ID(有缓存策略)
            3. 将shop_id赋值给上下文对象
        :param host:
        :return:
        """
        is_use_domain = self.properties.get('domain', 'is_use')
        domain_base = self.properties.get('domain', 'base')

        if host and is_use_domain == 'True':
            site_domain = ''
            # 1
            if domain_base in host:
                # site_domain = host
                hosts = host.split('.')
                if len(hosts) > 1 and hosts[0] != 'www' and hosts[
                        0] != 'wxauth' and hosts[0] != 'api':
                    site_domain = hosts[0]
            else:
                # hosts = host.split('.')
                # if len(hosts) > 1 and hosts[0] != 'www' and hosts[0] != 'wxauth' and hosts[0] != 'api':
                #     site_domain = hosts[0]
                hosts = host.split(':')
                site_domain = hosts[0]

            if site_domain:
                # 2
                result = yield self.do_service('channel.shop.service',
                                               'query_shop_domain',
                                               {'domain': site_domain})
                if result and result['code'] == 0:
                    shop_id = result['data']['shop_id']
                    if shop_id:
                        self.shop_id = shop_id
                        # 给参数对象添加shop_id
                        # params = self.params()
                        # 3
                        self._params['shop_id'] = shop_id

    def do_service(self, service_path, method, params={}):
        """
        调用服务
        :param service_path: 
        :param method: 
        :param params: 
        :return: 
        """
        token = self.get_cookie('token')
        buyer_token = self.get_cookie('buyer_token')
        language = self.get_cookie('language')
        if not token:
            token = self.params('token')
        if not buyer_token:
            buyer_token = self.params('buyer_token')
        if not language:
            language = self.params('language')

        # 从application.settings导入power_tree
        power_tree = self.settings['power_tree']

        # params['token'] = token if token else ''
        # params['buyer_token'] = buyer_token if buyer_token else ''
        # params['language'] = language if language else 'cn'
        return serviceManager.do_service(service_path,
                                         method,
                                         params=params,
                                         version=config.CONF['version'],
                                         power=power_tree)

    def get_user_unique_code(self):
        """
        创建访问者唯一身份标识
        :return:
        """
        cookie_name = 'unique_code'
        unique_code = self.get_cookie(cookie_name)
        if not unique_code:
            unique_code = self.params('unique_code')

        if not unique_code:
            unique_code = self.salt(32)
            self.set_cookie(cookie_name, unique_code)

        return unique_code

    def _e(self, error_key):
        """
        :param error_key:
        :return: 
        """
        # language = self.get_cookie('language')
        # if not language:
        #     language = self.params('language')
        # language = language if language else 'cn'
        # language_module = self.importlib.import_module('language.' + language).Code
        data = {}
        for key in self.error_code[error_key]:
            data[key] = self.error_code[error_key][key]
        # if error_key in language_module:
        #     data['msg'] = language_module[error_key]

        return data

    def _gr(self, data):
        """
        tornado.gen.Return
        :param data: 数据
        :return:
        """
        return tornado.gen.Return(data)

    def params(self, key=''):
        """
        获取参数中指定key的数据
        :param key:
        :return:
        """
        if not key:
            return self._params
        elif key not in self._params:
            return ''
        else:
            return self._params[key]

    def get_user_agent(self):
        """
        获取用户访问数据
        :return:
        """
        request = self.request
        if 'Remote_ip' in request.headers and request.headers['Remote_ip']:
            ip = request.headers['Remote_ip']
        elif 'X-Forward-For' in request.headers and request.headers[
                'X-Forward-For']:
            ip = request.headers['X-Forward-For']
        else:
            ip = request.remote_ip

        cookies = ''
        if request.cookies:
            for k, v in request.cookies.items():
                cookies += k + '=' + v.value + ';'

        try:
            user_agent = request.headers['User-Agent']
        except Exception as e:
            user_agent = ''

        return {
            'user_unique_code': self.get_user_unique_code(),
            'remote_ip': ip,
            'user_agent': user_agent,
            'cookies': cookies
        }

    def get_path(self, data, power_path_list=None):
        """
        1 遍历用户权限树,如果有child,获得child的path,如果没有,返回power['path']
        2 递归的遍历child获得path,直到所有child为空
        3 将所有path加载到power_tree 列表中
        4 获取子路径
        :param data: 用户权限树
        :return:
        """
        if power_path_list is None:
            power_path_list = []
        for power in data:
            power_path_list.append(str(power['path']))
            if power['child']:
                self.get_path(power['child'], power_path_list)
            # else:
            #     power_path_list.append(str(power['path']))
        return power_path_list
Ejemplo n.º 13
0
class Base(Controller):

    json = json
    error_code = Code
    redis = RedisBase()
    user_data = {}
    auth = None
    _params = {}
    properties = Properties()
    logger = Logs().get_logger()

    @tornado.gen.coroutine
    def prepare(self):
        if self.auth:
            if self.auth[0] is not None:
                # 如果控制器需要登录, 则进行登录检查
                token = self.get_cookie('token')
                self.user_data = self.redis.hgetall(token)
                if not self.user_data:
                    self.error_out(self._e('NOT_LOGIN'))
                    self.finish()

    def out(self, data):
        """ 
        输出结果
        :param data: 返回数据字典
        """
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(self.json.dumps(data, cls=CJsonEncoder))

    def error_out(self, error, data=''):
        """
        错误输出
        :param error: 错误信息对象
        :param data: 返回数据字典
        :return: 
        """
        out = error
        if data:
            out['data'] = data

        self.write(out)

    def create_token(self, params):
        """
        登录成功, 写token
        :param params: 
        :return: 
        """
        token = self.salt()
        expire_time = int(self.properties.get('expire', 'USER_EXPIRE'))
        self.redis.hmset(token, params, expire_time)
        self.set_cookie('token', token, expires=int(time.time()) + expire_time)

    def salt(self, salt_len=6, is_num=False):
        """ 
        密码加密字符串
        生成一个固定位数的随机字符串,包含0-9a-z
        @:param salt_len 生成字符串长度
        """

        if is_num:
            chrset = '0123456789'
        else:
            chrset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ'
        salt = []
        for i in range(salt_len):
            item = random.choice(chrset)
            salt.append(item)

        return ''.join(salt)

    @tornado.gen.coroutine
    def get(self):
        """
        重写父类get方法,接受GET请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    @tornado.gen.coroutine
    def post(self):
        """
        重写父类post方法,接受POST请求
        如果执行到此方法,说明请求类型错误
        """
        self.error_out(self._e('REQUEST_TYPE_ERROR'))

    def _e(self, code):
        """
        返回错误码
        :param code: 
        :return: 
        """
        return self.error_code[code]

    def _gre(self, data):
        """
        tornado.gen.Return
        :param data: 数据
        :return: 
        """
        return tornado.gen.Return(self._e(data))

    def do_service(self, service_path, method, params={}):
        """
        调用服务
        :param service_path: 
        :param method: 
        :param params: 
        :return: 
        """
        return serviceManager.do_service(service_path,
                                         method,
                                         params=params,
                                         version=config.CONF['version'])

    def params(self, key=''):
        """
        获取参数中指定key的数据
        :param key:
        :return:
        """
        if not key:
            return self.get_params()
        elif key not in self.get_params():
            return ''
        else:
            return self.get_params(key)
Ejemplo n.º 14
0
class Controller(tornado.web.RequestHandler):
    """ 
    基类
    """
    controllerKey = ''  # controller对应的key
    user_type = None
    config = None
    view_data = {}  # 模板输出数据
    model = None
    _GET = False
    _POST = False
    view_path = ''
    escape = tornado.escape
    version = ''
    importlib = importlib
    logger = Logs().logger

    def initialize(self):
        """
        初始化
        :return: 
        """
        # self.view_path = self.config['VIEW_PATH']

    def on_finish(self):
        """
        """
        # self.model.__del__()
        pass

    @tornado.gen.coroutine
    def display(self, view_name, view_path=''):
        """ 
        输出模板
        调用模板输出,使用当前类名为模板目录
        @params viewName string 调用模板名称
        @params data dict 输出数据
        """

        view_path = view_path if view_path else self.view_path

        if not self.config['debug']:
            try:
                self.render("%s/%s/%s.html" %
                            (view_path, self.__class__.__name__, view_name),
                            controller=self.__class__.__name__,
                            **self.view_data)
            except Exception as e:
                self.logger.exception(e)
                self.redirect('/700')
                return
        else:
            self.render("%s/%s/%s.html" %
                        (view_path, self.__class__.__name__, view_name),
                        controller=self.__class__.__name__,
                        **self.view_data)

    def get_params(self, key=""):
        """ 
        获取请求参数
        如果只有一个值,将其转为字符串,如果是list,保留list类型
        @:param key 参数名称
        @:param data_type 返回数据类型,默认
        """
        if not key:
            result = {}
            data = self.request.arguments
            for (k, v) in data.items():
                if len(v) > 1:
                    value_strip = []
                    for item in v:
                        value_strip.append(item.strip())
                    result[k] = value_strip
                else:
                    result[k] = v[0].strip().decode('utf-8')
            return result
        else:
            try:
                value = self.request.arguments[key]
                if len(value) > 1:
                    value_strip = []
                    for item in value:
                        value_strip.append(item.strip())
                    return value_strip
                else:
                    return value[0].strip().decode('utf-8')
            except Exception as e:
                return ''

    def import_model(self, model_name):
        """ 
        加载类
        @:param model_name 类名
        @:param model_dir 目录
        """

        try:
            model = importlib.import_module(self.version + '.model.' +
                                            model_name)
            return model.Model(self.model)
        except Exception as e:
            self.logger.exception(e)
            return None

    def import_service(self, service_name):
        """ 
        加载服务类
        @params service_name 服务类名
        @params service_dir 服务类所在目录
        """

        try:
            service = importlib.import_module(self.version + '.service.' +
                                              service_name)
            return service.Service()
        except Exception as e:
            self.logger.exception(e)
            return None

    def write_error(self, status_code, **kwargs):
        """
        复写方法
        :param status_code:
        :param kwargs:
        :return:
        """
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write({
            'code': -status_code,
            'msg': '服务错误,请联系管理员',
            'traceback': kwargs['traceback_error']
        })
        self.finish()

    def send_error(self, status_code=500, **kwargs):
        """
        复写方法
        :param status_code:
        :param kwargs:
        :return:
        """
        if self._headers_written:
            # gen_log.error("Cannot send error response after headers written")
            self.logger.info(
                'Cannot send error response after headers written')
            if not self._finished:
                self.finish()
            return
        self.clear()

        if 'exc_info' in kwargs:
            kwargs['traceback_error'] = traceback.format_exc()
        self.set_status(status_code)
        try:
            self.write_error(status_code, **kwargs)
        except Exception as e:
            self.logger.exception(e)

        if not self._finished:
            self.finish()