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.joinpath("{}.epk".format(app.app_name)).relative_to(config.UPLOAD_ROOT_DIR).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
    def getList(self, params, jwt):
114
        # 默认只查询资源包
115
        user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none()
wanli's avatar
wanli committed
116 117 118
        if not user:
            return False, ResponseCode.USER_NOT_EXISTS

119
        temp = { "is_delete": False }
120
        filters = [AppModel.is_delete==False]
121
        if user.role != 1:
122
            filters.append(AppModel.create_by==user.id)
123
            temp.update({ "create_by": user.id })
124

125
        if "scope" in params and params.get("scope") == "list":
wanli's avatar
wanli committed
126 127 128
            result = AppModel.query.filter_by(**temp).order_by(AppModel.create_at.desc())
            temp = []
            for item in result:
129 130 131 132 133 134
                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
135 136 137 138
            result = db.session.query(AppModel, func.count(distinct(AppModel.name))).all()
            temp = []
            for item in result:
                temp.append(item)
139
            return temp, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
140

141 142 143 144 145 146
        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
147
        if result.total and len(result.items):
148 149
            return result, ResponseCode.HTTP_SUCCESS
        return None, ResponseCode.HTTP_NOT_FOUND
wanli's avatar
wanli committed
150

151
    def post(self, params, jwt={}):
wanli's avatar
wanli committed
152
        # handle business
wanli's avatar
wanli committed
153 154
        # 应用打包
        # 插入一条打包记录
155
        user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none()
wanli's avatar
wanli committed
156 157 158 159 160 161 162
        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."
163 164 165
        algorithm = params.get('algorithm')
        if algorithm:
            params.pop("algorithm")
wanli's avatar
wanli committed
166 167 168 169 170 171 172 173 174
        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 = []
175
        epk_path = Path("")
wanli's avatar
wanli committed
176 177 178 179 180
        if params.get("fileList"):
            app_files = params.get("fileList")
            params.pop("fileList")
            epk_path = params.get("epk_path")
            params.pop("epk_path")
181 182
        if params.get("logo"):
            params.pop("logo")
183 184 185
        real_ip = params.get("real_ip", None)
        if real_ip:
            params.pop("real_ip")
wanli's avatar
wanli committed
186 187 188

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

191 192
        logger.info(params)

wanli's avatar
wanli committed
193
        # 在EPK目录下生成JSON文件
194
        epk_path.joinpath("epk.json").write_text(json.dumps(app.to_dict(), ensure_ascii=False), encoding="utf-8")
195 196
        # 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
197 198

        for a in app_files:
199 200
            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
201 202 203 204 205
            db.session.add(res)
            db.session.flush()
        db.session.commit()

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

        if algorithm:
            params['algorithm'] = algorithm

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

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

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

224
        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
225 226 227
        db.session.add(package)
        db.session.commit()

228
        update_information(real_ip, package.id)
wanli's avatar
wanli committed
229

230
        return True, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
231

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

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

wanli's avatar
wanli committed
242
        if params:
wanli's avatar
wanli committed
243 244 245
            # 更新文件
            if params.get("app_files"):
                for a in params.get("app_files"):
246
                    res = AnnexModel(app=app.id, title=a.get("filename"), path=a.get("filepath"), size=a.get("filesize"), create_by=user.id, create_at=datetime.now(), update_by=user.id, update_at=datetime.now())
wanli's avatar
wanli committed
247 248 249 250 251 252
                    db.session.add(res)
                    db.session.flush()
                db.session.commit()
                params.pop("app_files")

            # 更新icon
253 254
            if params.get("app_icon") and isinstance(params.get("app_icon"), dict):
                condition = { 'update_by': user.id, 'update_at': datetime.now() }
wanli's avatar
wanli committed
255 256 257 258 259 260 261 262 263
                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
264
            for key, value in params.items():
wanli's avatar
wanli committed
265 266
                if value != None:
                    setattr(app, key, value)
267
            app.update_by = user.id
wanli's avatar
wanli committed
268
            app.update_date = datetime.now()
wanli's avatar
wanli committed
269
            db.session.commit()
wanli's avatar
wanli committed
270
            return True, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
271
        else:
wanli's avatar
wanli committed
272
            return False, ResponseCode.HTTP_INVAILD_REQUEST
wanli's avatar
wanli committed
273

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

        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
285
        return True, ResponseCode.HTTP_SUCCESS
wanli's avatar
wanli committed
286 287

appManager = AppResource()