From 79273f0ed15e0a518b62f2d6f9498cf997f49840 Mon Sep 17 00:00:00 2001 From: xunbu Date: Thu, 21 Aug 2025 16:14:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=93=E5=8C=85=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-macos.yml | 93 +++++++++++++++++++---------- .github/workflows/build-windows.yml | 27 ++++----- full.spec | 47 +++++++++++---- lite.spec | 38 +++++++----- lite_mac.spec | 67 ++++++--------------- 5 files changed, 151 insertions(+), 121 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index bd84a92..58ef681 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -1,5 +1,3 @@ -# .github/workflows/build-macos.yml - name: Build macOS Application on: @@ -14,7 +12,7 @@ jobs: runs-on: macos-latest steps: - # 第 1 步: 检出你的代码 + # 第 1 步: 检出代码 - name: Checkout repository uses: actions/checkout@v4 @@ -22,43 +20,76 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' # 匹配你的 pyproject.toml + python-version: '3.12' - # 第 3 步: 安装 uv (超高速的包管理器) + # 第 3 步: 安装 uv - name: Install uv - run: curl -LsSf https://astral.sh/uv/install.sh | sh - - name: Add uv to PATH - run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.cargo/bin" >> $GITHUB_PATH - # 第 4 步: 使用 uv 安装项目及开发依赖 - # . --dev 会安装 pyproject.toml 中 [dependencies] 和 [dependency-groups].dev 的所有包 + # 第 4 步: 安装依赖 - name: Install dependencies with uv run: uv sync - # 第 5 步: 运行 PyInstaller - - name: Build the application with PyInstaller - # 使用你的 macOS spec 文件 - run: uv run pyinstaller lite_mac.spec --noconfirm - - # 第 6 步: 创建 DMG 磁盘映像 (macOS 标准分发格式) - - name: Install create-dmg - run: brew install create-dmg - - name: Create DMG + # 第 5 步: 安装 UPX (macOS 版本) + - name: Install UPX run: | - create-dmg \ - --volname "DocuTranslate Installer" \ - --window-pos 200 120 \ - --window-size 600 400 \ - --icon-size 100 \ - --icon "DocuTranslate.app" 200 190 \ - --hide-extension "DocuTranslate.app" \ - --app-drop-link 400 190 \ - "dist/DocuTranslate.dmg" \ - "dist/DocuTranslate.app" + brew install upx - # 第 7 步: 上传构建产物 (DMG 文件) + # 第 6 步: 运行 PyInstaller (macOS 版本) + - name: Build the application with PyInstaller + run: | + uv run pyinstaller lite_mac.spec --noconfirm + + # 第 7 步: 创建 macOS 应用包结构 (可选) + - name: Create macOS app bundle structure + run: | + mkdir -p dist/DocuTranslate.app/Contents/MacOS + mkdir -p dist/DocuTranslate.app/Contents/Resources + + # 移动可执行文件 + mv dist/DocuTranslate-*-mac dist/DocuTranslate.app/Contents/MacOS/DocuTranslate + chmod +x dist/DocuTranslate.app/Contents/MacOS/DocuTranslate + + # 复制图标文件 + cp DocuTranslate.icns dist/DocuTranslate.app/Contents/Resources/ + + # 创建 Info.plist + cat > dist/DocuTranslate.app/Contents/Info.plist << EOF + + + + + CFBundleExecutable + DocuTranslate + CFBundleIconFile + DocuTranslate.icns + CFBundleIdentifier + com.yourcompany.DocuTranslate + CFBundleName + DocuTranslate + CFBundleVersion + ${{ github.run_number }} + CFBundleShortVersionString + $(python -c "import docutranslate; print(docutranslate.__version__)") + NSHighResolutionCapable + + + + EOF + shell: bash + + # 第 8 步: 打包成 zip 文件 + - name: Package application into a zip file + run: | + cd dist + zip -r DocuTranslate-macOS.zip DocuTranslate.app + shell: bash + + # 第 9 步: 上传构建产物 - name: Upload macOS build artifact uses: actions/upload-artifact@v4 with: name: DocuTranslate-macOS - path: dist/DocuTranslate.dmg \ No newline at end of file + path: dist/DocuTranslate-macOS.zip \ No newline at end of file diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 636cc1e..f575847 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -1,5 +1,3 @@ -# .github/workflows/build-windows.yml - name: Build Windows Application on: @@ -22,37 +20,36 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - # 第 3 步: 安装 uv (Windows 版) + # 第 3 步: 安装 uv - name: Install uv run: powershell -c "irm https://astral.sh/uv/install.ps1 | iex" - name: Add uv to PATH run: echo "$env:APPDATA\uv\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - # 第 4 步: 使用 uv 安装项目及开发依赖 + # 第 4 步: 安装依赖 - name: Install dependencies with uv run: uv sync - # 第 5 步: 安装 UPX (用于压缩 exe) + # 第 5 步: 安装 UPX (简化版本) - name: Install UPX run: | - Invoke-WebRequest -Uri "https://github.com/upx/upx/releases/download/v4.2.4/upx-4.2.4-win64.zip" -OutFile "upx.zip" - Expand-Archive -Path "upx.zip" -DestinationPath "upx" - echo "$((Get-Item -Path ".\upx\*\").FullName)" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - shell: powershell + choco install upx -y # 第 6 步: 运行 PyInstaller - name: Build the application with PyInstaller - # 使用你的 Windows spec 文件 - run: uv run pyinstaller lite.spec --noconfirm + run: | + uv run pyinstaller lite.spec --noconfirm - # 第 7 步: 将单个 exe 文件打包成 .zip + # 第 7 步: 打包成 zip (使用通配符匹配版本号) - name: Package executable into a zip file - run: Compress-Archive -Path dist/DocuTranslate.exe -DestinationPath dist/DocuTranslate-Windows.zip + run: | + $exeFile = Get-ChildItem -Path "dist" -Name "DocuTranslate-*-win.exe" + Compress-Archive -Path "dist/$exeFile" -DestinationPath "dist/DocuTranslate-Windows.zip" shell: powershell - # 第 8 步: 上传构建产物 (Zip 文件) + # 第 8 步: 上传构建产物 - name: Upload Windows build artifact uses: actions/upload-artifact@v4 with: diff --git a/full.spec b/full.spec index 30f6b6c..b35218a 100644 --- a/full.spec +++ b/full.spec @@ -1,19 +1,42 @@ # -*- mode: python ; coding: utf-8 -*- +import os from PyInstaller.utils.hooks import collect_all -datas = [('./.venv/Lib/site-packages/docling_parse/pdf_resources_v2', 'docling_parse/pdf_resources_v2'), -('./docutranslate/static', 'docutranslate/static'),('./docutranslate/template', 'docutranslate/template')] +import docutranslate + +# 初始化列表 +datas = [] binaries = [] -hiddenimports=['markdown.extensions.tables','pymdownx.arithmatex','pymdownx.superfences','pymdownx.highlight','pygments'] -for i in ['easyocr','docling','pygments']: - tmp_ret = collect_all(i) - datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +hiddenimports = ['markdown.extensions.tables', 'pymdownx.arithmatex', + 'pymdownx.superfences', 'pymdownx.highlight', 'pygments'] + +# 先收集第三方包的资源 +for package in ['easyocr', 'docling', 'pygments']: + try: + tmp_ret = collect_all(package) + datas += tmp_ret[0] + binaries += tmp_ret[1] + hiddenimports += tmp_ret[2] + except Exception as e: + print(f"Warning: Failed to collect resources for {package}: {e}") + +# 然后添加您的自定义资源(避免重复) +custom_datas = [ + ('./.venv/Lib/site-packages/docling_parse/pdf_resources_v2', 'docling_parse/pdf_resources_v2'), + ('./docutranslate/static', 'docutranslate/static'), + ('./docutranslate/template', 'docutranslate/template') +] + +# 避免添加重复的数据 +for data in custom_datas: + if data not in datas: + datas.append(data) a = Analysis( - ['docutranslate\\app.py'], - pathex=[], + ['docutranslate/app.py'], # 使用正斜杠 + pathex=[], # 添加当前工作目录到 pathex binaries=binaries, datas=datas, - hiddenimports=hiddenimports, + hiddenimports=list(set(hiddenimports)), # 去重 hookspath=[], hooksconfig={}, runtime_hooks=[], @@ -29,7 +52,7 @@ exe = EXE( a.binaries, a.datas, [], - name='DocuTranslate_full', + name=f'DocuTranslate_full-{docutranslate.__version__}-win', debug=False, bootloader_ignore_signals=False, strip=False, @@ -42,5 +65,5 @@ exe = EXE( target_arch=None, codesign_identity=None, entitlements_file=None, - icon=['DocuTranslate.ico'], -) + icon='DocuTranslate.ico', +) \ No newline at end of file diff --git a/lite.spec b/lite.spec index e093016..88f58b1 100644 --- a/lite.spec +++ b/lite.spec @@ -1,25 +1,36 @@ # -*- mode: python ; coding: utf-8 -*- -from PyInstaller.utils.hooks import collect_all -datas = [('./docutranslate/static', 'docutranslate/static'),('./docutranslate/template', 'docutranslate/template')] -binaries = [] -hiddenimports=['markdown.extensions.tables','pymdownx.arithmatex','pymdownx.superfences','pymdownx.highlight','pygments'] -for i in ['pygments']: - tmp_ret = collect_all(i) - datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +import os +from PyInstaller.utils.hooks import collect_data_files +import docutranslate + +datas = [ + ('docutranslate/static', 'docutranslate/static'), + ('docutranslate/template', 'docutranslate/template'), + *collect_data_files('pygments') # 直接展开 +] + +hiddenimports = [ + 'markdown.extensions.tables', + 'pymdownx.arithmatex', + 'pymdownx.superfences', + 'pymdownx.highlight', + 'pygments' +] a = Analysis( - ['docutranslate\\app.py'], + ['docutranslate/app.py'], # 使用正斜杠,Windows 也支持 pathex=[], - binaries=binaries, + binaries=[], datas=datas, hiddenimports=hiddenimports, hookspath=[], hooksconfig={}, runtime_hooks=[], - excludes=["docling","docutranslate.converter.x2md.converter_docling"], + excludes=["docling", "docutranslate.converter.x2md.converter_docling"], noarchive=False, optimize=0, ) + pyz = PYZ(a.pure) exe = EXE( @@ -28,12 +39,11 @@ exe = EXE( a.binaries, a.datas, [], - name='DocuTranslate', + name=f'DocuTranslate-{docutranslate.__version__}-win', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, - upx_exclude=[], runtime_tmpdir=None, console=True, disable_windowed_traceback=False, @@ -41,5 +51,5 @@ exe = EXE( target_arch=None, codesign_identity=None, entitlements_file=None, - icon=['DocuTranslate.ico'], -) + icon='DocuTranslate.ico', # 修正为字符串 +) \ No newline at end of file diff --git a/lite_mac.spec b/lite_mac.spec index 1b06d08..2df75a6 100644 --- a/lite_mac.spec +++ b/lite_mac.spec @@ -1,32 +1,27 @@ # -*- mode: python ; coding: utf-8 -*- +from PyInstaller.utils.hooks import collect_data_files +import docutranslate -# 导入 os 模块以更好地处理路径 -import os -from PyInstaller.utils.hooks import collect_all - -# --- 数据文件和二进制文件 --- -# 路径分隔符已更正为 '/',这在所有平台上都更具兼容性 datas = [ ('./docutranslate/static', 'docutranslate/static'), ('./docutranslate/template', 'docutranslate/template') ] -binaries = [] -hiddenimports=['markdown.extensions.tables','pymdownx.arithmatex','pymdownx.superfences','pymdownx.highlight','pygments'] -# 使用 collect_all 来收集依赖 -# 这部分代码是跨平台的,无需修改 -for i in ['pygments']: - tmp_ret = collect_all(i) - datas += tmp_ret[0] - binaries += tmp_ret[1] - hiddenimports += tmp_ret[2] +# 只收集 pygments 的数据文件 +datas += collect_data_files('pygments') + +hiddenimports = [ + 'markdown.extensions.tables', + 'pymdownx.arithmatex', + 'pymdownx.superfences', + 'pymdownx.highlight', + 'pygments' +] -# --- 分析阶段 --- a = Analysis( - # 【修改 1】: 使用正斜杠 '/' 作为路径分隔符 ['docutranslate/app.py'], pathex=[], - binaries=binaries, + binaries=[], datas=datas, hiddenimports=hiddenimports, hookspath=[], @@ -39,49 +34,23 @@ a = Analysis( pyz = PYZ(a.pure) -# --- EXE 和 COLLECT 阶段 --- -# EXE 仅创建 Unix 可执行文件 exe = EXE( pyz, a.scripts, - [], # binaries 和 datas 移到下面的 BUNDLE/COLLECT 中 + a.binaries, + a.datas, [], - name='DocuTranslate', + name=f'DocuTranslate-{docutranslate.__version__}-mac', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, runtime_tmpdir=None, - # 【修改 2】: 如果是 GUI 应用,建议设为 False console=True, disable_windowed_traceback=False, argv_emulation=False, - target_arch=None, # 推荐 'universal2' 以支持 Apple Silicon 和 Intel + target_arch=None, codesign_identity=None, entitlements_file=None, -) - -# --- BUNDLE 阶段 (macOS 核心) --- -# 【修改 3】: 使用 BUNDLE 创建 .app 包,而不是单独的 EXE -# 这将生成一个标准的 macOS 应用程序 -app = BUNDLE( - exe, - name='DocuTranslate.app', - # 【修改 4】: 使用 .icns 格式的图标 icon='DocuTranslate.icns', - bundle_identifier='cc.xunbu.docutranslate', # 推荐设置一个唯一的包标识符 - info_plist={ - 'NSHighResolutionCapable': 'True', - 'NSPrincipalClass': 'NSApplication', - 'NSAppleScriptEnabled': False, - 'CFBundleDisplayName': 'DocuTranslate', - 'CFBundleName': 'DocuTranslate', - 'CFBundleVersion': '1.0.0', - 'CFBundleShortVersionString': '1.0', - 'NSHumanReadableCopyright': 'Copyright © 2023 Your Name. All rights reserved.' - } -) - -# 将 a.datas 和 a.binaries 添加到 .app 包中 -app.datas += a.datas -app.binaries += a.binaries \ No newline at end of file +) \ No newline at end of file