working...

pull/32/merge
apexliu 2017-03-17 02:34:45 +08:00
parent f142793394
commit 054deb839e
6 changed files with 222 additions and 33 deletions

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from eom_common.eomcore.logger import log
from eom_app.app.util import sec_generate_password
# 升级数据表结构时必须升级此版本号并编写响应的升级SQL
TELEPORT_DATABASE_VERSION = 10
def create_and_init(db, step_begin, step_end):
_admin_sec_password = sec_generate_password('admin')
_step = step_begin('创建表 account')
ret = db.exec("""CREATE TABLE `{}account` (
`account_id` integer PRIMARY KEY AUTOINCREMENT,
`account_type` int(11) DEFAULT 0,
`account_name` varchar(32) DEFAULT NULL,
`account_pwd` varchar(32) DEFAULT NULL,
`account_status` int(11) DEFAULT 0,
`account_lock` int(11) DEFAULT 0,
`account_desc` varchar(255)
);""".format(db.table_prefix))
if not ret:
log.e('create table `account` failed.')
step_end(_step, -1)
return
else:
log.i('create table `account` ok.')
step_end(_step, 0)

View File

@ -1,19 +1,20 @@
# -*- coding: utf-8 -*-
import os
import threading
import sqlite3
import builtins
import os
import sqlite3
import threading
from .configs import app_cfg
from eom_common.eomcore.logger import log
from .configs import app_cfg
from .database.create import create_and_init, TELEPORT_DATABASE_VERSION
cfg = app_cfg()
__all__ = ['get_db']
# 注意,每次调整数据库结构,必须增加版本号,并且在升级接口中编写对应的升级操作
TELEPORT_DATABASE_VERSION = 2
# TELEPORT_DATABASE_VERSION = 2
class TPDatabase:
@ -21,15 +22,22 @@ class TPDatabase:
if '__teleport_db__' in builtins.__dict__:
raise RuntimeError('TPDatabase object exists, you can not create more than one instance.')
self._table_prefix = ''
self.need_create = False # 数据尚未存在,需要创建
self.need_upgrade = False # 数据库已存在但版本较低,需要升级
self._conn_pool = None
@property
def table_prefix(self):
return self._table_prefix
def init_mysql(self):
# NOT SUPPORTED YET
pass
def init_sqlite(self, db_file):
self._table_prefix = 'ts_'
self._conn_pool = TPSqlitePool(db_file)
if not os.path.exists(db_file):
@ -38,18 +46,29 @@ class TPDatabase:
return
# 看看数据库中是否存在用户表(如果不存在,可能是一个空数据库文件),则可能是一个新安装的系统
ret = self._conn_pool.query('SELECT COUNT(*) FROM sqlite_master where type="table" and name="ts_account";')
ret = self.query('SELECT COUNT(*) FROM sqlite_master where type="table" and name="ts_account";')
if ret[0][0] == 0:
log.w('database need create.\n')
self.need_create = True
return
# 尝试从配置表中读取当前数据库版本号如果不存在说明是比较旧的版本了则置为0
ret = self._conn_pool.query('SELECT value FROM ts_config where name="db_ver";')
ret = self.query('SELECT value FROM ts_config where name="db_ver";')
if 0 == len(ret):
log.w('database need upgrade.\n')
self.need_upgrade = True
def query(self, sql):
return self._conn_pool.query(sql)
def exec(self, sql):
return self._conn_pool.exec(sql)
def create_and_init(self, step_begin, step_end):
step_begin('准备创建数据表')
create_and_init(self, step_begin, step_end)
class TPDatabasePool:
def __init__(self):
@ -59,9 +78,15 @@ class TPDatabasePool:
def query(self, sql):
_conn = self._get_connect()
if _conn is None:
return list()
return None
return self._do_query(_conn, sql)
def exec(self, sql):
_conn = self._get_connect()
if _conn is None:
return False
return self._do_exec(_conn, sql)
def _get_connect(self):
with self._locker:
thread_id = threading.get_ident()
@ -77,7 +102,10 @@ class TPDatabasePool:
return None
def _do_query(self, conn, sql):
return list()
return None
def _do_exec(self, conn, sql):
return None
class TPSqlitePool(TPDatabasePool):
@ -99,7 +127,18 @@ class TPSqlitePool(TPDatabasePool):
db_ret = cursor.fetchall()
return db_ret
except sqlite3.OperationalError:
return list()
return None
finally:
cursor.close()
def _do_exec(self, conn, sql):
cursor = conn.cursor()
try:
cursor.execute(sql)
conn.commit()
return True
except sqlite3.OperationalError:
return False
finally:
cursor.close()

View File

@ -3,6 +3,7 @@
import os
import random
import io
import hashlib
import json
import urllib.parse
@ -23,7 +24,7 @@ from .configs import app_cfg
cfg = app_cfg()
__all__ = ['async_post_http', 'async_enc']
__all__ = ['async_post_http', 'async_enc', 'gen_captcha', 'sec_generate_password', 'sec_verify_password']
@tornado.gen.coroutine
@ -67,8 +68,8 @@ def async_enc(data):
return {'code': 0, 'data': return_data['data']['c']}
_chars = 'AaCDdEeFfHJjKkLMmNnPpQRrTtVvWwXxYy34679'
_font_dir = os.path.join(cfg.res_path, 'fonts')
_captcha_chars = 'AaCDdEeFfHJjKkLMmNnPpQRTtVvWwXxYy34679'
# _font_dir = os.path.join(cfg.res_path, 'fonts')
def gen_captcha():
@ -82,26 +83,79 @@ def gen_captcha():
curve(color='#af6fff', width=3, number=16),
noise(number=80, color='#eeeeee', level=3),
text(fonts=[
os.path.join(_font_dir, '001.ttf')
os.path.join(cfg.res_path, 'fonts', '001.ttf')
],
# font_sizes=(28, 34, 36, 32),
font_sizes=(34, 36, 32),
font_sizes=(34, 38, 32),
color='#63a8f5',
squeeze_factor=1.2,
# squeeze_factor=1.2,
squeeze_factor=0.9,
drawings=[
# warp(dx_factor=0.05, dy_factor=0.05),
rotate(angle=15),
warp(dx_factor=0.03, dy_factor=0.03),
rotate(angle=20),
offset()
]),
# curve(color='#af6fff', width=3, number=16),
noise(number=60, color='#eeeeee', level=2),
noise(number=30, color='#eeeeee', level=2),
smooth(),
])
chars_t = random.sample(_chars, 4)
chars_t = random.sample(_captcha_chars, 4)
image = captcha_image_t(chars_t)
out = io.BytesIO()
image.save(out, "jpeg", quality=100)
# web.header('Content-Type','image/jpeg')
return ''.join(chars_t), out.getvalue()
_hex_chars = '0123456789abcdef'
def sec_generate_password(password):
"""
根据设置的password计算一个加盐的散列用于保存到数据库
@param password: string
@return: string
"""
_hash_type = '3' # 1 = md5, 2 = sha1, 3 = sha256
_salt_data = list()
for i in range(16):
_salt_data.append(random.choice(_hex_chars))
_salt = ''.join(_salt_data)
h = hashlib.sha256()
h.update(_hash_type.encode())
h.update(_salt.encode())
h.update(password.encode())
_val = h.hexdigest()
ret = '{}:{}:{}'.format(_hash_type, _salt, _val)
print(ret, len(ret))
return ret
def sec_verify_password(password, sec_password):
_sec = sec_password.split(':')
if len(_sec) != 3:
return False
if _sec[0] == '1':
h = hashlib.md5()
elif _sec[0] == '2':
h = hashlib.sha1()
elif _sec[0] == '3':
h = hashlib.sha256()
else:
return False
h.update(_sec[0].encode())
h.update(_sec[1].encode())
h.update(password.encode())
_val = h.hexdigest()
return _val == _sec[2]

View File

@ -5,6 +5,7 @@ import time
import threading
from .base import TPBaseUserAuthHandler, TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
from eom_app.app.db import get_db
from eom_app.app.util import sec_generate_password, sec_verify_password
class IndexHandler(TPBaseUserAuthHandler):
@ -59,6 +60,7 @@ class RpcThreadManage:
'steps': self._threads[task_id]['steps']
}
if not self._threads[task_id]['running']:
print('remove task-id', task_id)
del self._threads[task_id]
return ret
else:
@ -71,28 +73,67 @@ class RpcThreadManage:
self._threads[task_id]['stop'] = True
def _create_db(self, tid):
time.sleep(2)
self._add_step_result(tid, 0, '正在初始化 1...')
self._add_step_result(tid, 0, '正在初始化 2...')
self._add_step_result(tid, 0, '正在初始化 3...')
self._add_step_result(tid, 0, '正在初始化 4...')
# x = sec_generate_password('admin')
# print(sec_verify_password('admin', x))
# print(sec_verify_password('.admin', x))
def _step_begin(msg):
self._step_begin(tid, msg)
def _step_end(sid, code, msg=None):
self._step_end(tid, sid, code, msg)
time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 1...')
get_db().create_and_init(_step_begin, _step_end)
self._step_begin(tid, '操作已完成')
# time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 2...')
# time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 3...')
# time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 4...')
# self._threads[tid]['steps'].append({'stat': 0, 'msg': '执行已结束'})
# if self._threads[tid]['stop']:
# self._add_step_result(tid, -1, '操作被终止')
self._thread_end(tid)
def _add_step_result(self, tid, code, msg):
if len(self._threads[tid]['steps']) > 0:
self._threads[tid]['steps'][-1]['stat'] = 0 # 0 表示此步骤已完成
self._threads[tid]['steps'].append({'stat': 1, 'code': code, 'msg': msg})
def _step_begin(self, tid, msg):
with self._lock:
if len(self._threads[tid]['steps']) > 0:
self._threads[tid]['steps'][-1]['stat'] = 0 # 0 表示此步骤已完成
self._threads[tid]['steps'].append({'stat': 1, 'code': 0, 'msg': msg})
return len(self._threads[tid]['steps']) - 1
def _step_end(self, tid, sid, code, msg=None):
with self._lock:
try:
self._threads[tid]['steps'][sid]['code'] = code
self._threads[tid]['steps'][sid]['stat'] = 0 # 0 表示此步骤已完成
if msg is not None:
self._threads[tid]['steps'][sid]['msg'] = msg
except:
pass
return len(self._threads[tid]['steps']) - 1
# def _add_step_result(self, tid, code, msg):
# if len(self._threads[tid]['steps']) > 0:
# self._threads[tid]['steps'][-1]['stat'] = 0 # 0 表示此步骤已完成
# self._threads[tid]['steps'].append({'stat': 1, 'code': code, 'msg': msg})
def _thread_end(self, tid):
with self._lock:
if tid in self._threads:
self._threads[tid]['running'] = False
if self._threads[tid]['stop']:
self._add_step_result(tid, -1, '操作被终止')
sid = self._step_begin(tid, '操作被终止')
self._step_end(tid, sid, -1)
if len(self._threads[tid]['steps']) > 0:
self._threads[tid]['steps'][-1]['stat'] = 0
@ -123,7 +164,7 @@ class RpcHandler(TPBaseAdminAuthJsonHandler):
# return self.write_json(-1)
r = thread_mgr.get_task(args['tid'])
if r is None:
return self.write_json(0, data={'running': False, 'msg': []})
return self.write_json(0, data={'running': False, 'steps': []})
else:
# del r['stop']
return self.write_json(0, data=r)

View File

@ -67,13 +67,23 @@
};
ywl.dom.btn_create_db.click(function () {
ywl.dom.btn_create_db.attr('disabled', 'disabled');
console.log('create-db-click');
ywl.ajax_post_json('/maintenance/rpc', {cmd: 'create_db'},
function (ret) {
console.log('create-db:', ret);
if (ret.code == 0) {
ywl.get_task_ret(ret.data.task_id);
}
var cb_stack = CALLBACK_STACK.create();
cb_stack
.add(ywl.get_task_ret, {task_id: ret.data.task_id})
.add(ywl.delay_exec, {delay_ms: 500})
.exec();
## ywl.get_task_ret(ret.data.task_id);
}
},
function () {
@ -83,12 +93,25 @@
});
ywl.get_task_ret = function (task_id) {
ywl.get_task_ret = function (cb_stack, cb_args) {
var task_id = cb_args.task_id || 0;
if (task_id == 0) {
console.log('task-id', task_id);
return;
}
ywl.ajax_post_json('/maintenance/rpc', {cmd: 'get_task_ret', 'tid': task_id},
function (ret) {
console.log('get_task_ret:', ret);
if (ret.code == 0) {
if(!ret.data.running) {
return;
}
cb_stack
.add(ywl.get_task_ret, {task_id: task_id})
.add(ywl.delay_exec, {delay_ms: 500})
.exec();
}
},