#!/usr/bin/env python # -*- coding: utf_8 -*- import os import json import shutil import subprocess import traceback import uuid import time import zipfile import sqlite3 from pathlib import Path from datetime import datetime from flask import Blueprint, request, json from werkzeug.utils import secure_filename from app import config, signalManager from fullstack.log import logger from fullstack.login import Auth from fullstack.response import ResponseCode, response_result from fullstack.validation import validate_schema from schema.api import UpdatePasswordSchema, ApplicationBuildSchema, ConvertString import sys sys.path.append("..") from utils import vbuild api = Blueprint("api", __name__, url_prefix="/api/v1/%s" % config['NAME']) logger.info("/api/v1/%s" % config['NAME']) def stopApp(): fpath = os.sep.join([os.getcwd(), "restart.json"]) with open(fpath, "w+") as f: ret = json.loads(f.read()) ret["count"] = ret["count"] + 1 f.write(json.dumps(ret, indent=4)) return ret @api.route("/evm", methods=['GET','POST']) def hello_evm(): def check(p): if hasattr(request, p): return getattr(request, p) else: return None print(request.method) print(request.headers) print(request.data) print(request.stream.read()) print(request.get_data()) if request.method == "GET": result = { "args": request.args } else: result = { 'args': check('args'), 'json': check('json'), 'data': check('values'), 'form': check('form') } return json.dumps(result) @api.route("/store", methods=['GET', 'POST']) def get_store(): result = {} with open("./apiData.json", "r", encoding="utf-8") as f: result = json.loads(f.read()) logger.info(request.args) # logger.info(request.query_string) if request.args and request.args.get("category"): res = [] for item in result.get("appList", []): if item.get("category") == request.args.get("category"): res.append(item) result["appList"] = res result = { 'appList': result["appList"], 'categoryList': result["categoryList"] } return response_result(ResponseCode.OK, data=result) @api.route("/store/app/", methods=['GET', 'POST']) def get_store_app(uuid): logger.info(uuid) result = {} with open("./apiData.json", "r", encoding="utf-8") as f: result = json.loads(f.read()) res = {} for item in result.get("appList", []): if item.get("uuid") == uuid: res = item break return response_result(ResponseCode.OK, data=res) @api.route("/store/appInfo/", methods=['GET', 'POST']) def get_app_info(uuid): result = {} with open("./apiData.json", "r", encoding="utf-8") as f: result = json.loads(f.read()) res = None for item in result.get("downloadList", []): if item.get("apkId") == uuid: res = item break print(res) return response_result(ResponseCode.OK, data=res) @api.route("/store/downloadEpk/", methods=['GET', 'POST']) def download_epk(uuid): # 这里要做一些业务处理,根据应用ID和版本号,判断是否有新的应用更新 result = {} with open("./apiData.json", "r", encoding="utf-8") as f: result = json.loads(f.read()) res = {} for item in result.get("downloadList", []): if item.get("apkId") == uuid: res.update(item) break res.update({ 'status': 0, 'time': int(time.time()) }) print(res) return response_result(ResponseCode.OK, data=res) @api.route("/opqcp", methods=['POST']) def action_opqcp(): params = request.json result, message = signalManager.actionOpqcp.emit(params) print(result) return response_result(ResponseCode.OK, msg=message) @api.route("/build", methods=['POST']) def action_build(): # 接收用户上传的evue文件 # 创建一个文件夹 # 将用户上传文件移动到新创建的文件夹中 # 解析这个evue文件,分别生成3个文件:index.html.bc/index.css.bc/index.js.bc # 对这三个进行zip压缩,将压缩后的zip链接返回给前端 # binfile = request.files.get("binfile") # if not binfile: # return response_result(ResponseCode.REQUEST_ERROR, msg="upload field name error") if len(request.files.getlist('binfile')) < 0: return response_result(ResponseCode.REQUEST_ERROR, msg="upload file is null") target_path = Path(config.get("UPLOAD_PATH")).joinpath(config.get("BYTECODE_DIR")) if not target_path.exists(): target_path.mkdir() target_path = target_path.joinpath(uuid.uuid1().hex) if not target_path.exists(): target_path.mkdir() dst_files = [] zip_filepath = target_path.joinpath("{}.zip".format(target_path.name)).resolve().as_posix() z = zipfile.ZipFile(zip_filepath, 'w') for f in request.files.getlist('binfile'): target = target_path.joinpath(f.filename) if target.suffix != ".evue": continue with open(target.resolve().as_posix(), "wb+") as fd: fd.write(f.stream.read()) content = vbuild.render(target.resolve().as_posix()) if content: files = [ (target.parent.joinpath("{}.hml".format(Path(f.filename).stem)).resolve().as_posix(), content.html), (target.parent.joinpath("{}.css".format(Path(f.filename).stem)).resolve().as_posix(), content.style), (target.parent.joinpath("{}.js".format(Path(f.filename).stem)).resolve().as_posix(), content.script) ] for item in files: file, text = item with open(file, "w+") as fd: fd.write(text) result = subprocess.call("./executable -c {file}".format(file=file), shell=True) logger.info(result) t = Path(file) res = t.rename("{}.{}".format(t.name, "bc")) dst_files.append(res) for file in dst_files: z.write(file.resolve().as_posix(), arcname=file.name) shutil.move(file.resolve().as_posix(), target_path.joinpath(file.name).resolve().as_posix()) # 压缩 if len(dst_files): z.close() result = Path(zip_filepath).resolve().relative_to(Path(config.get("UPLOAD_PATH"))).as_posix() return response_result(ResponseCode.OK, data={ 'url': result, 'filename': os.path.basename(zip_filepath) }) else: return response_result(ResponseCode.SERVER_ERROR) @api.route("/monitor", methods=['GET', 'POST']) def action_monitor(): print(request.json) print(request.data) print(request.form) print(type(request.json)) return response_result(ResponseCode.OK) @api.route("/updatePassword", methods=['POST']) @validate_schema(UpdatePasswordSchema) @Auth.auth_required def update_password(): result, message = signalManager.actionUpdatePassword.emit(request.current_user.get("id"), request.schema_data) if result: return response_result(ResponseCode.OK, data=result, msg=message) else: return response_result(ResponseCode.NOTHING_CHANGE, msg=message) @api.route("/upload", methods=['POST']) # 上传文件 def upload_file(): try: result = None binfile = request.files.get("binfile") if not binfile: return response_result(ResponseCode.REQUEST_ERROR, msg="upload field name error") obj = dict() obj['filename'] = binfile.filename obj['content'] = binfile.stream.read() dtNowString = datetime.now().strftime("%Y%m%d%H%M%S%f") # 文件名构成:文件名_时间日期.文件后缀 filename = os.path.splitext(obj['filename'])[0] + "_{}".format(dtNowString) + os.path.splitext(obj['filename'])[-1] # 获取相对路径 relative_path = os.sep.join([config.get("TEMP_DIR"), dtNowString]) # 获取最终存储的绝对路径 savePath = os.path.normpath(os.sep.join([config.get("UPLOAD_PATH"), relative_path])) # 获取最终存储的文件路径 saveFile = os.path.normpath(os.sep.join([savePath, filename])) if not os.path.exists(savePath): os.makedirs(savePath) with open(saveFile, 'wb') as f: # 保存文件 f.write(obj['content']) result = { "uuid": str(uuid.uuid4()), # 附件唯一编号 "filename": obj['filename'], # 附件名称 "filesize": os.path.getsize(saveFile), # 附件大小 "filepath": os.sep.join([relative_path, filename]).replace("\\", "/"), # 附件存储路径 } return response_result(ResponseCode.OK, data=result, msg="upload file [%s] successfully!" % obj['filename']) except Exception as e: traceback.print_exc() logger.error(str(e)) return response_result(ResponseCode.SERVER_ERROR, msg=str(e)) @api.route("/system/updateDatabase", methods=['GET']) def update_db(): result = [] for index in range(16): print(index) result.append(str(uuid.uuid1())) # conn = sqlite3.connect('./app-store.db') # cur = conn.cursor() # update_sql = """update test set name = 'noname' where id = ?""" # x = (1, ) # cur.execute(update_sql, x) # # commit()提交事务 # conn.commit() # # 关闭游标 # cur.close() # # 关闭连接 # conn.close() return response_result(ResponseCode.OK, data=result) @api.route("/system/convertString", methods=['POST']) @validate_schema(ConvertString) def convert_string(): result = signalManager.actionGetConvertString.emit(request.schema_data) return response_result(ResponseCode.OK, data=result) @api.route("/application/build", methods=["post"]) @validate_schema(ApplicationBuildSchema) def application_build(): try: if request.method == 'POST' and 'binfiles' in request.files: files = [] data = request.schema_data dt = datetime.now().strftime("%Y%m%d%H%M%S") upload_path = os.sep.join([config["UPLOAD_PATH"], config["TEMP_DIR"], str(data['access_key']), dt]) if not os.path.exists(upload_path): os.makedirs(upload_path) for f in request.files.getlist('binfiles'): filename = secure_filename(f.filename) file_path = os.sep.join([upload_path, filename]) f.save(file_path) files.append(file_path) result, message = signalManager.actionApplicationBuild.emit(files, data) if result: return response_result(ResponseCode.OK, data=result, msg=message) else: return response_result(ResponseCode.REQUEST_ERROR, msg=message) else: return response_result(ResponseCode.REQUEST_ERROR, msg="files can not be null") except Exception as e: traceback.print_exc() logger.error(str(e)) return response_result(ResponseCode.SERVER_ERROR, msg=str(e))