Commit 1aea32a6 by 姚主播

Initial commit

parents
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
.static_storage/
.media/
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# idea
.idea/
\ No newline at end of file
# back_base
python back base
### 使用时,将back_base项目文件关联到新项目的base文件夹(作为子模块)
# coding: utf-8
import os
import socket
import sys
MACHINE_NAME = socket.gethostname()
def current_path():
path = os.path.realpath(sys.path[0])
if os.path.isfile(path):
path = os.path.dirname(path)
return os.path.abspath(path)
else:
import inspect
caller_file = inspect.stack()[1][1]
return os.path.abspath(os.path.dirname(caller_file))
ROOT_PATH = os.path.dirname(os.path.dirname(current_path()))
# 只加载某几个模块,为空则全部加载
LOAD_MODULE = []
# 不加载哪几个模块
REJECT_MODULE = []
BUSINESS_REDIS = {
"host": "localhost",
"port": 6379,
"db": 1,
}
# =================
# tornado资源配置
settings = {
"cookie_secret": "e446976943b4e8442f099fed1f3fea28462d5832f483a0ed9a3d5d3859f==08d",
"session_secret": "3cdcb1f00803b6e78ab50b466a40b9977db396840c28307f428b25e2277f0bcc",
"session_timeout": 60 * 30 * 2 * 24 * 30,
"store_options": {
'redis_host': BUSINESS_REDIS["host"],
'redis_port': BUSINESS_REDIS["port"],
'redis_db': '0',
},
"static_path": os.path.join(ROOT_PATH, "static"),
"template_path": os.path.join(ROOT_PATH, "templates"),
"gzip": True,
"debug": False,
}
# 日志路径设置
LOGFILE = ''
# 消息服务器
MSG_HOST = 'http://msg.kfw.net'
# =================
# 数据库连接装载
BASE_DB = "test"
SPATIAL_DB = "kfw_spatial"
# 单库
database = {
BASE_DB: {
'engine': 'mysql',
'db': 'test',
'host': '123.206.26.57',
'port': 3306,
'user': 'kfw',
'passwd': 'kfw123',
'charset': 'utf8mb4',
'conn': 5
}
}
# 主从分离
'''
DATABASE = {
'master':{
'test': {
'engine': 'mysql',
'db': 'db_name',
'host': 'localhost',
'port': 3306,
'user': 'bozyao',
'passwd': 'bozyao',
'charset': 'utf8mb4',
'conn': 20
},
'slave':[
'test': {
'engine': 'mysql',
'db': 'db_name',
'host': 'localhost',
'port': 3306,
'user': 'bozyao',
'passwd': 'bozyao',
'charset': 'utf8mb4',
'conn': 20
},
]
}
'''
# coding: utf-8
class GeneralError(Exception):
def __init__(self, error_msg):
super(GeneralError, self).__init__()
self.error_msg = error_msg
def __str__(self):
return self.error_msg
if __name__ == "__main__":
try:
raise GeneralError('客户异常')
except Exception as e:
print(e)
# coding: utf-8
# ::::::::::::::::::
# 错误信息及code列表
ERROR_CODE = {
# 第三方或者其他服务错误
"DBERR" : "2000",
"THIRDERR" : "2001",
"DATAERR" : "2003",
"IOERR" : "2004",
"REDISERR" : "2005",
"SERVERERR" : "2006",
# 返回内容错误
"NODATA" : "2300",
"DATAEXIST" : "2301",
"CONTENTERR" : "2302",
"NOT_FOUND" : "404",
# 未知错误
"UNKOWNERR" : "2400",
# 参数错误
"PARAMERR" : "2401",
# User 相关
"SESSIONERR" : "2100",
"USERERR" : "2102",
"ROLEERR" : "2103",
"PWDERR" : "2104",
"BALANCEERR" : "2110",
# 验证失败
"VERIFYERR" : "2105",
}
ERROR_MSG = {
# 第三方或者其他服务错误
"DBERR" : "数据库查询错误",
"THIRDERR" : "第三方系统错误",
"DATAERR" : "数据错误",
"IOERR" : "文件读写错误",
"REDISERR" : "REDIS错误",
"SERVERERR" : "内部错误",
# 返回内容错误
"NODATA" : "无数据",
"DATAEXIST" : "数据已存在",
"CONTENTERR" : "内容错误",
"NOT_FOUND" : "未知请求",
# 未知错误
"UNKOWNERR" : "未知错误",
# 参数错误
"PARAMERR" : "参数错误",
# User 相关
"SESSIONERR" : "未登录",
"USERERR" : "用户不存在",
"ROLEERR" : "用户身份错误",
"PWDERR" : "密码错误",
"BALANCEERR" : "钱包账号余额不足",
# 验证失败
"VERIFYERR" : "验证码错误",
}
ERROR_MSG_CODE = {
# 第三方或者其他服务错误
"数据库查询错误" : "2000",
"第三方系统错误" : "2001",
"数据错误" : "2003",
"文件读写错误" : "2004",
"REDIS错误" : "2005",
"内部错误" : "2006",
# 返回内容错误
"无数据" : "2300",
"数据已存在" : "2301",
"内容错误" : "2302",
"未知请求" : "404",
# 未知错误
"未知错误" : "2400",
# 参数错误
"参数错误" : "2401",
# User 相关
"未登录" : "2100",
"用户不存在" : "2102",
"用户身份错误" : "2103",
"密码错误" : "2104",
"钱包账号余额不足" : "2110",
# 验证失败
"验证码错误" : "2105",
}
#coding: utf-8
__author__ = 'yaobo'
def check_format(email):
import re
ret = re.findall('^[^@]{2,}@[\w\d]{2,}\.[\w]{2,}$', email)
return ret
if __name__ == "__main__":
print(check_format("afbd@dd"))
print(check_format("sdnv@dd.co"))
\ No newline at end of file
# coding: utf-8
# __author__ = 'bozyao'
import hashlib
import hmac
import json
import logging
import uuid
from datetime import datetime, date
import redis
def format_date(obj):
"""json dumps时使用的输出格式(暂时先这两个,以后可以加入,如自定义的对象)
@param obj: 需要转换的对象
@return: 转换后的样子
"""
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
if isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
class SessionData(dict):
def __init__(self, session_id, hmac_key):
self.session_id = session_id
self.hmac_key = hmac_key
class Session(SessionData):
def __init__(self, session_manager, request_handler):
self.session_manager = session_manager
self.request_handler = request_handler
try:
current_session = session_manager.get(request_handler)
except InvalidSessionException:
current_session = session_manager.get()
for key, data in current_session.items():
self[key] = data
self.session_id = current_session.session_id
self.hmac_key = current_session.hmac_key
def save(self, raw_data):
if not isinstance(raw_data, dict):
return
for key, data in raw_data.items():
self[key] = data
self.session_manager.set(self, self.request_handler)
return self.session_id
def remove(self):
self.session_manager.remove(self)
def get_all(self):
return self.session_manager.get_all()
class SessionManager(object):
def __init__(self, secret, store_options, session_timeout, m_db=None):
self.secret = secret
self.session_timeout = session_timeout
self.m_db = m_db
try:
self.redis = redis.StrictRedis(host=store_options['redis_host'],
port=store_options['redis_port'],
db=store_options['redis_db'])
except Exception as e:
print(e)
logging.error("Session redis connect error! %s" % e)
def _fetch(self, session_id):
try:
session_data = raw_data = self.redis.get(session_id)
# if not raw_data:
# session_data = raw_data = self.get_m_db_data(session_id)
if raw_data:
# self.redis.set(session_id, raw_data)
self.redis.setex(session_id, self.session_timeout, raw_data)
try:
session_data = json.loads(raw_data)
except:
session_data = {}
if isinstance(session_data, dict):
return session_data
else:
return {}
except IOError:
return {}
def get_session_id(self, request_handler, session_key="sid"):
session_id = request_handler.get_cookie(session_key, "")
return session_id
def _gen_session(self):
session_id = self._generate_id()
hmac_key = self._generate_hmac(session_id)
def get(self, request_handler=None):
if not request_handler:
session_id = None
hmac_key = ''
else:
session_id = self.get_session_id(request_handler)
hmac_key = request_handler.get_secure_cookie("verification")
# hmac_key = ''
if not session_id:
session_exists = False
session_id = self._generate_id()
hmac_key = self._generate_hmac(session_id)
# hmac_key = ''
else:
session_exists = True
check_hmac = self._generate_hmac(session_id)
if hmac_key != check_hmac:
raise InvalidSessionException()
session = SessionData(session_id, hmac_key)
if session_exists:
session_data = self._fetch(session_id)
for key, data in session_data.items():
session[key] = data
return session
def set(self, session, request_handler=None, session_key="sid"):
request_handler.set_cookie(session_key, session.session_id)
request_handler.set_secure_cookie("verification", session.hmac_key)
session_dict = dict(session.items())
session_data = json.dumps(session_dict, default=format_date)
self.set_m_db_data(session.session_id, session_data)
if 'user_id' in session_dict:
s_k = 's%s' % session_dict['user_id']
if not self.redis.sismember(s_k, session.session_id):
c = self.redis.scard(s_k)
while c >= 20:
self.redis.delete(self.redis.spop(s_k))
c -= 1
self.redis.sadd(s_k, session.session_id)
self.redis.setex(session.session_id, self.session_timeout, session_data)
def clear(self, user_id):
s_k = 's%s' % user_id
session_set = self.redis.smembers(s_k)
if not session_set:
return
for session_id in session_set:
self.redis.delete(session_id)
return len(session_set)
def remove(self, session):
# self.rm_m_db_data(session.session_id)
if 'user_id' in session:
s_k = 's%s' % session['user_id']
self.redis.srem(s_k, session.session_id)
self.redis.delete(session.session_id)
def get_all(self):
return len(self.redis.keys())
def _generate_id(self):
# new_id = hashlib.sha256(self.secret + str(uuid.uuid4()))
new_id = hashlib.sha1((self.secret + str(uuid.uuid4())).encode("utf8"))
return new_id.hexdigest()
def _generate_hmac(self, session_id):
return hmac.new(session_id, self.secret, hashlib.sha256).hexdigest()
def set_m_db_data(self, k, v):
if not self.m_db:
return 0
if not v:
return 0
# data = self.m_db.get("select * from user_session where sid = '%s'" % k)
data = self.get_m_db_data(k)
if data:
flag = self.m_db.execute("update user_session set vl = '%s' where sid = '%s'" % (v, k))
else:
flag = self.m_db.insert("user_session", {
"sid": k,
"vl": v
})
return flag
def get_m_db_data(self, k):
if not self.m_db:
return None
sql = "select vl from user_session where sid = '%s'" % k
data = self.m_db.get(sql)
if data:
data = data["vl"]
return data
def rm_m_db_data(self, k):
if not self.m_db:
return 0
return self.m_db.execute("delete from user_session where sid='%s'" % k)
class InvalidSessionException(Exception):
pass
# coding=utf-8
# __author__ = 'yaobo'
import inspect
import os
import random
import sys
_letter_cases = "abcdefhjkmnpqrtuvwxy" # 小写字母,去除可能干扰的i,l,o,z, g, s
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers))
def current_path():
path = os.path.realpath(sys.path[0])
if os.path.isfile(path):
path = os.path.dirname(path)
return os.path.abspath(path)
else:
caller_file = inspect.stack()[1][1]
return os.path.abspath(os.path.dirname(caller_file))
cur_path = current_path()
def create_validate_code(size=(120, 30),
chars=init_chars,
img_type="GIF",
mode="RGB",
bg_color=(255, 255, 255),
fg_color=(0, 0, 125),
font_size=20,
font_type="fb.ttf",
length=4,
draw_lines=True,
n_line=(1, 5),
draw_points=True,
point_chance=4):
"""
@todo: 生成验证码图片
@param size: 图片的大小,格式(宽,高),默认为(120, 30)
@param chars: 允许的字符集合,格式字符串
@param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
@param mode: 图片模式,默认为RGB
@param bg_color: 背景颜色,默认为白色
@param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
@param font_size: 验证码字体大小
@param font_type: 验证码字体
@param length: 验证码字符个数
@param draw_lines: 是否划干扰线
@param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
@param draw_points: 是否画干扰点
@param point_chance: 干扰点出现的概率,大小范围[0, 100]
@return: [0]: PIL Image实例
@return: [1]: 验证码图片中的字符串
"""
from PIL import Image, ImageDraw, ImageFont, ImageFilter
width, height = size # 宽, 高
img = Image.new(mode, size, bg_color) # 创建图形
draw = ImageDraw.Draw(img) # 创建画笔
def get_chars():
"""生成给定长度的字符串,返回列表格式"""
return random.sample(chars, length)
def create_lines():
"""绘制干扰线"""
line_num = random.randint(*n_line) # 干扰线条数
for i in range(line_num):
# 起始点
begin = (random.randint(0, size[0]), random.randint(0, size[1]))
# 结束点
end = (random.randint(0, size[0]), random.randint(0, size[1]))
draw.line([begin, end], fill=(0, 0, 0))
def create_points():
"""绘制干扰点"""
chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
for w in xrange(width):
for h in xrange(height):
tmp = random.randint(0, 100)
if tmp > 100 - chance:
draw.point((w, h), fill=(0, 0, 0))
def create_strs():
"""绘制验证码字符"""
c_chars = get_chars()
strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开
font = ImageFont.truetype(os.path.join(cur_path, font_type), font_size)
font_width, font_height = font.getsize(strs)
draw.text(((width - font_width) / 3, (height - font_height) / 3),
strs, font=font, fill=fg_color)
return ''.join(c_chars)
if draw_lines:
create_lines()
if draw_points:
create_points()
strs = create_strs()
# 图形扭曲参数
params = [1 - float(random.randint(1, 2)) / 100,
0,
0,
0,
1 - float(random.randint(1, 10)) / 100,
float(random.randint(1, 2)) / 500,
0.001,
float(random.randint(1, 2)) / 500
]
img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大)
return img, strs
if __name__ == "__main__":
code_img = create_validate_code()[0]
code_img.save("validate.gif", "GIF")
# coding: utf-8
import json
import redis
import time
import copy
import datetime
import types
import random
import logging
try:
from conf.settings import BUSINESS_REDIS
logging.info("Redis config by local......")
except ImportError:
from base_conf.settings import BUSINESS_REDIS
logging.info("Redis config by base......")
class BaseCache(object):
def __init__(self, db=BUSINESS_REDIS['db'], host=BUSINESS_REDIS['host'], port=BUSINESS_REDIS['port'], kc={}):
"""
初始化redis对象r, 初始化配置信息kc(keys_config), 例如:
'cache_1':{
'db':0, #使用数据库,非必须参数,默认为参数db值
'key':'%s_key1', #实际存储key
'type':'str', #存储类型
'timeout':86400, #超时时间
'postpone':0, #读取数据时,是否顺延timeout,0=不顺延,1=顺延,非必须参数,默认为0
'random':43200, #写入数据时,timeout随机添加0-43200,防止批量刷新缓存后,同时失效,非必须参数,默认为0
}
"""
self.db = db
self.r = redis.StrictRedis(host=host, port=port, db=db)
self.kc = kc
def get_conf(self, ckey, rkey, charset='utf-8'):
"""
@param ckey: 配置文件的key
@return: 返回相应配置
"""
if not ckey:
return None
tmp_kc = copy.deepcopy(self.kc)
# 不允许存在无过期时间的数据
if ckey not in tmp_kc or 'timeout' not in tmp_kc[ckey] or 'key' not in tmp_kc[ckey]:
return None
# 处理rkey
if '%' in tmp_kc[ckey]['key']:
if not rkey:
return None
if isinstance(rkey, types.UnicodeType):
rkey = rkey.encode(charset, 'ignore')
tmp_kc[ckey]['key'] = tmp_kc[ckey]['key'] % rkey
# 处理timeout
if tmp_kc[ckey].get('random', 0):
tmp_kc[ckey]['timeout'] = tmp_kc[ckey]['timeout'] + random.randint(0, tmp_kc[ckey].get('random', 0))
# 切换数据库
if 'db' in tmp_kc[ckey] and tmp_kc[ckey]['db'] != self.db:
self.r.select(tmp_kc[ckey]['db'])
return tmp_kc[ckey]
def str2dict(self, val):
"""
@param val: 数据字符串
@return: 数据字典
"""
return json.loads(val)
def dict2str(self, val):
"""
@param val: 数据字典
@return: 数据字符串
"""
if isinstance(val, dict):
for k, v in val.items():
if isinstance(v, datetime.datetime):
val[k] = v.strftime("%Y-%m-%d %H:%M:%S")
return json.dumps(val)
else:
return val
def set(self, ckey, value, rkey='', charset='utf-8'):
"""
@param ckey: 配置文件key
@param rkey: 写入redis数据的key
@param value: 要写入redis的数据
@return: 成功与否
"""
c = self.get_conf(ckey, rkey)
if not c:
return
k = c['key']
t = c['type']
# 写入数据为空时,删除已有key
if not value and self.r.exists(k):
self.r.delete(k)
return True
if t == 'str':
value = self.dict2str(value)
self.r.set(k, value)
elif t == 'hash':
self.r.hmset(k, value)
elif t == 'list':
if isinstance(value, (types.TupleType, types.ListType)):
for d in value:
self.r.rpush(k, d)
else:
self.r.rpush(k, value)
elif t == 'set':
if isinstance(value, (types.TupleType, types.ListType)):
for d in value:
redis['write'].sadd(k, d)
else:
redis['write'].sadd(k, value)
elif t == 'sortedset':
self.r.zadd(k, value, int(time.time()))
if self.r.exists(k):
self.r.expire(k, c['timeout'])
return True
def get(self, ckey, rkey, ext={}, charset='utf-8'):
"""
@param ckey: 配置文件key
@param rkey: 写入redis数据的key
@return: 读取的值
"""
c = self.get_conf(ckey, rkey)
if not c:
return
k = c['key']
t = c['type']
if c['postpone'] and self.r.exists(k):
self.r.expire(k, c['timeout'])
s = ext.get('min', 0)
e = ext.get('max', -1)
if t == 'str':
return self.str2dict(self.r.get(k))
elif t == 'hash':
return self.r.hgetall(k)
elif t == 'list':
return self.r.lrange(k, s, e)
elif t == 'set':
return self.smembers(k)
elif t == 'sortedset':
return self.r.zrangebyscore(k, s, e, withscores=True)
return
def refresh(self, ckey, value, rkey, charset='utf-8'):
""" 重刷rkey的数据
@param ckey: 配置文件key
@param rkey: 写入redis数据的key
@return: 成功与否
"""
c = self.get_conf(ckey, rkey)
if not c:
return
if self.r.exists(k):
self.r.delete(k)
return self.set(ckey, value, rkey, charset)
if __name__ == "__main__":
pass
# coding: utf-8
import importlib
import logging
import os
import socket
import sys
import time
import tornado.httpserver
import tornado.ioloop
import tornado.web
from logging.handlers import TimedRotatingFileHandler
from tornado.options import define, options
from .base_lib.app_route import Application, URL_PREFIX
path = os.path.dirname(os.path.abspath(__file__))
if path not in sys.path:
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
socket.setdefaulttimeout(10)
default_encoding = 'utf-8'
if sys.getdefaultencoding() != default_encoding:
reload(sys)
sys.setdefaultencoding(default_encoding)
try:
print("Load local setting...")
new_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
new_path = os.path.dirname(new_path)
if new_path not in sys.path:
sys.path.append(new_path)
from conf.settings import settings, LOAD_MODULE, REJECT_MODULE, LOGFILE
except ImportError as e:
print(e)
print("Load local setting error, load base settings...")
from base_conf.settings import settings, LOAD_MODULE, REJECT_MODULE, LOGFILE
class MyHandler(TimedRotatingFileHandler):
def __init__(self, filename, when='MIDNIGHT', interval=1, backup_count=10, encoding=None, delay=False, utc=False):
self.delay = delay
self.bfn = filename
when = when.upper()
if when == 'M':
self.suffix = "%Y-%m-%d_%H-%M"
elif when == 'H':
self.suffix = "%Y-%m-%d_%H"
elif when == 'D' or when == 'MIDNIGHT':
self.suffix = "%Y-%m-%d"
else:
raise ValueError("Invalid rollover interval specified: %s" % when)
self.cfn = self.get_cfn()
TimedRotatingFileHandler.__init__(self, filename, when=when, interval=interval, backupCount=backup_count,
encoding=encoding, delay=delay, utc=utc)
def get_cfn(self):
return self.bfn + "." + time.strftime(self.suffix, time.localtime())
def doRollover(self):
if self.stream:
self.stream.close()
self.stream = None
cur_time = int(time.time())
dst_now = time.localtime(cur_time)[-1]
self.cfn = self.get_cfn()
if self.backupCount > 0:
for s in self.getFilesToDelete():
os.remove(s)
if not self.delay:
self.stream = self._open()
new_rollover_at = self.computeRollover(cur_time)
while new_rollover_at <= cur_time:
new_rollover_at = new_rollover_at + self.interval
if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
dst_at_rollover = time.localtime(new_rollover_at)[-1]
if dst_now != dst_at_rollover:
if not dst_now:
addend = -3600
else:
addend = 3600
new_rollover_at += addend
self.rolloverAt = new_rollover_at
def _open(self):
self.cfn = self.get_cfn()
if self.encoding is None:
stream = open(self.cfn, self.mode)
else:
import codecs
stream = codecs.open(self.current_file_name, self.mode, self.encoding)
if os.path.exists(self.bfn):
try:
os.remove(self.bfn)
except OSError:
pass
try:
os.symlink(self.cfn, self.bfn)
except OSError:
pass
return stream
def current_path(paths=sys.path[0]):
path = os.path.realpath(paths)
if os.path.isfile(path):
path = os.path.dirname(path)
return os.path.abspath(path)
else:
import inspect
caller_file = inspect.stack()[1][1]
return os.path.abspath(os.path.dirname(caller_file))
# 加载所有handler模块
def load_module(app, path):
logging.info("Load module path:%s" % path)
all_py = scan_dir(path)
# 循环获取所有py文件
for file_name in all_py:
i = file_name.replace(path, "")
mn = i[1:-3].replace("/", ".").replace("\\", ".")
# print file_name, i, mn, current_path(), __file__
m = importlib.import_module(mn)
# 获取有效的Handler类,方法名称
# 此处如果类名不是Handler结尾,会对自动生成url规则产生影响,暂限定
hd = [j for j in dir(m) if j[-7:] == "Handler" and j != 'RequestHandler' and j != 'Handler']
if hd:
if ((LOAD_MODULE and i in LOAD_MODULE) or not LOAD_MODULE) and i not in REJECT_MODULE:
logging.info("Load handler file: %s" % file_name)
app.load_handler_module(m)
else:
logging.info("Miss handler file: %s" % file_name)
return app
# 扫描目录,得到所有py文件
def scan_dir(path, hfs=[]):
fds = os.listdir(path)
for i in fds:
i = os.path.join(path, i)
if i[-3:] == ".py":
hfs.append(i)
elif os.path.isdir(i):
hfs = scan_dir(i, hfs)
return hfs
def config_logger(options):
import logging
# from tornado.options import options
if options.logging is None or options.logging.lower() == 'none':
return
logger = logging.getLogger()
logger.setLevel(getattr(logging, options.logging.upper()))
formatter = logging.Formatter(
fmt='%(asctime)s.%(msecs)03d %(levelname)1.1s %(process)5d:%(threadName)-7.7s '
'%(module)10.10s:%(lineno)04d $$ %(message)s',
datefmt='%y%m%d %H:%M:%S'
)
logger.handlers = []
if options.log_file_prefix:
print("Set logging config with file at %s" % options.log_file_prefix)
channel = MyHandler(filename=options.log_file_prefix, backup_count=30)
if logger.handlers:
del logger.handlers[:]
logger.addHandler(channel)
if options.log_to_stderr or (options.log_to_stderr is None and not logger.handlers):
print("Set logging config with stdout.")
channel = logging.StreamHandler()
logger.addHandler(channel)
if logger.handlers:
for l in logger.handlers:
l.setFormatter(formatter)
def run(path="", port=8800, url_prefix=URL_PREFIX, use_session=True, debug=False):
import base_lib.app_route
base_lib.app_route.URL_PREFIX = url_prefix
define("port", default=port, help="run on the given port", type=int)
if debug:
settings["debug"] = True
application = Application(None, **settings)
tornado.options.parse_command_line(final=True)
if LOGFILE and not options.log_file_prefix:
options.log_file_prefix = LOGFILE
if settings["debug"]:
options.logging = "DEBUG"
config_logger(options)
if not path:
path = current_path()
load_module(application, path)
http_server = tornado.httpserver.HTTPServer(application, xheaders=True)
from base_lib.tools import session
from base_lib.dbpool import acquire
if use_session:
sessiion_db = settings.get("session_db", "")
application.session_manager = session.SessionManager(
settings["session_secret"],
settings["store_options"],
settings["session_timeout"],
m_db=acquire(sessiion_db)
)
application.use_session = use_session
http_server.listen(options.port)
logging.info('Server start , debug: %s, port: %s' % (settings["debug"], options.port))
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
run()
# coding: utf-8
import json
import logging
import traceback
from datetime import datetime, date
try:
from conf.settings import database, BASE_DB, settings
logging.info("Data config by local......")
except ImportError:
from ..base_conf.settings import database, BASE_DB, settings
logging.info("Data config by base......")
from ..base_lib.dbpool import with_database_class, install
from ..base_lib import dbpool
if settings.get("debug", False):
logging.info("Running in debugging mode......")
dbpool.debug = True
install(database)
def format_date(obj):
"""
@todo: json dumps时使用的输出格式(暂时先这两个,以后可以加入,如自定义的对象)
@param obj: 需要转换的对象
@return: 转换后的样子
"""
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
if isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
# TODO 未考虑redis缓存数据
@with_database_class(BASE_DB)
class BaseModel:
def __init__(self):
"""
__table__: 实体表明
__fields__: 字段
"""
self.__table__ = ""
self.__fields__ = "*"
self.__id__ = "id"
# 考虑是否加入类型,默认值,范围等?
def get(self, key, value=""):
return self.real_dict().get(key, value)
def set(self, key, value=""):
self.__dict__[key] = value
def to_json(self, data=None):
"""输出有意义的属性json格式
@param data: 要转化的数据,默认为空,使用对象本身
@return: 属性json格式
"""
if not data:
data = self.real_dict()
return json.dumps(data, default=format_date)
def real_dict(self):
"""输出有意义的属性字典
@param:
@return: 属性字典
"""
data = self.__dict__.copy()
for key in list(data.keys()):
if key.find('__') == 0 or key == 'db':
data.pop(key)
return data
def load(self, json_data):
"""加载数据
@param json_data: dict数据
@return: 成功与否
"""
try:
# cur_keys = self.__fields__.replace(" ", "")
for key in json_data.keys():
# if key in cur_keys.split(","):
self.__dict__[key] = json_data[key]
return self
except Exception as e:
logging.error(e)
return None
def save(self):
"""保存自身,新增
@param:
@return: 成功与否
"""
if not self.__table__:
return 0
self.__id__ = "id"
try:
if self.real_dict().get(self.__id__, 0):
return self.update()
return self.db.insert(self.__table__, self.real_dict())
except:
logging.warning(traceback.format_exc())
# raise
return 0
def insert(self):
"""新增
@param:
@return: 成功与否
"""
if not self.__table__:
return 0
try:
return self.db.insert(self.__table__, self.real_dict())
except:
return 0
def update(self):
"""更新自身
@param:
@return: 成功与否
"""
self.__id__ = "id"
if not self.__table__ or not self.real_dict().get(self.__id__, 0):
return 0
try:
return self.db.update(self.__table__, self.real_dict(), {self.__id__: self.real_dict()[self.__id__]})
except:
return 0
def update_values(self, data, where=None):
"""批量更新
@param data: 要更新的键值对
@param where: 条件键值对,默认使用自己的id
@return: 成功与否
"""
if not self.__table__:
return 0
self.__id__ = "id"
if not where:
if self.real_dict().get(self.__id__, ""):
where = {self.__id__: self.real_dict()[self.__id__]}
else:
return 0
ret = 0
if data:
ret = self.db.update(self.__table__, data, where)
return ret
def delete_by_id(self, __id__):
"""通过id删除
@param __id__: id
@return: 成功与否
"""
if not self.__table__:
return 0
self.__id__ = "id"
ret = self.db.delete(self.__table__, {self.__id__: __id__})
return ret
def get_by_id(self, __id__):
"""通过id获取
@param __id__: id
@return: json数据结构 dict
"""
if not self.__table__:
return {}
self.__id__ = "id"
ret = self.db.select(self.__table__, {self.__id__: __id__}, self.__fields__)
if ret:
# return self.to_json(ret[0])
return ret[0]
return {}
def select(self, where={}, other='', fields=''):
"""自定义查询
@param where: dict键值对条件
@param other: 自定义的
@param fields: 查询字段
@return: dict数据结构 数组
"""
if not self.__table__:
return []
if not fields:
fields = self.__fields__
data = self.db.select(self.__table__, where, fields, other)
return data
def select_one(self, where={}, other='', fields=''):
"""自定义查询
@param where: dict键值对条件
@param other: 自定义的
@param fields: 查询字段
@return: dict数据结构 数组
"""
if not self.__table__:
return []
if not fields:
fields = self.__fields__
data = self.db.select_one(self.__table__, where, fields, other)
return data
def query(self, sql):
"""自定义SQL查询
@param sql: 直接sql查询
@return: dict数据结果(不一定和当前model结构对等)
"""
if not self.__table__:
return []
ret = self.db.query(sql)
return ret
def execute(self, sql):
"""自定义SQL执行
@param sql: 直接sql
@return: 执行结果
"""
if not self.__table__:
return []
ret = self.db.execute(sql)
return ret
def escape(self, s):
return self.db.escape(s)
def format_json_str_list(self, data=[]):
ret = []
for row in data:
ret.append(self.to_json(row))
return ret
def load_info_to_list(self, datas, field="poi_id", info_field="poi"):
"""加载信息到数据集中
Args:
datas: 要加工的数据
field: 源数据中的id字段
info_field: 要加入的信息对应的key
Returns:
加工完的数据
"""
ids = ",".join([str(data[field]) for data in datas if data[field]])
if not ids:
return datas
self.__id__ = "id"
infos = self.select(other="where %s in (%s)" % (self.__id__, ids))
for info in infos:
for data in datas:
if data[field] == info[self.__id__]:
data[info_field] = info
return datas
def add_count(self, field_name, count=1):
""" 给int字段加值
@param field_name: 字段名
@param count: 加的数量,默认1,可以是负数
@return: 成功与否
"""
self.__id__ = "id"
try:
if not self.real_dict().get(self.__id__, ""):
logging.error("%s is null" % self.__id__)
return False
sql = "update %s set %s = %s + %d where %s = %d" % (
self.__table__, field_name, field_name, count, self.__id__, self.real_dict()[self.__id__]
)
self.execute(sql)
return True
except Exception as e:
logging.error("Add count error, info:%s" % e)
return False
def get_count(self, where={}, other=""):
self.__id__ = "id"
tmp_data = self.select(where, fields="count(%s) as count" % self.__id__, other=other)
return tmp_data[0]["count"]
if __name__ == "__main__":
b = BaseModel()
b.name = "121"
print(b.to_json())
print(b.save())
print(b.__dict__)
--index-url http://pypi.douban.com/simple/
--extra-index-url http://mirrors.aliyun.com/pypi/simple/
--allow-external PIL
--allow-unverified PIL
tornado>=4.5
redis>=2.10.6
MySQL-python>=1.2.5
qiniu>=7.0.7
psycopg2>=2.7.1
# coding: utf-8
__author__ = "bozyao"
import sys
import os
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if path not in sys.path:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
if __name__ == "__main__":
from main import run, current_path
path = os.path.join(current_path())
sys.path.append(path)
run(path, use_session=False, debug=True)
# coding: utf-8
import sys
import os
import logging
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
if __name__ == "__main__":
from base.main import run, current_path
path = current_path()
logging.info("Start path: %s" % path)
run(path)
# coding: utf-8
from base_lib.app_route import route, check_session, RequestHandler, async
@route()
class TestHandler(RequestHandler):
def post(self):
self.ret_data(
{"data": 'hello world'}
)
@route("/test/(\d+)")
class TestHandler(RequestHandler):
@async
def get(self, n):
import time
time.sleep(int(n))
self.ret_data({"sleep_time": n})
@route("/test1/(\d+)")
class Test1Handler(RequestHandler):
def get(self, n):
import time
time.sleep(int(n))
self.ret_data({"sleep_time": n})
@route()
class WorldHandler(RequestHandler):
@check_session()
# 必须登录,cookie中有session_id=xxxxxx,xxxx在redis中有数据userid
def get(self):
self.ret_data(
{"msg": "Say 'Hello world!'"}
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment