#!/usr/bin/env python # -*- coding: utf_8 -*- import os import re import shutil import copy import json import logging from urllib import parse from datetime import datetime from pony.orm import * from app import signalManager, config from model.annex import Annex from model.apps import Apps from model.user import User from model.app_logs import AppLogs from model.build_logs import BuildLogs from utils import sql_filter, ThreadMaker from utils.epk import EpkApp logger = logging.getLogger("AppsManager") @ThreadMaker def build_application(user, uuid): signalManager.actionAddBuildLog.emit(user, uuid, isMove=False) class AppsManager(object): def __init__(self): super(AppsManager, self).__init__() def add(self, user, data): with db_session: editor = User.get(id=user) if not editor: return False, "current user is not exists" # result = Apps.select(app_name=data.get("app_name"), is_delete=False).count() # if result < 1: # return False, "app_name has been exists." data.update({ 'app_icon': data["app_icon"].replace(config.get("UPLOAD_PATH"), ""), 'create_by': editor, 'create_at': datetime.now(), 'update_by': editor, 'update_at': datetime.now(), }) app_files = [] epk_path = "" if data.get("fileList"): app_files = data.get("fileList") data.pop("fileList") epk_path = data.get("epk_path") data.pop("epk_path") app = Apps(**data) commit() # 在EPK目录下生成JSON文件 with open(os.sep.join([os.path.dirname(epk_path), "epk.json"]), "w") as f: json.dump(app.to_dict(exclude=["uuid", "create_at", "update_at", "delete_at"]), f) for a in app_files: Annex(app=app, title=os.path.basename(a), path=a, size=os.path.getsize(a), create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now()) flush() commit() app_info = {} params = { 'appName': app.app_name, 'appDir': epk_path, 'appVersion': app.app_version, 'output': os.path.dirname(epk_path) } if editor.role == "administrator" or editor.role == "community": params['algorithm'] ="h" epk = EpkApp(**params) app_info = epk.pack() epk_filename = os.sep.join([os.path.dirname(epk_path).replace(config.get("UPLOAD_PATH"), ""), "{}.epk".format(app.app_name)]).replace('\\', '/') if app_info: app_info['md5'] = str(app_info['md5']) result = BuildLogs(app=app, app_path=epk_filename, app_info=app_info, source=1, create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now()) commit() AppLogs(app_name=app.app_name, app_path=epk_filename, app_version=data.get("app_version"), app_info=app_info, create_by=editor, create_at=datetime.now()) commit() return result, "add app {}".format("success" if result else "fail") def delete(self, user, uuid): with db_session: editor = User.get(id=user) if not editor: return False, "current user is not exists" result = Apps.get(uuid=uuid) if result: result.delete() return result, "delete app {}.".format("success" if result else "fail") def get(self, user, data): if not data.get("uuid"): return False, "app uuid can not be null" with db_session: editor = User.get(id=user) if not editor: return False, "current user is not exists" # 根据app查询应用,获取应用有哪些文件 # 按格式创建文件夹,将这些文件移动到这个文件夹 # 将这些零散文件进行打包 # 更新数据库对应文件的路径 app = Apps.get(uuid=data.get("uuid")) if not app: return None, "app not found" source_files = Annex.select().filter(app=app) if not source_files: return None, "apps file not found" dtNowString = datetime.now().strftime("%Y%m%d%H%M%S") dirname = "{}-{}-{}-{}".format(app.app_name, app.app_version, app.category, dtNowString) upload_dir = os.sep.join([config.get("UPLOAD_PATH"), config.get("EPK_DIR")]) target_dir = os.sep.join([upload_dir, dirname]) dest_dir = os.sep.join([target_dir, "src"]) if not os.path.exists(dest_dir): os.makedirs(dest_dir) app_files = [] for sf in source_files: target_file = sf.path if not os.path.exists(sf.path): target_file = os.sep.join([config.get("UPLOAD_PATH"), sf.path]) filename = os.path.basename(target_file) name, suffix = os.path.splitext(filename) name = re.sub(r"_\d{14}$", "", name) dst_file = os.path.normpath(os.sep.join([dest_dir, name + suffix])) shutil.copy(os.path.normpath(target_file), dst_file) app_files.append([sf.id, dst_file]) with open(os.sep.join([target_dir, "epk.json"]), "w") as f: json.dump(app.to_dict(exclude=["uuid", "create_at", "update_at", "delete_at"]), f) # 打包成EPK文件 app_info = {} params = { 'appName': app.app_name, 'appDir': dest_dir, 'appVersion': app.app_version, 'output': target_dir } if editor.role == "administrator" or editor.role == "community": params['algorithm'] = "h" epk = EpkApp(**params) app_info = epk.pack() app_info['md5'] = str(app_info['md5']) # 更新数据库对应文件路径 # 将文件拷贝过去后,需要重新更新数据库文件记录 epk_path = os.sep.join([target_dir.replace(config.get("UPLOAD_PATH"), ""), "{}.epk".format(app.app_name)]).replace('\\', '/') build = BuildLogs.get(app=app) if build: build.set(app_path=epk_path, app_info=app_info, update_by=editor, update_at=datetime.now()) commit() # 新增一条AppLogs AppLogs(app_name=app.app_name, app_path=epk_path, app_version=app.app_version, app_info=app_info, create_by=editor, create_at=datetime.now()) commit() return { 'app_name': app.app_name, 'app_path': epk_path }, "rebuild app {}.".format("success" if app_info else "fail") def getList(self, user, data): if not data or len(data) <= 0: return False, 0, "parameters can not be null." temp = copy.deepcopy(data) if 'pagenum' in temp: temp.pop('pagenum') if 'pagesize' in temp: temp.pop('pagesize') if 'scope_type' in temp: temp.pop('scope_type') with db_session: editor = User.get(id=user) if not editor: return False, "current user is not exists" if editor.role == "administrator": temp.update({"is_delete": False}) else: temp.update({ "create_by": editor, "is_delete": False }) if "scope_type" in data and data.get("scope_type") == "list": result = Apps.select().where(**temp).order_by(desc(Apps.create_at)) temp = [] for item in result: temp.append(item.to_dict(only=["uuid", "app_name"])) return temp, len(temp), "get app {}.".format("success" if temp else "fail") elif "scope_type" in data and data.get("scope_type") == "distinct": result = select(p.category for p in Apps) temp = [] for item in result: temp.append(item) return temp, len(temp), "success" result = Apps.select().where(**temp).order_by(Apps.sort).sort_by(desc(Apps.create_at)).page(data.get("pagenum", 1), pagesize=data.get("pagesize", 10)) count = Apps.select().where(**temp).count() if result and len(result): temp = [] for item in result: t = item.to_dict(with_collections=True, related_objects=True, exclude=["app_annex", "app_download", "is_delete", "delete_by", "delete_at"]) t.update({ "app_build_log": item.app_build_log.to_dict(exclude=["is_delete", "delete_by", "delete_at", "create_by", "update_by"]) if item.app_build_log else None, "create_by": item.create_by.to_dict(only=["uuid", "username"]), "update_by": item.update_by.to_dict(only=["uuid", "username"]), "create_at": item.create_at.strftime("%Y-%m-%d %H:%M:%S") if item.create_at else None, "update_at": item.update_at.strftime("%Y-%m-%d %H:%M:%S") if item.update_at else None, }) temp.append(t) result = temp return result, count, "get app {}.".format("success" if result else "no data") def update(self, user, uuid, data): # 当参数为空时,直接返回错误 if len(data) <= 0 or (len(data.keys()) == 1 and "id" in data): return False, "app can not be null." with db_session: editor = User.get(id=user) if not editor: return False, "current user is not exists" result = Apps.get(uuid=uuid) if not result: return False, "app not found" if data.get("app_files"): app_files = data.get("app_files") for a in app_files: Annex(app=result, title=a.get("filename"), path=a.get("filepath"), size=a.get("filesize"), create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now()) flush() commit() data.pop("app_files") if data.get("app_icon"): condition = { 'update_by': editor, 'update_at': datetime.now() } if data.get("app_icon").get("filename"): condition.update({"title": data.get("app_icon").get("filename")}) if data.get("app_icon").get("filepath"): condition.update({"path": data.get("app_icon").get("filepath")}) if data.get("app_icon").get("filesize"): condition.update({"size": data.get("app_icon").get("filesize")}) result.app_icon.set(**condition) commit() data.pop("app_icon") result.set(update_at=datetime.now(), update_by=editor, **data) commit() build_application(user, str(result.uuid)) return result, "update app {}.".format("success" if result else "fail") def build(self, files, data): with db_session: user = User.get(uuid=data['access_key']) if not user: return False, "user does not exists" if data.get("access_key"): data.pop("access_key") data.update({ 'create_by': user, 'create_at': datetime.now(), 'update_by': user, 'update_at': datetime.now(), }) app = Apps(**data) commit() dir_format = "{}-{}-{}".format(app.app_name, app.app_version, datetime.now().strftime("%Y%m%d%H%M%S")) upload_dir = os.sep.join([config.get("UPLOAD_PATH"), "evueapps"]) target_dir = os.sep.join([upload_dir, user.account, dir_format]) dest_dir = os.sep.join([target_dir, "src"]) if not os.path.exists(dest_dir): os.makedirs(dest_dir) for target_file in files: filename = os.path.basename(target_file) name, suffix = os.path.splitext(filename) name = re.sub(r"_\d{14}$", "", name) dst_file = os.path.normpath(os.sep.join([dest_dir, name + suffix])) shutil.copy(os.path.normpath(target_file), dst_file) Annex(app=app, title=filename, path=dst_file.replace(config.get("UPLOAD_PATH"), ""), size=os.path.getsize(dst_file), create_by=user, create_at=datetime.now(), update_by=user, update_at=datetime.now()) flush() commit() # 打包成EPK文件 app_info = {} params = { 'appName': app.app_name, 'appDir': dest_dir, 'appVersion': app.app_version, 'output': target_dir } if user.role == "administrator" or user.role == "community": params['algorithm'] = "h" epk = EpkApp(**params) app_info = epk.pack() app_info['md5'] = str(app_info['md5']) # 更新数据库对应文件路径 # 将文件拷贝过去后,需要重新更新数据库文件记录 epk_path = os.sep.join([target_dir.replace(config.get("UPLOAD_PATH"), ""), "{}.epk".format(app.app_name)]).replace('\\', '/') build = BuildLogs.get(app=app) if build: build.set(app_path=epk_path, app_info=app_info, update_by=user, update_at=datetime.now()) commit() else: BuildLogs(app=app, app_path=epk_path, app_info=app_info, source=2, create_by=user, create_at=datetime.now(), update_by=user, update_at=datetime.now()) commit() # 新增一条AppLogs AppLogs(app_name=app.app_name, app_path=epk_path, app_version=app.app_version, app_info=app_info, create_by=user, create_at=datetime.now()) commit() with open(os.sep.join([target_dir, "epk.json"]), "w") as f: json.dump(app.to_dict(exclude=["uuid", "create_at", "update_at", "delete_at"]), f) return { 'app_name': app.app_name, 'app_file': "{}.epk".format(app.app_name), 'app_url': parse.urljoin(config['UPLOAD_SERVER'], epk_path) }, "application build {}.".format("success" if app_info else "fail") appsManager = AppsManager()