Commit c0dd2d99 authored by wanli's avatar wanli

更新后端

parent 57c0f668
......@@ -12,10 +12,9 @@ config = dict(
DEBUG=True,
HOST="0.0.0.0",
PORT=5000,
SECRET_KEY='secret_key_EhuqUkwV',
LOGIN_DISABLED=False,
BACKUP_DIR=conf.get('application', 'backup_dir'),
NETDISC=conf.get('uploads', 'netdisc'),
MD5_SALT="EhuqUkwV",
SECRET_KEY='secret_key_EhuqUkwV',
DATABASE=conf.get('database', 'filename'),
DATABASE_FILE=conf.get('scheduler', 'db'),
PONY={
......@@ -24,9 +23,11 @@ config = dict(
'create_db': True,
},
TABLE_PREFIX='evm_store_',
MD5_SALT="EhuqUkwV",
BACKUP_DIR=conf.get('application', 'backup_dir'),
UPLOAD_SERVER="{}://{}:{}/".format(conf.get('uploads', 'protocol'), conf.get('uploads', 'host'), conf.get('uploads', 'port')),
UPLOAD_PATH=os.getcwd(),
EPK_DIR=conf.get('uploads', 'epk_dir'),
TEMP_DIR=conf.get('uploads', 'temp_dir'),
UPLOAD_PATH=os.path.abspath(conf.get('uploads', 'upload_path')),
UPLOAD_DIR=conf.get('uploads', 'upload_dir'),
TEMPLATE_PATH=os.path.join(os.getcwd(), "static"),
STATIC_PATH=os.path.join(os.getcwd(), "static"),
......
......@@ -8,11 +8,8 @@ class SignalManager(object):
actionUpdatePassword = PySignal()
# 上传文件
actionUploadFile = PySignal()
actionBackupDatabase = PySignal()
actionApplicationBuild = PySignal()
# 导入excel
# 导出excel
# 登录模块
actionLogin = PySignal()
......@@ -33,13 +30,6 @@ class SignalManager(object):
actionUpdateBuildLog = PySignal()
actionDeleteBuildLog = PySignal()
# 网盘管理
actionAddNetDisc = PySignal()
actionGetNetDisc = PySignal()
actionGetNetDiscList = PySignal()
actionUpdateNetDisc = PySignal()
actionDeleteNetDisc = PySignal()
# 用户模块
actionAddUser = PySignal()
actionDeleteUser = PySignal()
......
{"lastModifyDateTime": 1618915131}
\ No newline at end of file
......@@ -2,10 +2,11 @@
port = 80
host = store.evmiot.com
protocol = http
upload_path = ./
upload_path = ../../evm_app_store_files
temp_dir = tmp
epk_dir = epks
db_dir = epkdb
upload_dir = uploads
netdisc = netdisc
[database]
provider = sqlite
......
......@@ -21,7 +21,6 @@ logger = logging.getLogger("controller")
def initConnect():
# 系统模块
signalManager.actionUploadFile.connect(uploadManager.upload)
signalManager.actionUpdatePassword.connect(apiManager.update_user_password)
signalManager.actionApplicationBuild.connect(appsManager.build)
......
......@@ -73,7 +73,7 @@ class AppLogsManager(object):
if not editor:
return False, "current user is not exists"
if editor.role == "USER":
if editor.role != "administrator":
temp.update({ 'create_by': editor })
if "scope_type" in data and data.get("scope_type") == "list":
......
......@@ -13,6 +13,7 @@ import traceback
from urllib import parse
from datetime import datetime
from pony.orm import *
from app import signalManager, config
from model import fullStackDB
from model.annex import Annex
......@@ -44,6 +45,7 @@ class AppsManager(object):
# 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,
......@@ -51,52 +53,33 @@ class AppsManager(object):
})
app_files = []
if data.get("app_files"):
app_files = data.get("app_files")
data.pop("app_files")
data.update({ "app_icon": data.get("app_icon").get("filepath") })
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()
target_path = os.sep.join([config.get("UPLOAD_PATH"), config.get("UPLOAD_DIR"), "evueapps", editor.account])
epk_dirname = "{}-{}-{}".format(app.app_name, app.app_version, datetime.now().strftime("%Y%m%d%H%M%S"))
# EPK资源文件临时目录
target_dir = os.path.normpath(os.sep.join([target_path, epk_dirname]))
target_path = os.sep.join([target_dir, "src"])
if not os.path.exists(target_path):
os.makedirs(target_path)
target_files = []
for f in app_files:
filename = os.path.basename(f.get("filepath"))
target_f = copy.deepcopy(f)
name, suffix = os.path.splitext(filename)
name = re.sub(r"_\d{14}$", "", name)
target_filepath = os.sep.join([target_path, name + suffix])
target_f['filepath'] = target_filepath
target_files.append(target_f)
shutil.copy(f.get("filepath"), target_f['filepath'])
os.remove(f.get("filepath"))
# 在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 target_files:
Annex(app=app, 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())
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()
# 打包成EPK文件
app_info = {}
params = { 'appName': app.app_name, 'appDir': target_path, 'appVersion': app.app_version, 'output': target_dir.replace(config.get("UPLOAD_PATH"), "") }
if editor.role == "ADMIN":
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 == "enterprise":
params['algorithm'] ="h"
epk = EpkApp(**params)
app_info = epk.pack()
epk_filename = os.sep.join([target_dir.replace(config.get("UPLOAD_PATH"), ""), "{}.epk".format(app.app_name)]).replace('\\', '/')
epk_filename = os.sep.join([os.path.dirname(epk_path).replace(config.get("UPLOAD_PATH"), ""), "{}.epk".format(app.app_name)]).replace('\\', '/')
app_info['md5'] = str(app_info['md5'])
result = BuildLogs(app=app, app_path=epk_filename, app_info=app_info, create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
......@@ -104,7 +87,7 @@ class AppsManager(object):
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")
return result, "add app {}".format("success" if result else "fail")
def delete(self, user, uuid):
with db_session:
......@@ -119,7 +102,6 @@ class AppsManager(object):
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"
......@@ -141,9 +123,10 @@ class AppsManager(object):
if not source_files:
return None, "apps file not found"
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"), config.get("UPLOAD_DIR"), "evueapps"])
target_dir = os.sep.join([upload_dir, editor.account, dir_format])
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)
......@@ -161,13 +144,13 @@ class AppsManager(object):
shutil.copy(os.path.normpath(target_file), dst_file)
app_files.append([sf.id, dst_file])
# 这里面存在一个逻辑问题,就是将文件拷贝过去之后,需要在Annex表重新生成有感这个EPK文件所有资源文件的记录
# 否则会在下次重新打包时候,找不到相关资源文件报错
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.replace(config.get("UPLOAD_PATH"), "") }
if editor.role == "ADMIN":
params = { 'appName': app.app_name, 'appDir': dest_dir, 'appVersion': app.app_version, 'output': target_dir }
if editor.role == "administrator" or editor.role == "enterprise":
params['algorithm'] = "h"
epk = EpkApp(**params)
app_info = epk.pack()
......@@ -175,7 +158,6 @@ class AppsManager(object):
# 更新数据库对应文件路径
# 将文件拷贝过去后,需要重新更新数据库文件记录
epk_path = os.sep.join([target_dir.replace(config.get("UPLOAD_PATH"), ""), "{}.epk".format(app.app_name)]).replace('\\', '/')
build = BuildLogs.get(app=app)
......@@ -206,7 +188,7 @@ class AppsManager(object):
if not editor:
return False, "current user is not exists"
if editor.role == "ADMIN":
if editor.role == "administrator":
temp.update({"is_delete": False})
else:
temp.update({ "create_by": editor, "is_delete": False })
......@@ -319,7 +301,7 @@ class AppsManager(object):
# 打包成EPK文件
app_info = {}
params = { 'appName': app.app_name, 'appDir': dest_dir, 'appVersion': app.app_version, 'output': target_dir.replace(config.get("UPLOAD_PATH"), "") }
if user.role == "ADMIN":
if user.role == "administrator" or user.role == "enterprise":
params['algorithm'] = "h"
epk = EpkApp(**params)
app_info = epk.pack()
......
......@@ -68,7 +68,7 @@ class BuildLogsManager(object):
# 打包成EPK文件
app_info = {}
params = { 'appName': app.app_name, 'appDir': dest_dir, 'appVersion': app.app_version, 'output': target_dir.replace(config.get("UPLOAD_PATH"), "") }
if editor.role == "ADMIN":
if editor.role == "administrator" or editor.role == "enterprise":
params['algorithm'] = "h"
epk = EpkApp(**params)
app_info = epk.pack()
......@@ -137,10 +137,10 @@ class BuildLogsManager(object):
if not editor:
return False, "current user is not exists"
if editor.role == "USER":
temp.update({"create_by": editor, "is_delete": False})
else:
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 = BuildLogs.select().where(**temp).order_by(desc(BuildLogs.create_at))
......
......@@ -73,11 +73,10 @@ class DeviceManager(object):
if not editor:
return False, "current user is not exists"
if editor.role == "ADMIN":
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 = Device.select().where(**temp).order_by(desc(Device.create_at))
......
......@@ -19,7 +19,6 @@ from urllib import parse
from datetime import datetime
from threading import Thread
from werkzeug.security import check_password_hash
from flask import request
from app.setting import config
from utils import md5_salt, random_string
......@@ -114,45 +113,6 @@ class UploadManager(object):
"message": "upload file [%s] failed!\n %s" % (obj['path'], repr(e))
}
def upload(self):
try:
binfile = request.files.get("binfile")
if not binfile:
return None, "file can not be null"
obj = dict()
obj['filename'] = binfile.filename
obj['content'] = binfile.stream.read()
# 目录结构:模块类型/年/月/项目名/文件名_时间日期.文件后缀
# 模块类型:项目管理模块、资质管理模块
filename = os.path.splitext(obj['filename'])[0] + "_{}".format(datetime.now().strftime("%Y%m%d%H%M%S")) + os.path.splitext(obj['filename'])[-1]
# 获取相对路径
relative_path = config.get("UPLOAD_DIR")
# 获取最终存储的绝对路径
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'])
return {
"uuid": str(uuid.uuid4()), # 附件唯一编号
"filename": obj['filename'], # 附件名称
"filesize": os.path.getsize(saveFile), # 附件大小
"filepath": os.sep.join([relative_path, filename]).replace("\\", "/"), # 附件存储路径
}, "upload file [%s] successfully!" % obj['filename']
except Exception as e: # repr(e)
traceback.print_exc()
logger.error(str(e))
return None, repr(e)
def delete(self, data):
try:
isAccessed, path = checkPath(data["path"])
......
This diff is collapsed.
#!/usr/bin/env bash
# 获取当前路径
Cur_Dir=$(pwd)
# 关闭evm_store
supervisorctl stop evm_store
# 切换到release分支
git checkout release
# 拉取最新代码
git pull
# 启动evm_store
supervisorctl start evm_store
# 启动一个定时任务
# cd $Cur_Dir
# source venv/bin/activate
# 0 */1 * * * "${Cur_Dir}/venv/bin/python deploy.py"
......@@ -13,7 +13,7 @@ class User(db.Entity):
_table_ = "{}".format(config['TABLE_PREFIX']) + "user"
id = PrimaryKey(int, auto=True)
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
role = Required(str, default="USER") # 角色
role = Required(str, default="community") # 角色,管理员[administrator]、企业用户[enterprise]、社区用户[community]
account = Required(str, unique=True) # 账号
username = Required(str, max_len=100) # 用户名
password = Required(str, max_len=64) # 密码
......
{
"count": 84
}
\ No newline at end of file
#!/usr/bin/env bash
source venv/bin/activate
python start.py
\ No newline at end of file
......@@ -5,11 +5,10 @@ from marshmallow import fields, validate, RAISE, INCLUDE, EXCLUDE
class AddSchema(BaseSchema):
app_name = fields.String(required=True)
app_version = fields.String(required=False)
app_icon = fields.Dict(required=True)
app_url = fields.String(required=False)
category = fields.String(required=False)
app_desc = fields.String(required=False)
app_files = fields.List(fields.Dict, required=False)
category = fields.String(required=False)
logo = fields.Raw(required=False)
fileList = fields.List(fields.Raw, required=False)
sort = fields.Int(required=False, default=0)
class Meta:
......@@ -18,11 +17,8 @@ class AddSchema(BaseSchema):
class UpdateSchema(BaseSchema):
app_name = fields.String(required=False)
app_version = fields.String(required=False)
app_icon = fields.Dict(required=True)
app_url = fields.String(required=False)
category = fields.String(required=False)
app_desc = fields.String(required=False)
app_files = fields.List(fields.Dict, required=False)
category = fields.String(required=False)
sort = fields.Int(required=False)
class Meta:
......
......@@ -61,15 +61,11 @@ class EpkApp(object):
self._appName = appName
self._appDir = os.path.abspath(appDir)
self.algorithm = algorithm
print(sys.argv)
print(appName)
print(appDir)
print(self._appDir)
self._appVersion = appVersion
self._appCRCCode = None
self._files = []
self._infoPath = os.sep.join([self._appDir, "%s.json" % self._appName])
self._epksDir = os.sep.join([os.getcwd(), output])
self._epksDir = output
if not os.path.exists(self._epksDir):
fs.open_fs(os.getcwd()).makedirs(output)
self._epkName = os.sep.join([self._epksDir, "%s.epk" % self._appName])
......@@ -100,10 +96,9 @@ class EpkApp(object):
fpath = "C:/%s" % jspath.info.name
fname = jspath.info.name
fsize = jspath.info.size
fbasename = jspath.info.name.split(".")[0]
fext = jspath.info.name.split(".")[1]
fbasename, fext = os.path.splitext(jspath.info.name)
if fext in ["exe", "dll", "nv", "conf"]:
if fext in ["", "exe", "dll", "nv", "conf"]:
continue
finfo = {
......@@ -115,7 +110,6 @@ class EpkApp(object):
}
if self._infoPath == os.sep.join([path, fname]):
print(finfo)
files.insert(0, finfo)
else:
files.append(finfo)
......@@ -126,11 +120,8 @@ class EpkApp(object):
return files
def header(self, epk_start=0xAAAA, md5_offset=0, file_count=0):
bytes_header = struct.pack("<HLH", epk_start, md5_offset, file_count)
return bytes_header
def fileMD5(self, info):
md5path = os.sep.join([self._appDir, "%s.md5" % info["basename"]])
......@@ -158,7 +149,6 @@ class EpkApp(object):
md5 = hashlib.md5() #获取一个md5加密算法对象
md5.update(content) #指定需要加密的字符串
newmd5 = md5.hexdigest() #获取加密后的16进制字符串
print("md5 == ",newmd5)
content = self.sign(newmd5)
ret = b""
......@@ -172,7 +162,6 @@ class EpkApp(object):
fpath = os.sep.join([self._appDir, fname])
fext = info["ext"]
fileBytes = b""
if fext == "md5":
fileBytes += struct.pack("<B", 1)
......@@ -185,8 +174,6 @@ class EpkApp(object):
fileBytes += struct.pack("<%ds" % len(_name), fname.encode("utf-8"))
with open(fpath, "rb") as fc:
fileContentBytes = fc.read()
print(info["name"])
print(len(fileContentBytes))
fileBytes += struct.pack("<L", len(fileContentBytes))
if fext == "md5":
......@@ -194,14 +181,8 @@ class EpkApp(object):
else:
fileCompressBytes = self.compress()(fileContentBytes, level)
print("===",fileCompressBytes[0])
print(fileCompressBytes)
fileBytes += struct.pack("<L", len(fileCompressBytes))
print(fileBytes)
fileBytes += fileCompressBytes
return fileBytes
def pack(self, level=9):
......@@ -216,24 +197,16 @@ class EpkApp(object):
with open(self._epkName, "wb") as f:
for info in infos["files"]:
epkFileContentBytes += self.packFile(info)
epkFileContentLength = len(epkFileContentBytes)
epkFileBytes += self.header(md5_offset= 8 + epkFileContentLength, file_count=file_count)
epkFileBytes += epkFileContentBytes
epkmd5Bytes = self.md5(epkFileBytes)
epkFileBytes += struct.pack("<H", len(epkmd5Bytes))
epkFileBytes += epkmd5Bytes
crcBytes = zlib.crc32(epkFileBytes)
epkFileBytes += struct.pack("<L", crcBytes)
f.write(epkFileBytes)
ret = {
......
......@@ -12,7 +12,7 @@ from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.annex import AddSchema, DeleteSchema, QuerySchema, UpdateSchema, ResponseSchema
logger = logging.getLogger("annexApi")
logger = logging.getLogger(__name__)
annex_api = Blueprint("annex_api", __name__, url_prefix="/api/v1/%s/annex" % config['NAME'])
......
......@@ -2,13 +2,14 @@
# -*- coding: utf_8 -*-
import os
import json
import datetime
import logging
import traceback
import uuid
from datetime import datetime
from flask import Blueprint, request, redirect, url_for, json, Response, send_file, make_response, send_from_directory
from werkzeug.utils import secure_filename
from app import config, signalManager
from app.setting import conf
from fullstack.login import Auth
......@@ -16,10 +17,13 @@ from fullstack.response import ResponseCode, response_result
from fullstack.validation import validate_schema
from schema.api import UpdatePasswordSchema, ApplicationBuildSchema
logger = logging.getLogger("api")
logger = logging.getLogger(__name__)
api = Blueprint("api", __name__, url_prefix="/api/v1/%s" % config['NAME'])
logger.info(config.get("UPLOAD_PATH"))
logger.info(os.path.abspath(config.get("UPLOAD_PATH")))
def stopApp():
fpath = os.sep.join([os.getcwd(), "restart.json"])
with open(fpath, "w+") as f:
......@@ -47,11 +51,45 @@ def update_password():
@api.route("/upload", methods=['POST']) # 上传文件
def upload_file():
try:
result, message = signalManager.actionUploadFile.emit()
if result:
return response_result(ResponseCode.OK, data=result, msg=message)
else:
result = None
message = None
binfile = request.files.get("binfile")
if not binfile:
return response_result(ResponseCode.REQUEST_ERROR, msg=message)
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), # 附件大小
"filepath": os.sep.join([config.get("UPLOAD_DIR"), relative_path, filename]).replace("\\", "/"), # 附件存储路径
}, "upload file [%s] successfully!" % obj['filename']
return response_result(ResponseCode.OK, data=result)
except Exception as e:
traceback.print_exc()
logger.error(str(e))
......@@ -79,7 +117,6 @@ def application_build():
os.makedirs(upload_path)
for f in request.files.getlist('binfiles'):
filename = secure_filename(f.filename)
print(filename)
file_path = os.sep.join([upload_path, filename])
f.save(file_path)
files.append(file_path)
......
......@@ -12,7 +12,7 @@ from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.app_logs import AddSchema, DeleteSchema, QuerySchema, UpdateSchema, ResponseSchema
logger = logging.getLogger("appLogsApi")
logger = logging.getLogger(__name__)
appLogs_api = Blueprint("appLogs_api", __name__, url_prefix="/api/v1/%s/appLogs" % config['NAME'])
......
......@@ -2,10 +2,13 @@
# -*- coding: utf_8 -*-
import os
import json
import datetime
import logging
import traceback
from datetime import datetime
from flask import Blueprint, request
from werkzeug.utils import secure_filename
from app import config, signalManager
from fullstack.login import Auth
from fullstack.validation import validate_schema
......@@ -13,7 +16,7 @@ from fullstack.response import ResponseCode, response_result
from schema.apps import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
from schema.build_logs import AddSchema as LogAddScheme, QuerySchema as LogQuerySchema
logger = logging.getLogger("appsApi")
logger = logging.getLogger(__name__)
apps_api = Blueprint("apps_api", __name__, url_prefix="/api/v1/%s/apps" % config['NAME'])
......@@ -22,8 +25,48 @@ apps_api = Blueprint("apps_api", __name__, url_prefix="/api/v1/%s/apps" % config
@Auth.auth_required
def add():
try:
params = request.schema_data
dtNowString = datetime.now().strftime("%Y%m%d%H%M%S")
# 获取相对路径
dirname = "{}-{}-{}-{}".format(params["app_name"], params["app_version"], params["category"], dtNowString)
relative_path = os.sep.join([config.get("EPK_DIR"), dirname])
# 获取最终存储的绝对路径
upload_path = os.path.normpath(os.sep.join([config.get("UPLOAD_PATH"), relative_path]))
if not os.path.exists(upload_path):
os.makedirs(upload_path)
files = []
logo = request.files.get("logo")
if logo:
filename = secure_filename(logo.filename)
file_path = os.sep.join([upload_path, filename])
file_path = os.path.normpath(file_path)
logo.save(file_path)
params.update({ "app_icon": file_path })
fileList = request.files.getlist('fileList')
if fileList:
upload_path = os.sep.join([upload_path, "src"])
if not os.path.exists(upload_path):
os.mkdir(upload_path)
for f in fileList:
filename = secure_filename(f.filename)
file_path = os.sep.join([upload_path, filename])
file_path = os.path.normpath(file_path)
f.save(file_path)
files.append(file_path)
# obj = dict()
# obj['filename'] = binfile.filename
# obj['content'] = binfile.stream.read()
params.update({ "fileList": files, "epk_path": upload_path })
user = request.current_user.get("id")
isSuccess, message = signalManager.actionAddApp.emit(user, request.schema_data)
isSuccess, message = signalManager.actionAddApp.emit(user, params)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
......@@ -33,7 +76,6 @@ def add():
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR, msg=str(e))
@apps_api.route("/delete/<uuid:id>", methods=['POST'])
@Auth.auth_required
def delete(id):
......@@ -49,7 +91,6 @@ def delete(id):
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR)
@apps_api.route("/get", methods=["POST"])
@validate_schema(QuerySchema)
@Auth.auth_required
......@@ -82,7 +123,6 @@ def get_list():
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR)
@apps_api.route("/update/<uuid:id>", methods=['POST'])
@validate_schema(UpdateSchema)
@Auth.auth_required
......
......@@ -12,7 +12,7 @@ from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.device import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
logger = logging.getLogger("deviceApi")
logger = logging.getLogger(__name__)
device_api = Blueprint("device_api", __name__, url_prefix="/api/v1/%s/device" % config['NAME'])
......
......@@ -12,7 +12,7 @@ from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.download import AddSchema, DeleteSchema, QuerySchema, UpdateSchema, DownloadSchema
logger = logging.getLogger("DownloadApi")
logger = logging.getLogger(__name__)
download_api = Blueprint("download_api", __name__, url_prefix="/api/v1/%s/download" % config['NAME'])
......
......@@ -9,21 +9,15 @@ import tempfile
import shutil
import base64
import logging
from hashlib import md5 as fmd5
from flask import Blueprint, request, redirect, url_for, json
from app.setting import config
if ((3, 0) <= sys.version_info <= (3, 10)):
from hashlib import md5 as fmd5
elif ((2, 0) <= sys.version_info <= (2, 10)):
import md5
fmd5 = md5.new
logger = logging.getLogger("filesApi")
logger = logging.getLogger(__name__)
file_api = Blueprint("file_api", __name__, url_prefix="/api/v1/file")
FileStoragePath = os.path.join(config.get("UPLOAD_PATH"), config.get("NETDISC"))
FileStoragePath = os.path.join(config.get("UPLOAD_PATH"))
def ajaxCheckAcess(path):
realpath = os.path.realpath(path)
......
......@@ -9,7 +9,7 @@ from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.login import LoginSchema, RegisterSchema
logger = logging.getLogger("loginApi")
logger = logging.getLogger(__name__)
login_api = Blueprint("login_api", __name__, url_prefix="/api/v1/%s/login" % config['NAME'])
......
......@@ -13,7 +13,7 @@ from fullstack.response import ResponseCode, response_result
from schema.netdisc import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
from utils import random_string
logger = logging.getLogger("netdiscApi")
logger = logging.getLogger(__name__)
netdisc_api = Blueprint("netdisc_api", __name__, url_prefix="/api/v1/%s/netdisc" % config['NAME'])
......
......@@ -10,7 +10,7 @@ from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.user import AddSchema, DeleteSchema, UpdateSchema, QuerySchema, ResponseSchema
logger = logging.getLogger("userApi")
logger = logging.getLogger(__name__)
user_api = Blueprint("user_api", __name__, url_prefix="/api/v1/%s/user" % config['NAME'])
......
......@@ -8,9 +8,9 @@
>
</el-form>
<el-table
:data="list"
v-loading="isLoading"
element-loading-text="Loading"
:data="list"
size="mini"
border
stripe
......@@ -32,11 +32,6 @@
label="应用类别"
width="120"
></el-table-column>
<el-table-column
prop="app_url"
label="应用路径"
width="120"
></el-table-column>
<el-table-column
prop="epk_size"
label="应用大小"
......@@ -137,13 +132,6 @@
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="应用路径" prop="app_url">
<el-input
type="text"
v-model="post.app_url"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="应用类别" prop="category">
<el-input
type="text"
......@@ -161,12 +149,15 @@
<el-form-item label="应用Logo" prop="app_icon">
<el-upload
class="avatar-uploader"
ref="icon"
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
name="binfile"
:on-remove="handleAvatarRemove"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
ref="logo"
name="logo"
accept="image/*"
action="null"
:auto-upload="false"
:http-request="handleUploadLogo"
:on-remove="handleLogoRemove"
:on-change="handleLogoChange"
:before-upload="beforeLogoUpload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
......@@ -175,12 +166,13 @@
<el-form-item label="应用文件" prop="app_files">
<el-upload
drag
ref="upload"
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
multiple
name="binfile"
ref="upload"
name="binfiles"
action="null"
:auto-upload="false"
:http-request="handleUploadFile"
:on-remove="handleUploadRemove"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
......@@ -228,7 +220,6 @@ export default {
imageUrl: "",
total: 0,
list: [],
fileList: [],
isLoading: false,
form: {
uuid: null,
......@@ -245,10 +236,11 @@ export default {
app_name: "evue_launcher",
app_version: "1.0",
app_icon: null,
app_url: "evue_launcher",
category: "tools",
app_desc: "启动器",
app_files: [],
logo: null,
fileList: [],
},
};
},
......@@ -261,7 +253,7 @@ export default {
this.post.app_icon = null;
this.post.app_files = [];
this.$refs.upload.clearFiles();
this.$refs.icon.clearFiles();
this.$refs.logo.clearFiles();
},
fetchData(params) {
this.isLoading = true;
......@@ -271,7 +263,8 @@ export default {
this.list = res.data.map((item) => {
if (item.app_build_log && item.app_build_log.app_info)
item.epk_size =
(item.app_build_log.app_info.buff_length / 1024).toFixed(2) + "KB";
(item.app_build_log.app_info.buff_length / 1024).toFixed(2) +
"KB";
else item.epk_size = "";
return item;
});
......@@ -292,21 +285,22 @@ export default {
this.fetchData(mapTrim(this.form));
},
handleRebuild(index, row) {
console.log(index)
rebuildApp({ uuid: row.uuid }).then(res => {
// download(`${res.data.app_name}.epk`, res.data.app_path)
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
rebuildApp({ uuid: row.uuid })
.then((res) => {
this.$message.success(res.message);
})
.catch((err) => {
this.$message.error(err.message);
});
},
handleBuild(index, row) {
console.log(index)
getBuildApp(row.uuid).then((res) => {
download(`${res.data.app_name}.epk`, res.data.app_path)
this.$message.success(res.message)
}).catch((err) => {
this.$message.error(err.message)
getBuildApp(row.uuid)
.then((res) => {
download(`${res.data.app_name}.epk`, res.data.app_path);
this.$message.success(res.message);
})
.catch((err) => {
this.$message.error(err.message);
});
},
handleEdit(index, row) {
......@@ -342,68 +336,82 @@ export default {
}
);
},
handleUploadSuccess(res) {
if (res.code == 200) this.post.app_files.push(res.data);
handleUploadLogo(file) {
this.post.logo = file;
},
handleAvatarSuccess(res, file) {
if (res.code == 200) this.post.app_icon = res.data;
this.imageUrl = URL.createObjectURL(file.raw);
handleUploadFile(file) {
this.post.fileList.push(file);
},
beforeAvatarUpload() {
// const isJPG = file.type === "image/jpeg";
// const isLt2M = file.size / 1024 / 1024 < 2;
// if (!isJPG) {
// this.$message.error("上传头像图片只能是 JPG 格式!");
// }
// if (!isLt2M) {
// this.$message.error("上传头像图片大小不能超过 2MB!");
// }
// return isJPG && isLt2M;
return true;
},
handleAvatarRemove(file) {
console.log(file);
this.imageUrl = null;
},
handleRemove(file) {
handleUploadRemove(file, fileList) {
console.log(file, fileList);
for (let i = 0; i < this.post.app_files.length; i++) {
if (this.post.app_files[i].uuid == file.response.data.uuid) {
this.post.app_files.splice(i, 1);
break;
}
}
console.log(file);
// this.post.app_files = fileList;
},
handleFrameworkRemove() {},
handleFrameworkSuccess(res) {
this.framework.assets.files.push(res.data);
handleLogoChange(file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
beforeLogoUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
}
return isLt2M;
},
handleLogoRemove(file) {
console.log(file);
this.imageUrl = null;
this.post.logo = file.file;
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true;
if (valid) {
if (this.dialogTitle === "添加")
addApp(mapTrim(this.post))
.then((res) => {
console.log(res);
this.$message({ type: "success", message: "添加成功" });
if (this.dialogTitle === "添加") {
this.$refs.upload.submit(); // 调用这个upload组件该方法才会执行http-request回调
this.$refs.logo.submit();
let formData = new FormData();
this.post.fileList.forEach(item => {
formData.append("fileList", item.file)
});
formData.append("logo", this.post.logo.file)
Object.keys(this.post).forEach(k => {
if (this.post[k] && typeof this.post[k] !== "object") {
formData.append(k, this.post[k])
}
});
addApp(formData).then((res) => {
this.$message({
type: "success",
message: `添加成功:${res.message}`,
});
this.fetchData(mapTrim(this.form));
})
.catch((err) => {
this.$message.error(err.message);
});
else if (this.dialogTitle === "编辑")
});
}
else if (this.dialogTitle === "编辑") {
updateApp(this.currentValue.uuid, this.post)
.then((res) => {
console.log(res);
// this.$set(this.list, this.currentIndex, Object.assign(this.currentValue, tmp))
this.$message({ type: "success", message: "更新成功" });
this.$message({
type: "success",
message: `更新成功:${res.message}`,
});
this.fetchData(mapTrim(this.form));
})
.catch((err) => {
this.$message.error(err.message);
});
}
} else {
result = false;
}
......@@ -412,12 +420,10 @@ export default {
});
},
onAdd() {
setTimeout(() => {
this.clear();
}, 100)
this.post.sort = this.form.pagesize * (this.form.pagenum - 1) + this.list.length + 1
this.dialogTitle = "添加"
this.dialogVisible = true
setTimeout(() => { this.clear(); }, 100);
this.post.sort = this.form.pagesize * (this.form.pagenum - 1) + this.list.length + 1;
this.dialogTitle = "添加";
this.dialogVisible = true;
},
onSubmit() {
this.form.pagenum = 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment