async def tree_channel(request): sourceData = rest.getList({ 'pagesize': -1, 'sort': '-sort,-id' }, 'channel', 'treeChannel', True) if sourceData == 1: return fail('服务器内部错误', 500, 500) if sourceData['total'] < 1: return fail('您当前还没有添加任何栏目') sourceList = sourceData['list'] def makeTree(pid, arr): res = [] for i in arr: if i['pid'] == pid: rep = makeTree(i['id'], arr) if len(rep) != 0: i['children'] = rep res.append(i) return res res = makeTree(0, sourceList) return ok(res)
def get(request, name, oid, key=None, speed=False): hmupName = str2Hump(name) try: redisData = r.get(key) if redisData and speed: res = pickle.loads(redisData) print('get by redis') else: res = query.get(hmupName, oid) print('get by db') if speed: r.set(key, pickle.dumps(res), ex=REDIS_SPEED_TIME) except: print('redis error; get by db') res = query.get(hmupName, oid) if isinstance(res, dict): return ok(res) elif res == 404: return fail('数据库中没有' + name + '这个表', 404, 404) elif res == 4042: return fail('没有这条数据', 404, 404) elif res == 4043: return fail(name + '数据库中没有数据', 404, 404) elif res == 503: return fail('数据查询失败', 503) else: return fail('服务器内部错误', 500, 500)
async def doProcess(app, name, request, query, method, oid=None): # 通过配置前缀字典,获得不同前缀字符串,并替换斜杠为下划线 for i in PREFIX: if i in request.url: p = '_'.join(list(filter(None, PREFIX[i].split('/')))) # 组装前后处理的不同名称 bm = p + 'before' + name am = p + 'after' + name # 进行对应前处理,非字典结果,直接抛出 if dir(app.process.get(bm)).count(method) == 1: if oid == None: data = await getattr(app.process.get(bm), method)(query) else: data = await getattr(app.process.get(bm), method)(query, oid) if data: return data # 得到查询结果 if oid == None: response = getattr(rest, method)(query, name) else: response = getattr(rest, method)(query, name, oid) resBody = json.loads(response.body) resStatus = response.status # 根据返回结果判断是否需要后处理(错误状态就不处理了) if resStatus == 200 and resBody['status'] == 0 \ and dir(app.process.get(am)).count(method) == 1: data = await getattr(app.process.get(am), method)(resBody['data']) return ok(data) else: return response
async def login(request): dat = request.json manageData = {'username': '******', 'password': '******'} res = fail('参数错误', 400) # 检查入参是否正确 if not checkParam(['account', 'password'], dat): del res.cookies['session'] return res # 从传参中解密密码 password = rsaDecrypt(PRIVATE_KEY_PATH, dat['password']) # 检查用户名密码是否正确 if dat['account'] != manageData['username'] \ or password != manageData['password']: res = fail('用户名或密码错误', 400) del res.cookies['session'] return res # 正常处理 token = makeToken(dat['account'], 'manage') res = ok(token) res.cookies['session'] = token res.cookies['session']['httponly'] = True return res
async def logout(request): session = request.cookies.get('session') res = fail('退出失败', 401, 401) cs = checkSession(session) if cs == 0: clearSession(session) res = ok('退出成功') del res.cookies['session'] return res
def post(request, name): hmupName = str2Hump(name) res = query.post(hmupName, request) if isinstance(res, dict): return ok(res) elif res == 400: return fail('参数错误', 400) elif res == 404: return fail('数据库中没有' + name + '这个表', 404, 404) elif res == 503: return fail('数据添加失败', 503) else: return fail('服务器内部错误', 500, 500)
def delete(request, name, oid): hmupName = str2Hump(name) res = query.delete(hmupName, oid) if isinstance(res, dict): return ok(res) elif res == 400: return fail('您要删除的数据不存在', 400) elif res == 404: return fail('数据库中没有' + name + '这个表', 404, 404) elif res == 503: return fail('数据删除失败', 503) else: return fail('服务器内部错误', 500, 500)
def ls(request, name): hmupName = str2Hump(name) res = query.ls(hmupName, request) if isinstance(res, dict): return ok(res['list'], res['total']) elif res == 400: return fail('参数错误', 400) elif res == 404: return fail('数据库中没有' + name + '这个表', 404) elif res == 503: return fail('数据查询失败', 503) else: return fail('服务器内部错误', 500, 500)
async def doProcess(app, name, request, query, method, oid=None): # 是否需要缓存加速,默认否 speed = False # 通过配置前缀字典,获得不同前缀字符串,并替换斜杠为下划线 for i in PREFIX: if i in request.url: FIX = PREFIX[i] p = '_'.join(list(filter(None, FIX.split('/')))) # 查看接口是否在加速列表 if FIX in REDIS_SPEED_API_PREFIX_LIST: speed = True # 组装前后处理的不同名称 bm = p + 'before' + name am = p + 'after' + name # 进行对应前处理,非字典结果,直接抛出 if dir(app.process.get(bm)).count(method) == 1: if oid == None: data = await getattr(app.process.get(bm), method)(query) else: data = await getattr(app.process.get(bm), method)(query, oid) if data: return data # 得到查询结果 if oid == None: if method == 'ls': redisKeyName = p + name + dict2str(query) response = getattr(rest, method)(query, name, redisKeyName, speed) else: response = getattr(rest, method)(query, name) else: if method == 'get': redisKeyName = p + name + oid + dict2str(query) response = getattr(rest, method)(query, name, oid, redisKeyName, speed) else: response = getattr(rest, method)(query, name, oid) resBody = json.loads(response.body) resStatus = response.status # 根据返回结果判断是否需要后处理(错误状态就不处理了) if resStatus == 200 and resBody['status'] == 0 \ and dir(app.process.get(am)).count(method) == 1: data = await getattr(app.process.get(am), method)(resBody['data']) return ok(data) else: return response
async def upload(request): # 字节码转16进制字符串 def bytes2hex(bytes): hexstr = u"" for i in range(10): t = u"%x" % bytes[i] if len(t) % 2: hexstr += u"0" hexstr += t return hexstr.lower() # 根据16进制字符串获取文件后缀 def getSuffix(hexStr): print(hexStr) for i in SUPPORT_TYPE: if i in hexStr: return SUPPORT_TYPE[i] return 400 # 判断参数是否正确 if not request.files and not request.files.get('file'): return fail('参数错误', 400) image = request.files.get('file').body # 判断文件是否支持 imageSuffix = getSuffix(bytes2hex(image)) if imageSuffix == 400: return fail('不支持的文件类型', 400) # 组织图片存储路径 m1 = hashlib.md5() m1.update(image) md5Name = m1.hexdigest() saveDir = UPLOAD_PATH + md5Name[0:2] + '/' savePath = saveDir + md5Name[2:] + '.' + imageSuffix resPath = '/' + md5Name[0:2] + '/' + md5Name[2:] + '.' + imageSuffix # 如果文件夹不存在,就创建文件夹 if not os.path.exists(saveDir): os.makedirs(saveDir) # 将文件写入到硬盘 tempFile = open(savePath, 'wb') tempFile.write(image) tempFile.close() # 给客户端返回结果 return ok({"path": resPath})
def get(request, name, oid): hmupName = str2Hump(name) res = query.get(hmupName, oid) if isinstance(res, dict): return ok(res) elif res == 404: return fail('数据库中没有' + name + '这个表', 404) elif res == 4042: return fail('没有这条数据', 404) elif res == 4043: return fail(name + '数据库中没有数据', 404) elif res == 503: return fail('数据查询失败', 503) else: return fail('服务器内部错误', 500, 500)
async def count(request): res = [] res.append({ 'type': '全站文章数量', 'total': rest.getList({'pagesize': 1}, 'article')['total'] }) res.append({ 'type': '全站作者总量', 'total': rest.getList({'pagesize': 1}, 'author')['total'] }) res.append({ 'type': '全站来源总量', 'total': rest.getList({'pagesize': 1}, 'origin')['total'] }) res.append({ 'type': '全站关键词数量', 'total': rest.getList({'pagesize': 1}, 'tags')['total'] }) return ok(res)
async def login(request): # 先检查参数是否正确 req = json.loads(request.body) checkParam(['account', 'password'], req) # 根据用户名,从数据库中读取管理员信息 accRes = json.loads(rest.ls({'username': req['account']}, 'manages').body) # 判断查询结果是否正常 if accRes['status'] == 0: # 判断是否查到该管理员 if len(accRes['data']['list']) >= 1: # 处理管路员密码 acc = accRes['data']['list'][0] accPw = rsaDecrypt(KEY_PATH, acc['password']) reqPw = rsaDecrypt(KEY_PATH, req['password']) reqPwLen = len(reqPw) if reqPwLen < 6 or reqPwLen > 16: res = fail('密码长度为 6-16 位') del res.cookies['session'] return res elif accPw != reqPw: res = fail('密码不正确') del res.cookies['session'] return res else: session = makeSession(req['account'], 'manage') res = ok('登录成功') res.cookies['session'] = session res.cookies['session']['httponly'] = True return res else: res = fail('用户名不正确') del res.cookies['session'] return res else: return fail('服务器内部错误', 503)
async def upimg(request): # 判断参数是否正确 if not request.files and not request.files.get('file'): return fail('request args is error', 412) image = request.files.get('file').body # 判断文件是否支持 imageSuffix = getSuffix(bytes2hex(image)) if imageSuffix == 'error': return fail('image type is error', 415) # 组织图片存储路径 m1 = hashlib.md5() m1.update(image) md5Name = m1.hexdigest() saveDir = STATIC_DIR + '/' + md5Name[0:2] + '/' savePath = saveDir + md5Name[2:] + '.' + imageSuffix resPath = md5Name + '.' + imageSuffix # 如果文件夹不存在,就创建文件夹 if not os.path.exists(saveDir): os.makedirs(saveDir) # 上传文件附带参数处理 if 'data' in request.form and imageSuffix != 'svg': # 检查参数是否是 json params_text = request.form['data'][0] if not isDictStr(params_text): return fail('form data must be Json String', 412) params = json.loads(params_text) # 读取原图信息 sImg = Image.open(BytesIO(image)) sw, sh = sImg.size # PNG 和 JPG 图片的处理 if imageSuffix != 'gif': oImg = sImg # 处理缩放图片 if 'zoom' in params: zoom = params['zoom'] if not isNum(zoom): return fail('zoom value must be Positive integer', 412) # 如果原图尺寸小于缩放尺寸,则直接保存 if sw <= zoom and sh <= zoom: saveImage(savePath, image) else: oImg = zoomImg(sImg, sw, sh, zoom) # 处理水印参数 mParam = calcMarkParams(params) if not isinstance(mParam, dict) and mParam != False: return mParam if isinstance(mParam, dict): oImg = makeMark(oImg, mParam) # 保存图片 oImg.save(savePath, checkSuffix(imageSuffix)) oImg.close() # 处理 gif 图片 else: oImg = sImg # 将 gif 拆解为一组照片 tempGIf = hackGif(sImg, savePath) tempImgPath = tempGIf[0] tempDirPath = tempGIf[1] gifDur = tempGIf[2] / 1000 tempImg = [] # 压缩每一张照片 for i in tempImgPath: tmp = Image.open(i) if 'zoom' in params: zoom = params['zoom'] if not isNum(zoom): return fail('zoom value must be Positive integer', 412) # 如果原图尺寸小于缩放尺寸,则直接保存 if sw > zoom and sh > zoom: tmp = zoomImg(tmp, sw, sh, zoom) # 处理水印参数 mParam = calcMarkParams(params) if not isinstance(mParam, dict) and mParam != False: return mParam if isinstance(mParam, dict): tmp = makeMark(tmp, mParam) tmp.save(i, 'PNG') tempImg.append(imageio.imread(i)) # 将拆解出来的图片重新组装为gif图片 imageio.mimsave(savePath, tempImg, 'GIF', duration=gifDur) # 删除临时文件夹 shutil.rmtree(tempDirPath) else: saveImage(savePath, image) # 给客户端返回结果 return ok({"path": resPath})