#!/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()