You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Curriculum_Design/build_release.py

258 lines
7.9 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MagicWord 0.3.0 版本发布脚本
用于构建和打包应用程序
"""
import os
import sys
import subprocess
import platform
import shutil
import zipfile
from datetime import datetime
def run_command(command, shell=False, cwd=None):
"""运行命令并返回结果"""
try:
result = subprocess.run(command, shell=shell, capture_output=True, text=True, encoding='utf-8', cwd=cwd)
return result.returncode, result.stdout, result.stderr
except Exception as e:
return -1, "", str(e)
def clean_build_dirs():
"""清理构建目录"""
print("清理构建目录...")
dirs_to_clean = ['build', 'dist', '__pycache__', '*.egg-info']
for dir_name in dirs_to_clean:
if '*' in dir_name:
# 处理通配符
import glob
for path in glob.glob(dir_name):
if os.path.isdir(path):
shutil.rmtree(path, ignore_errors=True)
elif os.path.exists(dir_name):
if os.path.isdir(dir_name):
shutil.rmtree(dir_name, ignore_errors=True)
else:
os.remove(dir_name)
# 清理src目录下的__pycache__
for root, dirs, files in os.walk('src'):
for dir_name in dirs:
if dir_name == '__pycache__':
cache_path = os.path.join(root, dir_name)
shutil.rmtree(cache_path, ignore_errors=True)
print(f"清理缓存: {cache_path}")
def install_dependencies():
"""安装依赖"""
print("安装项目依赖...")
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
if code != 0:
print(f"依赖安装失败: {stderr}")
return False
print("依赖安装成功")
return True
def build_executable():
"""构建可执行文件"""
print("构建可执行文件...")
# 安装pyinstaller
print("安装PyInstaller...")
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "install", "pyinstaller"])
if code != 0:
print(f"PyInstaller安装失败: {stderr}")
return False
# PyInstaller命令
pyinstaller_cmd = [
"pyinstaller",
"--name", "MagicWord",
"--version", "0.3.0",
"--distpath", "dist",
"--workpath", "build",
"--specpath", ".",
"--add-data", "resources;resources",
"--add-data", "src;src",
"--hidden-import", "PyQt5",
"--hidden-import", "PyQt5.QtCore",
"--hidden-import", "PyQt5.QtGui",
"--hidden-import", "PyQt5.QtWidgets",
"--hidden-import", "requests",
"--hidden-import", "beautifulsoup4",
"--hidden-import", "python-docx",
"--hidden-import", "PyPDF2",
"--hidden-import", "ebooklib",
"--hidden-import", "chardet",
"--hidden-import", "PIL",
# 移除有问题的图标参数
# "--icon", "resources/icons/app_icon.ico",
"--windowed", # 无控制台窗口
"--noconfirm",
"src/main.py"
]
# Windows平台特殊处理
if platform.system() == "Windows":
pyinstaller_cmd.extend(["--add-binary", "resources;resources"])
print("运行PyInstaller...")
code, stdout, stderr = run_command(pyinstaller_cmd)
if code != 0:
print(f"构建失败: {stderr}")
print("尝试简化构建...")
# 简化版本
simple_cmd = [
"pyinstaller",
"--onefile",
"--windowed",
"--icon=resources/icons/app_icon.ico",
"--add-data=resources;resources",
"--name=MagicWord",
"src/main.py"
]
code, stdout, stderr = run_command(simple_cmd)
if code != 0:
print(f"简化构建也失败: {stderr}")
return False
print("可执行文件构建成功")
return True
def create_package():
"""创建发布包"""
print("创建发布包...")
# 检查构建结果
if platform.system() == "Windows":
exe_path = "dist/MagicWord.exe"
else:
exe_path = "dist/MagicWord"
if not os.path.exists(exe_path):
print(f"错误: 找不到可执行文件 {exe_path}")
return False
# 创建发布目录
release_dir = "dist_package"
if os.path.exists(release_dir):
shutil.rmtree(release_dir)
os.makedirs(release_dir)
# 复制文件到发布目录
files_to_copy = [
(exe_path, "MagicWord.exe" if platform.system() == "Windows" else "MagicWord"),
("README.md", "README.md"),
("CHANGELOG.md", "CHANGELOG.md"),
("requirements.txt", "requirements.txt"),
("install_and_fix.py", "install_and_fix.py"),
]
for src, dst in files_to_copy:
if os.path.exists(src):
shutil.copy2(src, os.path.join(release_dir, dst))
print(f"复制: {src} -> {dst}")
# 创建运行脚本
if platform.system() == "Windows":
run_script = """@echo off
echo MagicWord 0.3.0 启动中...
cd /d "%~dp0"
start MagicWord.exe
"""
with open(os.path.join(release_dir, "run.bat"), "w") as f:
f.write(run_script)
else:
run_script = """#!/bin/bash
echo "MagicWord 0.3.0 启动中..."
cd "$(dirname "$0")"
./MagicWord &
"""
with open(os.path.join(release_dir, "run.sh"), "w") as f:
f.write(run_script)
os.chmod(os.path.join(release_dir, "run.sh"), 0o755)
# 创建发布说明
release_info = f"""MagicWord 0.3.0 发布包
构建时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
平台: {platform.system()} {platform.machine()}
Python版本: {platform.python_version()}
快速开始:
1. 运行 install_and_fix.py 安装依赖
2. 运行 run.bat (Windows) 或 run.sh (Linux/Mac)
3. 或直接运行 MagicWord.exe
主要更新:
- 完整的天气功能集成
- 自动IP定位功能
- 40+个城市支持
- 中英文城市名智能映射
- 每日一言功能集成
- 附加工具菜单(原天气信息菜单重命名)
详细更新请查看 CHANGELOG.md
"""
with open(os.path.join(release_dir, "RELEASE_INFO.txt"), "w", encoding="utf-8") as f:
f.write(release_info)
# 创建ZIP包
zip_name = f"MagicWord_v0.3.0_{platform.system()}_{platform.machine()}.zip"
with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(release_dir):
for file in files:
file_path = os.path.join(root, file)
arc_name = os.path.relpath(file_path, release_dir)
zipf.write(file_path, arc_name)
print(f"发布包创建成功: {zip_name}")
return True
def main():
"""主函数"""
print("=" * 60)
print("MagicWord 0.3.0 版本发布构建脚本")
print("=" * 60)
# 检查Python版本
print(f"Python版本: {platform.python_version()}")
print(f"操作系统: {platform.system()} {platform.machine()}")
# 清理构建目录
clean_build_dirs()
# 安装依赖
print("\n安装依赖...")
if not install_dependencies():
print("依赖安装失败")
sys.exit(1)
# 构建可执行文件
print("\n构建可执行文件...")
if not build_executable():
print("构建失败,尝试手动构建...")
# 如果自动构建失败,提供手动构建说明
print("\n手动构建步骤:")
print("1. 安装PyInstaller: pip install pyinstaller")
print("2. 运行: pyinstaller --onefile --windowed --icon=resources/icons/app_icon.ico src/main.py")
sys.exit(1)
# 创建发布包
print("\n创建发布包...")
if not create_package():
print("发布包创建失败")
sys.exit(1)
print("\n" + "=" * 60)
print("发布构建完成!")
print("发布包已创建在当前目录下")
print("=" * 60)
if __name__ == "__main__":
main()