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,运行
|
||||
|
||||
```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文件夹
|
||||
|
|
|
@ -2,9 +2,6 @@ import json
|
|||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from yamlcore import CoreLoader
|
||||
|
||||
from launcher.config.conf import Conf
|
||||
|
||||
conf_path = Path(os.path.join(os.getcwd(), "conf.json"))
|
||||
|
@ -22,8 +19,8 @@ def load_conf():
|
|||
conf = Conf()
|
||||
save_conf()
|
||||
return
|
||||
with conf_path.open("r", encoding="utf-8") as f:
|
||||
data = yaml.load(f, Loader=CoreLoader)
|
||||
with conf_path.open("r", encoding="utf-8") as file:
|
||||
data = json.load(file)
|
||||
if data is None:
|
||||
data = {}
|
||||
conf = Conf(**data)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
class SysConfig:
|
||||
"""
|
||||
|
@ -26,13 +25,13 @@ class SysConfig:
|
|||
# 如果是打包后的可执行文件
|
||||
base_path = sys._MEIPASS
|
||||
config_subdir = 'launcher/sys_config' # 添加子目录
|
||||
config_filename = 'config_dist.yaml'
|
||||
config_filename = 'config_dist.json'
|
||||
else:
|
||||
# logger.error("本地配置")
|
||||
# 如果是本地开发环境
|
||||
base_path = os.path.dirname(__file__)
|
||||
config_subdir = '' # 本地开发环境不需要子目录
|
||||
config_filename = 'config_local.yaml'
|
||||
config_filename = 'config_local.json'
|
||||
|
||||
config_path = os.path.join(base_path, config_subdir, config_filename)
|
||||
return config_path
|
||||
|
@ -40,7 +39,7 @@ class SysConfig:
|
|||
def load_config(self):
|
||||
try:
|
||||
with open(self.config_path, 'r', encoding='utf-8') as file:
|
||||
self.config = yaml.safe_load(file)
|
||||
self.config = json.load(file)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
# 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 subprocess import Popen
|
||||
|
||||
import chardet
|
||||
import requests
|
||||
|
||||
from launcher import config
|
||||
|
@ -29,27 +28,27 @@ command_list = {
|
|||
"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",
|
||||
"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",
|
||||
"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):
|
||||
detected_encoding = detect_encoding(stream)
|
||||
text_io = io.TextIOWrapper(stream, encoding=detected_encoding, errors='replace')
|
||||
try:
|
||||
def process_lines(text_io):
|
||||
for line in iter(text_io.readline, ''):
|
||||
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:
|
||||
text_io.close()
|
||||
|
||||
|
@ -136,7 +135,7 @@ class Api:
|
|||
universal_newlines=False
|
||||
) as p:
|
||||
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()
|
||||
stderr_thread.start()
|
||||
|
@ -145,7 +144,9 @@ class Api:
|
|||
stderr_thread.join()
|
||||
if p.returncode == 0:
|
||||
return "success"
|
||||
else:
|
||||
logger.error(f"{command} 运行失败")
|
||||
return "failed"
|
||||
except Exception as e:
|
||||
logger.exception(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: '安装依赖',
|
||||
command: ['pip_install'],
|
||||
command: ['pip_tools_install', 'pip_sync'],
|
||||
cwd: 'mower-ng'
|
||||
}
|
||||
])
|
||||
|
|
Loading…
Reference in a new issue