api.py 10.8 KB
Newer Older
wanli's avatar
wanli committed
1 2 3 4
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
import json
5 6
import shutil
import subprocess
wanli's avatar
wanli committed
7 8
import traceback
import uuid
wanli's avatar
wanli committed
9
import time
10
import zipfile
wanli's avatar
wanli committed
11
import sqlite3
12
from pathlib import Path
wanli's avatar
wanli committed
13
from datetime import datetime
wanli's avatar
wanli committed
14

wanli's avatar
wanli committed
15
from flask import Blueprint, request, json
wanli's avatar
wanli committed
16
from werkzeug.utils import secure_filename
wanli's avatar
wanli committed
17

wanli's avatar
wanli committed
18
from app import config, signalManager
19
from fullstack.log import logger
wanli's avatar
wanli committed
20 21 22
from fullstack.login import Auth
from fullstack.response import ResponseCode, response_result
from fullstack.validation import validate_schema
wanli's avatar
wanli committed
23
from schema.api import UpdatePasswordSchema, ApplicationBuildSchema, ConvertString
24 25 26
import sys
sys.path.append("..")
from utils import vbuild
wanli's avatar
wanli committed
27 28 29

api = Blueprint("api", __name__, url_prefix="/api/v1/%s" % config['NAME'])

30 31
logger.info("/api/v1/%s" % config['NAME'])

wanli's avatar
wanli committed
32 33
def stopApp():
    fpath = os.sep.join([os.getcwd(), "restart.json"])
wanli's avatar
wanli committed
34
    with open(fpath, "w+") as f:
wanli's avatar
wanli committed
35 36 37 38 39
        ret = json.loads(f.read())
        ret["count"] = ret["count"] + 1
        f.write(json.dumps(ret, indent=4))
    return ret

wanliofficial's avatar
wanliofficial committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
@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)

wanli's avatar
wanli committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
@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/<uuid>", 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/<uuid>", 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/<uuid>", 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)

wanli's avatar
wanli committed
137 138 139
@api.route("/opqcp", methods=['POST'])
def action_opqcp():
    params = request.json
wanliofficial's avatar
wanliofficial committed
140
    result, message = signalManager.actionOpqcp.emit(params)
wanli's avatar
wanli committed
141
    print(result)
wanli's avatar
wanli committed
142

wanliofficial's avatar
wanliofficial committed
143
    return response_result(ResponseCode.OK, msg=message)
wanliofficial's avatar
wanliofficial committed
144

145 146 147 148 149 150 151 152
@api.route("/build", methods=['POST'])
def action_build():
    # 接收用户上传的evue文件
    # 创建一个文件夹
    # 将用户上传文件移动到新创建的文件夹中
    # 解析这个evue文件,分别生成3个文件:index.html.bc/index.css.bc/index.js.bc
    # 对这三个进行zip压缩,将压缩后的zip链接返回给前端

153 154 155 156 157 158
    # 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")
159 160 161 162 163 164 165 166 167

    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()

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    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)
        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())

    # 压缩
    z.close()
202 203 204 205

    result = Path(zip_filepath).resolve().relative_to(Path(config.get("UPLOAD_PATH"))).as_posix()
    return response_result(ResponseCode.OK, data=result)

wanli's avatar
wanli committed
206 207 208 209 210 211 212
@api.route("/monitor", methods=['GET', 'POST'])
def action_monitor():
    print(request.json)
    print(request.data)
    print(request.form)
    print(type(request.json))
    
wanli's avatar
wanli committed
213
    return response_result(ResponseCode.OK)
wanli's avatar
wanli committed
214 215 216 217 218

@api.route("/updatePassword", methods=['POST'])
@validate_schema(UpdatePasswordSchema)
@Auth.auth_required
def update_password():
wanli's avatar
wanli committed
219
    result, message = signalManager.actionUpdatePassword.emit(request.current_user.get("id"), request.schema_data)
wanli's avatar
wanli committed
220 221 222 223 224 225 226 227
    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:
wanli's avatar
wanli committed
228 229 230 231
        result = None

        binfile = request.files.get("binfile")
        if not binfile:
wanli's avatar
wanli committed
232
            return response_result(ResponseCode.REQUEST_ERROR, msg="upload field name error")
wanli's avatar
wanli committed
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261

        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), # 附件大小
wanli's avatar
wanli committed
262 263
            "filepath": os.sep.join([relative_path, filename]).replace("\\", "/"), # 附件存储路径
        }
wanli's avatar
wanli committed
264

wanli's avatar
wanli committed
265
        return response_result(ResponseCode.OK, data=result, msg="upload file [%s] successfully!" % obj['filename'])
wanli's avatar
wanli committed
266 267 268 269 270 271 272 273
    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 = []
wanli's avatar
wanli committed
274 275 276 277
    for index in range(16):
        print(index)
        result.append(str(uuid.uuid1()))

wanli's avatar
wanli committed
278 279 280 281 282 283 284 285 286 287 288 289
    # 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()

wanli's avatar
wanli committed
290
    return response_result(ResponseCode.OK, data=result)
wanli's avatar
wanli committed
291

wanli's avatar
wanli committed
292 293 294 295 296 297
@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)

wanli's avatar
wanli committed
298 299 300 301 302 303 304
@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
wanli's avatar
wanli committed
305
            dt = datetime.now().strftime("%Y%m%d%H%M%S")
wanli's avatar
wanli committed
306
            upload_path = os.sep.join([config["UPLOAD_PATH"], config["TEMP_DIR"], str(data['access_key']), dt])
wanli's avatar
wanli committed
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
            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))