Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
92ef815d0d | |||
ffc2ff6808 | |||
bcbd556e7d |
11 changed files with 113 additions and 35 deletions
14
README.md
14
README.md
|
@ -2,14 +2,24 @@
|
||||||
|
|
||||||
## 开发环境
|
## 开发环境
|
||||||
|
|
||||||
目前只有 `pywebview` 一个依赖。
|
安装 `pip-tools`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install pip-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip-sync requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
## 打包
|
## 打包
|
||||||
|
|
||||||
前端运行 `npm run build` 生成 `ui/dist`,之后安装 PyInstaller,运行
|
前端运行 `npm run build` 生成 `ui/dist`,之后安装 PyInstaller,运行
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pyinstaller -w --add-data "ui/dist:ui/dist" --add-data "launcher/sys_config/config_dist.yaml:launcher/sys_config" launcher.py
|
pyinstaller -w --add-data "ui/dist:ui/dist" --add-data "launcher/sys_config/config_dist.json:launcher/sys_config" launcher.py
|
||||||
```
|
```
|
||||||
|
|
||||||
在dist文件夹生成launcher文件夹
|
在dist文件夹生成launcher文件夹
|
||||||
|
|
|
@ -2,9 +2,6 @@ import json
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import yaml
|
|
||||||
from yamlcore import CoreLoader
|
|
||||||
|
|
||||||
from launcher.config.conf import Conf
|
from launcher.config.conf import Conf
|
||||||
|
|
||||||
conf_path = Path(os.path.join(os.getcwd(), "conf.json"))
|
conf_path = Path(os.path.join(os.getcwd(), "conf.json"))
|
||||||
|
@ -22,8 +19,8 @@ def load_conf():
|
||||||
conf = Conf()
|
conf = Conf()
|
||||||
save_conf()
|
save_conf()
|
||||||
return
|
return
|
||||||
with conf_path.open("r", encoding="utf-8") as f:
|
with conf_path.open("r", encoding="utf-8") as file:
|
||||||
data = yaml.load(f, Loader=CoreLoader)
|
data = json.load(file)
|
||||||
if data is None:
|
if data is None:
|
||||||
data = {}
|
data = {}
|
||||||
conf = Conf(**data)
|
conf = Conf(**data)
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
|
|
||||||
class SysConfig:
|
class SysConfig:
|
||||||
"""
|
"""
|
||||||
|
@ -26,13 +25,13 @@ class SysConfig:
|
||||||
# 如果是打包后的可执行文件
|
# 如果是打包后的可执行文件
|
||||||
base_path = sys._MEIPASS
|
base_path = sys._MEIPASS
|
||||||
config_subdir = 'launcher/sys_config' # 添加子目录
|
config_subdir = 'launcher/sys_config' # 添加子目录
|
||||||
config_filename = 'config_dist.yaml'
|
config_filename = 'config_dist.json'
|
||||||
else:
|
else:
|
||||||
# logger.error("本地配置")
|
# logger.error("本地配置")
|
||||||
# 如果是本地开发环境
|
# 如果是本地开发环境
|
||||||
base_path = os.path.dirname(__file__)
|
base_path = os.path.dirname(__file__)
|
||||||
config_subdir = '' # 本地开发环境不需要子目录
|
config_subdir = '' # 本地开发环境不需要子目录
|
||||||
config_filename = 'config_local.yaml'
|
config_filename = 'config_local.json'
|
||||||
|
|
||||||
config_path = os.path.join(base_path, config_subdir, config_filename)
|
config_path = os.path.join(base_path, config_subdir, config_filename)
|
||||||
return config_path
|
return config_path
|
||||||
|
@ -40,7 +39,7 @@ class SysConfig:
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
try:
|
try:
|
||||||
with open(self.config_path, 'r', encoding='utf-8') as file:
|
with open(self.config_path, 'r', encoding='utf-8') as file:
|
||||||
self.config = yaml.safe_load(file)
|
self.config = json.load(file)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
# logger.error(f"配置文件未找到: {self.config_path}")
|
# logger.error(f"配置文件未找到: {self.config_path}")
|
||||||
|
|
5
launcher/sys_config/config_dist.json
Normal file
5
launcher/sys_config/config_dist.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"version": "v0.4",
|
||||||
|
"url": "ui/dist/index.html",
|
||||||
|
"log_level": "ERROR"
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
version: "v0.4"
|
|
||||||
url: "ui/dist/index.html"
|
|
||||||
log_level: "ERROR"
|
|
5
launcher/sys_config/config_local.json
Normal file
5
launcher/sys_config/config_local.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"version": "dev",
|
||||||
|
"url": "http://localhost:5173/",
|
||||||
|
"log_level": "INFO"
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
version: "dev"
|
|
||||||
url: "http://localhost:5173/"
|
|
||||||
log_level: "INFO"
|
|
|
@ -7,7 +7,6 @@ from pathlib import Path
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from subprocess import Popen
|
from subprocess import Popen
|
||||||
|
|
||||||
import chardet
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from launcher import config
|
from launcher import config
|
||||||
|
@ -29,27 +28,27 @@ command_list = {
|
||||||
"fetch": lambda: f"..\\git\\bin\\git fetch origin {config.conf.branch} --progress",
|
"fetch": lambda: f"..\\git\\bin\\git fetch origin {config.conf.branch} --progress",
|
||||||
"switch": lambda: f"..\\git\\bin\\git -c lfs.concurrenttransfers=100 switch -f {config.conf.branch} --progress",
|
"switch": lambda: f"..\\git\\bin\\git -c lfs.concurrenttransfers=100 switch -f {config.conf.branch} --progress",
|
||||||
"reset": lambda: f"..\\git\\bin\\git -c lfs.concurrenttransfers=200 reset --hard origin/{config.conf.branch}",
|
"reset": lambda: f"..\\git\\bin\\git -c lfs.concurrenttransfers=200 reset --hard origin/{config.conf.branch}",
|
||||||
"pip_install": lambda: f"..\\python\\Scripts\\pip install --no-cache-dir -i {mirror_list[config.conf.mirror]} -r requirements.txt --no-warn-script-location",
|
"pip_tools_install": lambda: f"..\\python\\Scripts\\pip install --no-cache-dir -i {mirror_list[config.conf.mirror]} pip-tools --no-warn-script-location",
|
||||||
|
"pip_sync": lambda: f"..\\python\\Scripts\\pip-sync -i {mirror_list[config.conf.mirror]} requirements.txt",
|
||||||
"webview": "start ..\\python\\pythonw webview_ui.py",
|
"webview": "start ..\\python\\pythonw webview_ui.py",
|
||||||
"manager": "start ..\\python\\pythonw manager.py",
|
"manager": "start ..\\python\\pythonw manager.py",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def detect_encoding(stream):
|
|
||||||
# 读取一部分数据来检测编码
|
|
||||||
raw_data = stream.read(4096)
|
|
||||||
result = chardet.detect(raw_data)
|
|
||||||
stream.seek(0) # 将流指针重置到开头
|
|
||||||
return result['encoding']
|
|
||||||
|
|
||||||
|
|
||||||
def read_stream(stream, log_func):
|
def read_stream(stream, log_func):
|
||||||
detected_encoding = detect_encoding(stream)
|
def process_lines(text_io):
|
||||||
text_io = io.TextIOWrapper(stream, encoding=detected_encoding, errors='replace')
|
|
||||||
try:
|
|
||||||
for line in iter(text_io.readline, ''):
|
for line in iter(text_io.readline, ''):
|
||||||
text = line.rstrip('\n')
|
text = line.rstrip('\n')
|
||||||
custom_event(text.strip() + "\n")
|
custom_event(f"{text.strip()}\n")
|
||||||
|
|
||||||
|
detected_encoding = 'utf-8'
|
||||||
|
text_io = io.TextIOWrapper(stream, encoding=detected_encoding, errors='replace')
|
||||||
|
try:
|
||||||
|
process_lines(text_io)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
stream.seek(0) # 重新将流指针重置到开头
|
||||||
|
text_io = io.TextIOWrapper(stream, encoding='gbk', errors='replace')
|
||||||
|
process_lines(text_io)
|
||||||
finally:
|
finally:
|
||||||
text_io.close()
|
text_io.close()
|
||||||
|
|
||||||
|
@ -136,7 +135,7 @@ class Api:
|
||||||
universal_newlines=False
|
universal_newlines=False
|
||||||
) as p:
|
) as p:
|
||||||
stdout_thread = threading.Thread(target=read_stream, args=(p.stdout, logger.info))
|
stdout_thread = threading.Thread(target=read_stream, args=(p.stdout, logger.info))
|
||||||
stderr_thread = threading.Thread(target=read_stream, args=(p.stderr, logger.info))
|
stderr_thread = threading.Thread(target=read_stream, args=(p.stderr, logger.error))
|
||||||
|
|
||||||
stdout_thread.start()
|
stdout_thread.start()
|
||||||
stderr_thread.start()
|
stderr_thread.start()
|
||||||
|
@ -145,7 +144,9 @@ class Api:
|
||||||
stderr_thread.join()
|
stderr_thread.join()
|
||||||
if p.returncode == 0:
|
if p.returncode == 0:
|
||||||
return "success"
|
return "success"
|
||||||
|
else:
|
||||||
|
logger.error(f"{command} 运行失败")
|
||||||
|
return "failed"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
custom_event(str(e))
|
custom_event(str(e))
|
||||||
return "failed"
|
|
||||||
|
|
4
requirements.in
Normal file
4
requirements.in
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pywebview==5.1
|
||||||
|
requests==2.32.3
|
||||||
|
py7zr==0.22.0
|
||||||
|
pydantic==2.10.3
|
63
requirements.txt
Normal file
63
requirements.txt
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.12
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# pip-compile requirements.in
|
||||||
|
#
|
||||||
|
--index-url https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
annotated-types==0.7.0
|
||||||
|
# via pydantic
|
||||||
|
bottle==0.13.2
|
||||||
|
# via pywebview
|
||||||
|
brotli==1.1.0
|
||||||
|
# via py7zr
|
||||||
|
certifi==2024.12.14
|
||||||
|
# via requests
|
||||||
|
cffi==1.17.1
|
||||||
|
# via clr-loader
|
||||||
|
charset-normalizer==3.4.0
|
||||||
|
# via requests
|
||||||
|
clr-loader==0.2.7.post0
|
||||||
|
# via pythonnet
|
||||||
|
idna==3.10
|
||||||
|
# via requests
|
||||||
|
inflate64==1.0.0
|
||||||
|
# via py7zr
|
||||||
|
multivolumefile==0.2.3
|
||||||
|
# via py7zr
|
||||||
|
proxy-tools==0.1.0
|
||||||
|
# via pywebview
|
||||||
|
psutil==6.1.0
|
||||||
|
# via py7zr
|
||||||
|
py7zr==0.22.0
|
||||||
|
# via -r requirements.in
|
||||||
|
pybcj==1.0.2
|
||||||
|
# via py7zr
|
||||||
|
pycparser==2.22
|
||||||
|
# via cffi
|
||||||
|
pycryptodomex==3.21.0
|
||||||
|
# via py7zr
|
||||||
|
pydantic==2.10.3
|
||||||
|
# via -r requirements.in
|
||||||
|
pydantic-core==2.27.1
|
||||||
|
# via pydantic
|
||||||
|
pyppmd==1.1.0
|
||||||
|
# via py7zr
|
||||||
|
pythonnet==3.0.5
|
||||||
|
# via pywebview
|
||||||
|
pywebview==5.1
|
||||||
|
# via -r requirements.in
|
||||||
|
pyzstd==0.16.2
|
||||||
|
# via py7zr
|
||||||
|
requests==2.32.3
|
||||||
|
# via -r requirements.in
|
||||||
|
texttable==1.7.0
|
||||||
|
# via py7zr
|
||||||
|
typing-extensions==4.12.2
|
||||||
|
# via
|
||||||
|
# pydantic
|
||||||
|
# pydantic-core
|
||||||
|
# pywebview
|
||||||
|
urllib3==2.2.3
|
||||||
|
# via requests
|
|
@ -13,7 +13,7 @@ const steps = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '安装依赖',
|
title: '安装依赖',
|
||||||
command: ['pip_install'],
|
command: ['pip_tools_install', 'pip_sync'],
|
||||||
cwd: 'mower-ng'
|
cwd: 'mower-ng'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
Loading…
Reference in a new issue