init
This commit is contained in:
144
build.py
Normal file
144
build.py
Normal file
@@ -0,0 +1,144 @@
|
||||
"""
|
||||
故事提取工具 - 打包构建脚本
|
||||
使用方法: python build.py
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
BACKEND_DIR = os.path.join(BASE_DIR, "backend")
|
||||
FRONTEND_DIR = os.path.join(BASE_DIR, "frontend")
|
||||
DIST_DIR = os.path.join(BASE_DIR, "dist")
|
||||
BUILD_DIR = os.path.join(BASE_DIR, "build")
|
||||
|
||||
|
||||
def step(msg: str):
|
||||
print(f"\n{'='*50}")
|
||||
print(f" {msg}")
|
||||
print(f"{'='*50}")
|
||||
|
||||
|
||||
def build_frontend():
|
||||
"""构建前端"""
|
||||
step("1/4 构建前端...")
|
||||
os.chdir(FRONTEND_DIR)
|
||||
subprocess.run([sys.executable, "-m", "npm", "run", "build"], check=True, shell=False)
|
||||
os.chdir(BASE_DIR)
|
||||
print("前端构建完成!")
|
||||
|
||||
|
||||
def create_package_structure():
|
||||
"""创建打包目录结构"""
|
||||
step("2/4 准备打包文件...")
|
||||
|
||||
# 清理旧的 dist
|
||||
if os.path.exists(DIST_DIR):
|
||||
shutil.rmtree(DIST_DIR)
|
||||
os.makedirs(DIST_DIR, exist_ok=True)
|
||||
|
||||
# 复制 backend 目录
|
||||
pkg_backend = os.path.join(DIST_DIR, "backend")
|
||||
if os.path.exists(pkg_backend):
|
||||
shutil.rmtree(pkg_backend)
|
||||
shutil.copytree(BACKEND_DIR, pkg_backend)
|
||||
|
||||
# 复制 frontend/dist
|
||||
pkg_frontend = os.path.join(DIST_DIR, "frontend", "dist")
|
||||
os.makedirs(pkg_frontend, exist_ok=True)
|
||||
src_dist = os.path.join(FRONTEND_DIR, "dist")
|
||||
if os.path.exists(src_dist):
|
||||
for item in os.listdir(src_dist):
|
||||
s = os.path.join(src_dist, item)
|
||||
d = os.path.join(pkg_frontend, item)
|
||||
if os.path.isdir(s):
|
||||
shutil.copytree(s, d)
|
||||
else:
|
||||
shutil.copy2(s, d)
|
||||
|
||||
# 复制 run.py
|
||||
shutil.copy2(os.path.join(BASE_DIR, "run.py"), os.path.join(DIST_DIR, "run.py"))
|
||||
|
||||
print("打包文件准备完成!")
|
||||
|
||||
|
||||
def build_exe():
|
||||
"""使用 PyInstaller 打包"""
|
||||
step("3/4 打包成 exe...")
|
||||
|
||||
os.chdir(DIST_DIR)
|
||||
|
||||
cmd = [
|
||||
sys.executable, "-m", "PyInstaller",
|
||||
"--name=故事提取工具",
|
||||
"--onefile",
|
||||
"--windowed",
|
||||
"--noconfirm",
|
||||
"--clean",
|
||||
# 隐藏导入
|
||||
"--hidden-import=uvicorn.logging",
|
||||
"--hidden-import=uvicorn.loops",
|
||||
"--hidden-import=uvicorn.loops.auto",
|
||||
"--hidden-import=uvicorn.protocols",
|
||||
"--hidden-import=uvicorn.protocols.http",
|
||||
"--hidden-import=uvicorn.protocols.http.auto",
|
||||
"--hidden-import=uvicorn.protocols.websockets",
|
||||
"--hidden-import=uvicorn.protocols.websockets.auto",
|
||||
"--hidden-import=uvicorn.lifespan",
|
||||
"--hidden-import=uvicorn.lifespan.on",
|
||||
"--hidden-import=multipart",
|
||||
# 收集数据文件
|
||||
f"--add-data=backend;backend",
|
||||
f"--add-data=frontend;frontend",
|
||||
# 入口
|
||||
"run.py",
|
||||
]
|
||||
|
||||
subprocess.run(cmd, check=True, shell=False)
|
||||
os.chdir(BASE_DIR)
|
||||
print("打包完成!")
|
||||
|
||||
|
||||
def copy_output():
|
||||
"""复制最终输出"""
|
||||
step("4/4 整理输出...")
|
||||
|
||||
exe_name = "故事提取工具.exe"
|
||||
src = os.path.join(DIST_DIR, "dist", exe_name)
|
||||
dst = os.path.join(BASE_DIR, exe_name)
|
||||
|
||||
if os.path.exists(src):
|
||||
shutil.copy2(src, dst)
|
||||
size_mb = os.path.getsize(dst) / (1024 * 1024)
|
||||
print(f"\n✅ 打包成功!")
|
||||
print(f" 输出文件: {dst}")
|
||||
print(f" 文件大小: {size_mb:.1f} MB")
|
||||
print(f"\n 使用方法:")
|
||||
print(f" 1. 将 {exe_name} 发送给用户")
|
||||
print(f" 2. 用户双击运行,自动打开浏览器")
|
||||
print(f" 3. 首次使用需要在设置页面配置 API Key")
|
||||
else:
|
||||
print(f"\n❌ 打包失败,未找到输出文件: {src}")
|
||||
|
||||
|
||||
def main():
|
||||
print("故事提取工具 - 打包构建")
|
||||
print("=" * 50)
|
||||
|
||||
# 检查 PyInstaller
|
||||
try:
|
||||
import PyInstaller
|
||||
except ImportError:
|
||||
print("正在安装 PyInstaller...")
|
||||
subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller", "--break-system-packages"],
|
||||
check=True, shell=False)
|
||||
|
||||
build_frontend()
|
||||
create_package_structure()
|
||||
build_exe()
|
||||
copy_output()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user