app.py 11.4 KB
Newer Older
wanli's avatar
wanli committed
1 2 3 4 5 6 7
#!/usr/bin/env python
# -*- coding: utf_8 -*-

import os
import re
import json
import shutil
8
from pathlib import Path
wanli's avatar
wanli committed
9
from datetime import datetime
wanli's avatar
wanli committed
10
from sqlalchemy import func, distinct
wanli's avatar
wanli committed
11
from application.app import db
wanli's avatar
wanli committed
12 13 14
from models.package import PackageModel
from models.annex import AnnexModel
from models.user import UserModel
wanli's avatar
wanli committed
15
from models.app import AppModel
wanli's avatar
wanli committed
16
from application.config import config
17
from webcreator import utils
wanli's avatar
wanli committed
18
from webcreator.utils.epk import EpkApp
wanli's avatar
wanli committed
19
from webcreator.log import logger
wanli's avatar
wanli committed
20
from webcreator.response import ResponseCode
wanli's avatar
wanli committed
21

22 23 24 25 26 27 28 29 30 31 32 33 34 35
@utils.ThreadMaker
def update_information(ip, record_id):
    try:
        jsonData = utils.get_location_by_ip(ip)
        if (0 != jsonData['status']):
            return None

        pack = PackageModel.query.filter(PackageModel.id==record_id).first()
        pack.geo_location = json.dumps(jsonData, ensure_ascii=False)
        pack.ip = ip
        db.session.commit()
    except Exception as e:
        logger.error(e)

wanli's avatar
wanli committed
36 37 38 39
class AppResource(object):
    def __init__(self):
        super().__init__()

40
    def get(self, uuid, jwt):
wanli's avatar
wanli committed
41
        # handle business
42
        filters = [AppModel.is_delete==False, AppModel.uuid==uuid]
wanli's avatar
wanli committed
43 44 45 46
        app = AppModel.query.filter(*filters).one_or_none()
        if not app:
            return None, ResponseCode.HTTP_NOT_FOUND

47
        user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none()
wanli's avatar
wanli committed
48 49 50 51 52 53 54 55
        if not user:
            return False, ResponseCode.USER_NOT_EXISTS

        # 根据app查询应用,获取应用有哪些文件
        # 按格式创建文件夹,将这些文件移动到这个文件夹
        # 将这些零散文件进行打包
        # 更新数据库对应文件的路径

56
        source_files = AnnexModel.query.filter(AnnexModel.app==app.id).all()
wanli's avatar
wanli committed
57 58 59
        if not source_files:
            return None, ResponseCode.HTTP_NOT_FOUND

60 61 62 63 64 65
        now_str = datetime.now().strftime("%Y%m%d%H%M%S")
        dirname = "{}-{}-{}-{}".format(app.app_name, app.app_version, app.category, now_str)
        target_dir = Path(config.UPLOAD_ROOT_DIR).joinpath(config.EPK_DIR).joinpath(dirname)
        dest_dir = target_dir.joinpath("src")
        if not dest_dir.exists():
            os.makedirs(dest_dir.resolve().as_posix())
wanli's avatar
wanli committed
66 67 68

        app_files = []
        for sf in source_files:
69 70 71 72 73 74 75 76 77 78
            target_file = Path(sf.path)
            if not target_file.exists():
                target_file = Path(config.UPLOAD_ROOT_DIR).joinpath(sf.path)
            
            name = re.sub(r"_\d{14}$", "", target_file.stem)
            suffix = target_file.suffix
            dst_file = dest_dir.joinpath(name + suffix)
            shutil.copy(target_file.resolve().as_posix(), dst_file.resolve().as_posix())
            app_files.append([sf.id, dst_file.resolve().as_posix()])

79
        target_dir.joinpath("epk.json").write_text(json.dumps(app.to_dict(), ensure_ascii=False), encoding="utf-8")
wanli's avatar
wanli committed
80 81 82

        # 打包成EPK文件
        app_info = {}
83
        params = { 'appName': app.app_name, 'appDir': dest_dir.resolve().as_posix(), 'appVersion': app.app_version, 'output': target_dir.resolve().as_posix() }
84
        if user.role == 1:
wanli's avatar
wanli committed
85 86 87 88 89 90 91
            params['algorithm'] = "h"
        epk = EpkApp(**params)
        app_info = epk.pack()
        app_info['md5'] = str(app_info['md5'])

        # 更新数据库对应文件路径
        # 将文件拷贝过去后,需要重新更新数据库文件记录
92
        epk_path = target_dir.relative_to(config.UPLOAD_ROOT_DIR).joinpath("{}.epk".format(app.app_name)).resolve().as_posix()
wanli's avatar
wanli committed
93

94
        package = PackageModel.query.filter(PackageModel.app==app.id).one_or_none()
wanli's avatar
wanli committed
95 96 97 98 99 100 101 102
        if package:
            package.app_path = epk_path
            package.app_info = app_info
            package.update_by = user.id
            package.update_at = datetime.now()
            db.session.commit()

        # 新增一条AppLogs
103
        package = PackageModel(app=app.app_name, app_version=app.app_version, file_path=epk_path, package_info=json.dumps(app_info, ensure_ascii=False), create_by=user.id, create_at=datetime.now())
wanli's avatar
wanli committed
104
        db.session.add(package)
105 106 107 108
        app.update_by = user.id
        app.update_at = datetime.now()
        app.app_file_size = app_info.get("buff_length", 0)
        app.download_url = epk_path
wanli's avatar
wanli committed
109 110
        db.session.commit()

111
        return { 'app_name': app.app_name, 'app_path': epk_path }, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
112

113 114
    def getList(self, params, jwt):
        user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none()
wanli's avatar
wanli committed
115 116 117 118
        if not user:
            return False, ResponseCode.USER_NOT_EXISTS

        temp = {}
119 120 121
        filters = [AppModel.is_delete==False]
        if user.role == 1:
            temp.update({ "is_delete": False })
wanli's avatar
wanli committed
122
        else:
123 124
            filters.append(AppModel.create_by==user.id)
            temp.update({ "create_by": user.id, "is_delete": False })
125

126
        if "scope" in params and params.get("scope") == "list":
wanli's avatar
wanli committed
127 128 129
            result = AppModel.query.filter_by(**temp).order_by(AppModel.create_at.desc())
            temp = []
            for item in result:
130 131 132 133 134 135
                temp.append({
                    "uuid": item.uuid,
                    "app_name": item.app_name
                })
            return temp, ResponseCode.HTTP_SUCCESS
        elif "scope" in params and params.get("scope") == "distinct":
wanli's avatar
wanli committed
136 137 138 139
            result = db.session.query(AppModel, func.count(distinct(AppModel.name))).all()
            temp = []
            for item in result:
                temp.append(item)
140
            return temp, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
141

142 143 144 145 146 147
        for p in params:
            if hasattr(AppModel, p) and params[p] != None:
                temp[p] = params[p]

        result = AppModel.query.filter_by(**temp).order_by(AppModel.create_at.desc()).paginate(params.get("page", 1), params.get("pageSize", 15), error_out=False)
        # result = AppModel.query.filter(*filters).order_by(AppModel.create_at.desc()).paginate(params.get('page', 1), params.get('pageSize', 15), error_out=False)
wanli's avatar
wanli committed
148 149

        if result.total and len(result.items):
150 151
            return result, ResponseCode.HTTP_SUCCESS
        return None, ResponseCode.HTTP_NOT_FOUND
wanli's avatar
wanli committed
152

153
    def post(self, params, jwt={}):
wanli's avatar
wanli committed
154
        # handle business
wanli's avatar
wanli committed
155 156
        # 应用打包
        # 插入一条打包记录
157
        user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none()
wanli's avatar
wanli committed
158 159 160 161 162 163 164
        if not user:
            return False, ResponseCode.USER_NOT_EXISTS

        # 判断下app是否存在
        # result = Apps.select(app_name=data.get("app_name"), is_delete=False).count()
        # if result < 1:
        #     return False, "app_name has been exists."
165 166 167
        algorithm = params.get('algorithm')
        if algorithm:
            params.pop("algorithm")
wanli's avatar
wanli committed
168 169 170 171 172 173 174 175 176
        params.update({
            'app_icon': params["app_icon"].replace(config.UPLOAD_ROOT_DIR, ""),
            'create_by': user.id,
            'create_at': datetime.now(),
            'update_by': user.id,
            'update_at': datetime.now(),
        })

        app_files = []
177
        epk_path = Path("")
wanli's avatar
wanli committed
178 179 180 181 182
        if params.get("fileList"):
            app_files = params.get("fileList")
            params.pop("fileList")
            epk_path = params.get("epk_path")
            params.pop("epk_path")
183 184
        if params.get("logo"):
            params.pop("logo")
185 186 187
        real_ip = params.get("real_ip", None)
        if real_ip:
            params.pop("real_ip")
wanli's avatar
wanli committed
188 189 190

        app = AppModel(**params)
        db.session.add(app)
wanli's avatar
wanli committed
191
        db.session.commit()
wanli's avatar
wanli committed
192

193 194
        logger.info(params)

wanli's avatar
wanli committed
195
        # 在EPK目录下生成JSON文件
196
        epk_path.joinpath("epk.json").write_text(json.dumps(app.to_dict(), ensure_ascii=False), encoding="utf-8")
197 198
        # with open(os.sep.join([os.path.dirname(epk_path), "epk.json"]), "w") as f:
        #     json.dump(app.to_dict(), f)
wanli's avatar
wanli committed
199 200

        for a in app_files:
201 202
            t = Path(config.UPLOAD_ROOT_DIR).joinpath(a)
            res = AnnexModel(app=app.id, title=t.name, path=a, size=t.stat().st_size, create_by=user.id, create_at=datetime.now(), update_by=user.id, update_at=datetime.now())
wanli's avatar
wanli committed
203 204 205 206 207
            db.session.add(res)
            db.session.flush()
        db.session.commit()

        app_info = {}
208
        params = { 'appName': app.app_name, 'appDir': epk_path.resolve().as_posix(), 'appVersion': app.app_version, 'output': epk_path.parent.resolve().as_posix() }
209
        if user.role == 1:
wanli's avatar
wanli committed
210
            params['algorithm'] ="h"
211 212 213 214

        if algorithm:
            params['algorithm'] = algorithm

wanli's avatar
wanli committed
215 216 217
        epk = EpkApp(**params)
        app_info = epk.pack()

218
        epk_filename = epk_path.parent.relative_to(config.UPLOAD_ROOT_DIR).joinpath("{}.epk".format(app.app_name)).resolve().as_posix()
wanli's avatar
wanli committed
219 220 221
        if app_info:
            app_info['md5'] = str(app_info['md5'])

222 223 224 225
        app.app_file_size = app_info.get("buff_length")
        app.download_url = epk_filename
        db.session.commit()

226
        package = PackageModel(app=app.id, file_path=epk_filename, app_version=params.get("appVersion"), package_info=json.dumps(app_info, ensure_ascii=False), source=1, create_by=user.id, create_at=datetime.now(), update_by=user.id, update_at=datetime.now(), remarks=json.dumps(params, ensure_ascii=False))
wanli's avatar
wanli committed
227 228 229
        db.session.add(package)
        db.session.commit()

230
        update_information(real_ip, package.id)
wanli's avatar
wanli committed
231

232
        return True, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
233

234
    def put(self, uuid, params, jwt={}):
wanli's avatar
wanli committed
235 236 237 238
        user = UserModel.query.filter(UserModel.id==params.get('user')).one_or_none()
        if not user:
            return False, ResponseCode.USER_NOT_EXISTS

wanli's avatar
wanli committed
239
        # handle business
wanli's avatar
wanli committed
240 241 242
        app = AppModel.query.filter(AppModel.uuid==uuid).first()
        if not app:
            return None, ResponseCode.HTTP_NOT_FOUND
243

wanli's avatar
wanli committed
244
        if params:
wanli's avatar
wanli committed
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
            # 更新文件
            if params.get("app_files"):
                for a in params.get("app_files"):
                    res = AnnexModel(app=app, title=a.get("filename"), path=a.get("filepath"), size=a.get("filesize"), create_by=user, create_at=datetime.now(), update_by=user, update_at=datetime.now())
                    db.session.add(res)
                    db.session.flush()
                db.session.commit()
                params.pop("app_files")

            # 更新icon
            if params.get("app_icon"):
                condition = { 'update_by': user, 'update_at': datetime.now() }
                if params.get("app_icon").get("filename"):
                    condition.update({"title": params.get("app_icon").get("filename")})
                if params.get("app_icon").get("filepath"):
                    condition.update({"path": params.get("app_icon").get("filepath")})
                if params.get("app_icon").get("filesize"):
                    condition.update({"size": params.get("app_icon").get("filesize")})

                params.pop("app_icon")

wanli's avatar
wanli committed
266
            for key, value in params.items():
wanli's avatar
wanli committed
267 268 269 270
                if value != None:
                    setattr(app, key, value)
            app.update_by = jwt.get("id", "")
            app.update_date = datetime.now()
wanli's avatar
wanli committed
271
            db.session.commit()
wanli's avatar
wanli committed
272
            return True, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
273
        else:
wanli's avatar
wanli committed
274
            return False, ResponseCode.HTTP_INVAILD_REQUEST
wanli's avatar
wanli committed
275

276
    def delete(self, uuid, jwt={}):
wanli's avatar
wanli committed
277
        # handle business
278 279
        result = AppModel.query.filter(AppModel.uuid==uuid).first()
        if not result:
wanli's avatar
wanli committed
280
            return False, ResponseCode.HTTP_NOT_FOUND
281 282 283 284 285 286

        result.update_by = jwt.get("id", "")
        result.update_date = datetime.now()
        result.is_delete = True
        db.session.delete(result)
        db.session.commit()
wanli's avatar
wanli committed
287
        return True, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
288 289

appManager = AppResource()