#!/usr/bin/env python # -*- coding: utf_8 -*- import os import re import json import shutil from pathlib import Path from datetime import datetime from sqlalchemy import func, distinct from application.app import db from models.package import PackageModel from models.annex import AnnexModel from models.user import UserModel from models.app import AppModel from application.config import config from webcreator import utils from webcreator.utils.epk import EpkApp from webcreator.log import logger from webcreator.response import ResponseCode @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) class AppResource(object): def __init__(self): super().__init__() def get(self, uuid, jwt): # handle business filters = [AppModel.is_delete==False, AppModel.uuid==uuid] app = AppModel.query.filter(*filters).one_or_none() if not app: return None, ResponseCode.HTTP_NOT_FOUND user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none() if not user: return False, ResponseCode.USER_NOT_EXISTS # 根据app查询应用,获取应用有哪些文件 # 按格式创建文件夹,将这些文件移动到这个文件夹 # 将这些零散文件进行打包 # 更新数据库对应文件的路径 source_files = AnnexModel.query.filter(AnnexModel.app==app.id).all() if not source_files: return None, ResponseCode.HTTP_NOT_FOUND 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()) app_files = [] for sf in source_files: 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()]) target_dir.joinpath("epk.json").write_text(json.dumps(app.to_dict(), ensure_ascii=False), encoding="utf-8") # 打包成EPK文件 app_info = {} params = { 'appName': app.app_name, 'appDir': dest_dir.resolve().as_posix(), 'appVersion': app.app_version, 'output': target_dir.resolve().as_posix() } if user.role == 1: params['algorithm'] = "h" epk = EpkApp(**params) app_info = epk.pack() app_info['md5'] = str(app_info['md5']) # 更新数据库对应文件路径 # 将文件拷贝过去后,需要重新更新数据库文件记录 epk_path = target_dir.joinpath("{}.epk".format(app.app_name)).relative_to(config.UPLOAD_ROOT_DIR).as_posix() package = PackageModel.query.filter(PackageModel.app==app.id).one_or_none() 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 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()) db.session.add(package) 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 db.session.commit() return { 'app_name': app.app_name, 'app_path': epk_path }, ResponseCode.HTTP_SUCCESS def getList(self, params, jwt): # 默认只查询资源包 user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none() if not user: return False, ResponseCode.USER_NOT_EXISTS temp = { "is_delete": False } filters = [AppModel.is_delete==False] if user.role != 1: filters.append(AppModel.create_by==user.id) temp.update({ "create_by": user.id }) if "scope" in params and params.get("scope") == "list": result = AppModel.query.filter_by(**temp).order_by(AppModel.create_at.desc()) temp = [] for item in result: temp.append({ "uuid": item.uuid, "app_name": item.app_name }) return temp, ResponseCode.HTTP_SUCCESS elif "scope" in params and params.get("scope") == "distinct": result = db.session.query(AppModel, func.count(distinct(AppModel.name))).all() temp = [] for item in result: temp.append(item) return temp, ResponseCode.HTTP_SUCCESS 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) if result.total and len(result.items): return result, ResponseCode.HTTP_SUCCESS return None, ResponseCode.HTTP_NOT_FOUND def post(self, params, jwt={}): # handle business # 应用打包 # 插入一条打包记录 user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none() 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." algorithm = params.get('algorithm') if algorithm: params.pop("algorithm") 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 = [] epk_path = Path("") if params.get("fileList"): app_files = params.get("fileList") params.pop("fileList") epk_path = params.get("epk_path") params.pop("epk_path") if params.get("logo"): params.pop("logo") real_ip = params.get("real_ip", None) if real_ip: params.pop("real_ip") app = AppModel(**params) db.session.add(app) db.session.commit() logger.info(params) # 在EPK目录下生成JSON文件 epk_path.joinpath("epk.json").write_text(json.dumps(app.to_dict(), ensure_ascii=False), encoding="utf-8") # with open(os.sep.join([os.path.dirname(epk_path), "epk.json"]), "w") as f: # json.dump(app.to_dict(), f) for a in app_files: 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()) db.session.add(res) db.session.flush() db.session.commit() app_info = {} params = { 'appName': app.app_name, 'appDir': epk_path.resolve().as_posix(), 'appVersion': app.app_version, 'output': epk_path.parent.resolve().as_posix() } if user.role == 1: params['algorithm'] ="h" if algorithm: params['algorithm'] = algorithm epk = EpkApp(**params) app_info = epk.pack() epk_filename = epk_path.parent.relative_to(config.UPLOAD_ROOT_DIR).joinpath("{}.epk".format(app.app_name)).as_posix() if app_info: app_info['md5'] = str(app_info['md5']) app.app_file_size = app_info.get("buff_length") app.download_url = epk_filename db.session.commit() 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)) db.session.add(package) db.session.commit() update_information(real_ip, package.id) return True, ResponseCode.HTTP_SUCCESS def put(self, uuid, params, jwt={}): user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none() if not user: return False, ResponseCode.USER_NOT_EXISTS # handle business app = AppModel.query.filter(AppModel.uuid==uuid).first() if not app: return None, ResponseCode.HTTP_NOT_FOUND if params: # 更新文件 if params.get("app_files"): for a in params.get("app_files"): 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()) db.session.add(res) db.session.flush() db.session.commit() params.pop("app_files") # 更新icon if params.get("app_icon") and isinstance(params.get("app_icon"), dict): condition = { 'update_by': user.id, '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") for key, value in params.items(): if value != None: setattr(app, key, value) app.update_by = user.id app.update_date = datetime.now() db.session.commit() return True, ResponseCode.HTTP_SUCCESS else: return False, ResponseCode.HTTP_INVAILD_REQUEST def delete(self, uuid, jwt={}): # handle business result = AppModel.query.filter(AppModel.uuid==uuid).first() if not result: return False, ResponseCode.HTTP_NOT_FOUND result.update_by = jwt.get("id", "") result.update_date = datetime.now() result.is_delete = True db.session.delete(result) db.session.commit() return True, ResponseCode.HTTP_SUCCESS appManager = AppResource()