From 18fd015d1143c319d5b620630d05963d347bac15 Mon Sep 17 00:00:00 2001 From: Kissablecho Date: Wed, 9 Jul 2025 23:32:23 +0800 Subject: [PATCH 1/3] Merge branch 'dev' into main(#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dev_package_and_upload.yml (#17) * 更新 NetEase_Cloud_Music_Download * sync (#19) * Update dev_package_and_upload.yml * Update README.md * update nuitka_build.py * Update pyinstaller_package_and_release.yml * Update nuitka_package_release.yml * Update nuitka_build.py * 更新 NetEase_Cloud_Music_Download (#18) * Update dev_package_and_upload.yml (#17) * 更新 NetEase_Cloud_Music_Download * 更新依赖项,添加psutil和astropy库 * 添加favicon.ico图标文件,并在配置中启用UPX压缩 * Merge branch 'main' into dev * Nuitka Build 启用多核并行编译 * test cache * 删去错误版本信息 * fix dev_package_and_upload.yml * fix dev_package_and_upload.yml * fix dev_package_and_upload.yml pip-cache-dir * Update dev_package_and_upload.yml fix type * 添加对插件的支持,更新配置文件以启用UPX插件和自定义命令 * 禁用 Nuitka Package and Upload(dev) 自动流程,启用手动触发,添加测试流程 * fix Nuitka Package and Upload(dev) * try fix nuitka_build.py * Nuitka Package and Upload(dev) update upx installer and use more os bulid * Nuitka Package and Upload(dev) fix value * Nuitka Package and Upload(dev) fix Timezone * update * update nuitka 兼容Linux Windows平台 * remove windows-11-arm * update * more option * fix artifact upload * update Package * Merge branch 'main' into dev --- .github/workflows/dev_package_and_upload.yml | 153 +++++++++-- .github/workflows/nuitka_package_release.yml | 143 ++++++++-- novel_crawler/novel_crawler_v.25.07.08.py | 2 +- package/hello_world.py | 55 ++++ package/nuitka_build.py | 269 +++++++++++++------ package/nuitka_config.yml | 55 ++-- package/nuitka_test_config.yml | 18 ++ 7 files changed, 555 insertions(+), 140 deletions(-) create mode 100644 package/hello_world.py create mode 100644 package/nuitka_test_config.yml diff --git a/.github/workflows/dev_package_and_upload.yml b/.github/workflows/dev_package_and_upload.yml index dc149f7..1252b40 100644 --- a/.github/workflows/dev_package_and_upload.yml +++ b/.github/workflows/dev_package_and_upload.yml @@ -2,37 +2,120 @@ name: Nuitka Package and Upload(dev) on: workflow_dispatch: - push: - branches: - - dev - paths: - - 'package/nuitka_config.yml' + inputs: + test: + description: '测试' + required: true + type: boolean + default: true + config_path: + description: '测试模式时用的配置文件路径(非测试时请忽略)' + required: true + type: string + default: 'package/nuitka_test_config.yml' + # push: + # branches: + # - dev + # paths: + # - 'package/nuitka_config.yml' jobs: package-and-upload: - runs-on: windows-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest,ubuntu-24.04-arm,windows-latest] # windows-11-arm没有对应的 Python + env: + PYTHON_VERSION: '3.10' + NUITKA_CACHE_DIR: ${{ github.workspace }}/nuitka-cache + UPXVERSION: '5.0.1' # 添加必要的权限 permissions: contents: write # 允许创建发布和上传资源 steps: - - name: Set Timezone to China Standard Time - run: tzutil /s "China Standard Time" - shell: pwsh - name: Checkout code uses: actions/checkout@v4 + + - name: Set Timezone to China Standard Time on Windows + if: ${{ runner.os == 'Windows' }} + run: tzutil /s "China Standard Time" + shell: pwsh + + - name: Set Timezone to China Standard Time on Linux + if: ${{ runner.os == 'Linux' }} + run: sudo timedatectl set-timezone Asia/Shanghai + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: ${{ env.PYTHON_VERSION }} + + - name: Cache UPX + id: cache-upx + uses: actions/cache@v4 + with: + path: upx + key: ${{ runner.os }}-${{ runner.arch }}-upx-v${{ env.UPXVERSION }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-upx- + + - name: Create UPX directory + if: ${{ steps.cache-upx.outputs.cache-hit != 'true' }} + run: mkdir -p ./upx + + - name: Install UPX on Linux + if: ${{ runner.os == 'Linux' && steps.cache-upx.outputs.cache-hit != 'true' }} + run: | + + UPX_URL="https://github.com/upx/upx/releases/download/v${{ env.UPXVERSION }}/upx-${{ env.UPXVERSION }}-${{ runner.arch == 'X64' && 'amd64' || 'arm64' }}_linux.tar.xz" + curl -L "$UPX_URL" -o upx.tar.xz + tar -xf upx.tar.xz -C ./upx --strip-components=1 + chmod +x ./upx/upx + + shell: bash + + - name: Install UPX on Windows + if: ${{ runner.os == 'Windows' && steps.cache-upx.outputs.cache-hit != 'true' }} + run: | + $arch = if (("${{ runner.arch }}" -eq "amd64") -or ("${{ runner.arch }}" -eq "X64")) { "win64" } else { "win32" } + $upxVersion = "${{ env.UPXVERSION }}" + $upxUrl = "https://github.com/upx/upx/releases/download/v$upxVersion/upx-$upxVersion-$arch.zip" + + Invoke-WebRequest -Uri $upxUrl -OutFile upx.zip + Expand-Archive -Path upx.zip -DestinationPath ./upx -Force + + # Windows 版本的 UPX 解压后在子目录中,需要移动到根目录 + Move-Item -Path "./upx/upx-$upxVersion-$arch/*" -Destination ./upx -Force + + shell: pwsh - - name: UPX Setup + - name: Verify UPX installation run: | - mkdir upx - curl -o upx/upx.exe https://assets.ksable.top/github/upx/upx/v5.0.1/windows-amd64/upx.exe + ./upx/upx --version + shell: bash + + - name: get pip cache dir on Windows + if: ${{ runner.os == 'Windows' }} + id: pip-cache-dir-window + run: echo "pip-cache-dir=$(pip cache dir)" >> $env:GITHUB_OUTPUT + + - name: get pip cache dir on Linux + if: ${{ runner.os == 'Linux' }} + id: pip-cache-dir-linux + run: echo "pip-cache-dir=$(pip cache dir)" >> $GITHUB_OUTPUT + + - name: pip cache + uses: actions/cache@v4 + with: + path: ${{ runner.os == 'Windows' && steps.pip-cache-dir-window.outputs.pip-cache-dir || steps.pip-cache-dir-linux.outputs.pip-cache-dir }} + key: ${{ runner.os }}-${{ runner.arch }}-pip-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-pip- + - name: Install dependencies run: | @@ -52,22 +135,56 @@ jobs: # [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # # 设置控制台编码为UTF-8 # chcp.com 65001 + + - name: Install ccache on Linux + if: ${{ runner.os == 'Linux' }} + run: | + sudo apt-get update -y + sudo apt-get install -y ccache + + - name: Cache Nuitka cache directory + uses: actions/cache@v4 + with: + path: ${{ env.NUITKA_CACHE_DIR }} + key: nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}-nuitka-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}- + nuitka-${{ runner.os }}-${{ runner.arch }}- + + - name: Run packaging script on Windows + if: ${{ !github.event.inputs.test && runner.os == 'Windows' }} + run: | + # 设置Python使用UTF-8编码 + [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') + # 设置控制台编码为UTF-8 + chcp.com 65001 + python ./package/nuitka_build.py ./package/nuitka_config.yml - - name: Run packaging script + - name: Run Test packaging script on Windows + if: ${{ github.event.inputs.test && runner.os == 'Windows' }} run: | # 设置Python使用UTF-8编码 [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # 设置控制台编码为UTF-8 chcp.com 65001 - cd package - python nuitka_build.py nuitka_config.yml + python ./package/nuitka_build.py ${{ github.event.inputs.config_path }} + + - name: Run packaging script on Linux + if: ${{ !github.event.inputs.test && runner.os == 'Linux' }} + run: | + python ./package/nuitka_build.py ./package/nuitka_config.yml + + - name: Run Test packaging script on Linux + if: ${{ github.event.inputs.test && runner.os == 'Linux' }} + run: | + python ./package/nuitka_build.py ${{ github.event.inputs.config_path }} - name: Upload files with wildcards uses: actions/upload-artifact@v4 with: - name: Artifact + name: ${{ runner.os }}-${{ runner.arch }}-${{ github.event.inputs.test && 'test-' || '' }}artifact path: | - ./dist/*.exe + ./dist/* retention-days: 14 if-no-files-found: warn overwrite: true diff --git a/.github/workflows/nuitka_package_release.yml b/.github/workflows/nuitka_package_release.yml index 490faf2..7b4fb95 100644 --- a/.github/workflows/nuitka_package_release.yml +++ b/.github/workflows/nuitka_package_release.yml @@ -1,4 +1,4 @@ -name: Nuitka Package and Release +name: Nuitka Package and Upload(dev) on: workflow_dispatch: @@ -9,41 +9,122 @@ on: - 'package/nuitka_config.yml' jobs: - package-and-release: + package-and-upload: runs-on: windows-latest + # runs-on: ${{ matrix.os }} + # strategy: + # matrix: + # os: [ubuntu-latest,ubuntu-24.04-arm,windows-latest] # windows-11-arm没有对应的 Python + env: + PYTHON_VERSION: '3.10' + NUITKA_CACHE_DIR: ${{ github.workspace }}/nuitka-cache + UPXVERSION: '5.0.1' # 添加必要的权限 permissions: contents: write # 允许创建发布和上传资源 steps: - - name: Set Timezone to China Standard Time - run: tzutil /s "China Standard Time" - shell: pwsh - name: Checkout code uses: actions/checkout@v4 - - name: Generate version tag - id: version + - name: Set Timezone to China Standard Time on Windows + if: ${{ runner.os == 'Windows' }} + run: tzutil /s "China Standard Time" + shell: pwsh + + - name: Set Timezone to China Standard Time on Linux + if: ${{ runner.os == 'Linux' }} + run: sudo timedatectl set-timezone Asia/Shanghai + + - name: Generate version tag on Windows + if: ${{ runner.os == 'Windows' }} run: | # 使用 UTC 时间确保一致性 $date = (Get-Date).ToUniversalTime().ToString("yy.MM.dd") $tag = "v$date" $release = "Release $date" - echo "tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - echo "release_name=$release" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - - + echo "VERSION_TAG=$tag" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "RELEASE_NAME=$release" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + shell: pwsh + + - name: Generate version tag on Linux + if: ${{ runner.os == 'Linux' }} + run: | + # 使用 UTC 时间确保一致性 + DATE=$(date -u +%y.%m.%d) + echo "VERSION_TAG=v$DATE" >> $GITHUB_ENV + echo "RELEASE_NAME=Release $DATE" >> $GITHUB_ENV + shell: bash + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: ${{ env.PYTHON_VERSION }} + + - name: Cache UPX + id: cache-upx + uses: actions/cache@v4 + with: + path: upx + key: ${{ runner.os }}-${{ runner.arch }}-upx-v${{ env.UPXVERSION }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-upx- + + - name: Create UPX directory + if: ${{ steps.cache-upx.outputs.cache-hit != 'true' }} + run: mkdir -p ./upx + + - name: Install UPX on Linux + if: ${{ runner.os == 'Linux' && steps.cache-upx.outputs.cache-hit != 'true' }} + run: | + + UPX_URL="https://github.com/upx/upx/releases/download/v${{ env.UPXVERSION }}/upx-${{ env.UPXVERSION }}-${{ runner.arch == 'X64' && 'amd64' || 'arm64' }}_linux.tar.xz" + curl -L "$UPX_URL" -o upx.tar.xz + tar -xf upx.tar.xz -C ./upx --strip-components=1 + chmod +x ./upx/upx + + shell: bash - - name: UPX Setup + - name: Install UPX on Windows + if: ${{ runner.os == 'Windows' && steps.cache-upx.outputs.cache-hit != 'true' }} run: | - mkdir upx - curl -o upx/upx.exe https://assets.ksable.top/github/upx/upx/v5.0.1/windows-amd64/upx.exe + $arch = if (("${{ runner.arch }}" -eq "amd64") -or ("${{ runner.arch }}" -eq "X64")) { "win64" } else { "win32" } + $upxVersion = "${{ env.UPXVERSION }}" + $upxUrl = "https://github.com/upx/upx/releases/download/v$upxVersion/upx-$upxVersion-$arch.zip" + + Invoke-WebRequest -Uri $upxUrl -OutFile upx.zip + Expand-Archive -Path upx.zip -DestinationPath ./upx -Force + + # Windows 版本的 UPX 解压后在子目录中,需要移动到根目录 + Move-Item -Path "./upx/upx-$upxVersion-$arch/*" -Destination ./upx -Force + + shell: pwsh + + - name: Verify UPX installation + run: | + ./upx/upx --version + shell: bash + + - name: get pip cache dir on Windows + if: ${{ runner.os == 'Windows' }} + id: pip-cache-dir-window + run: echo "pip-cache-dir=$(pip cache dir)" >> $env:GITHUB_OUTPUT + + - name: get pip cache dir on Linux + if: ${{ runner.os == 'Linux' }} + id: pip-cache-dir-linux + run: echo "pip-cache-dir=$(pip cache dir)" >> $GITHUB_OUTPUT + + - name: pip cache + uses: actions/cache@v4 + with: + path: ${{ runner.os == 'Windows' && steps.pip-cache-dir-window.outputs.pip-cache-dir || steps.pip-cache-dir-linux.outputs.pip-cache-dir }} + key: ${{ runner.os }}-${{ runner.arch }}-pip-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-pip- + - name: Install dependencies run: | @@ -64,14 +145,34 @@ jobs: # # 设置控制台编码为UTF-8 # chcp.com 65001 - - name: Run packaging script + - name: Install ccache on Linux + if: ${{ runner.os == 'Linux' }} + run: | + sudo apt-get update -y + sudo apt-get install -y ccache + + - name: Cache Nuitka cache directory + uses: actions/cache@v4 + with: + path: ${{ env.NUITKA_CACHE_DIR }} + key: nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}-nuitka-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}- + nuitka-${{ runner.os }}-${{ runner.arch }}- + + - name: Run packaging script on Windows + if: ${{ runner.os == 'Windows' }} run: | # 设置Python使用UTF-8编码 [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # 设置控制台编码为UTF-8 chcp.com 65001 - cd package - python nuitka_build.py nuitka_config.yml + python ./package/nuitka_build.py ./package/nuitka_config.yml + + - name: Run packaging script on Linux + if: ${{ runner.os == 'Linux' }} + run: | + python ./package/nuitka_build.py ./package/nuitka_config.yml - name: Create Release id: create_release @@ -79,11 +180,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ steps.version.outputs.tag }} - name: ${{ steps.version.outputs.release_name }} + tag_name: ${{ env.VERSION_TAG }} + name: ${{ env.RELEASE_NAME }} generate_release_notes: true draft: false prerelease: false overwrite_files: true files: | - dist/*.exe + dist/* diff --git a/novel_crawler/novel_crawler_v.25.07.08.py b/novel_crawler/novel_crawler_v.25.07.08.py index 91fe75b..b6269ee 100644 --- a/novel_crawler/novel_crawler_v.25.07.08.py +++ b/novel_crawler/novel_crawler_v.25.07.08.py @@ -417,7 +417,7 @@ def download_chapter(chapter_info, progress, task_id, chapter_count): # 主函数开始 def main(): - print_header("小说爬虫工具\n版本 v.25.07.07") + print_header("小说爬虫工具") if debug: logger.debug("Debug模式已开启") diff --git a/package/hello_world.py b/package/hello_world.py new file mode 100644 index 0000000..ed9692d --- /dev/null +++ b/package/hello_world.py @@ -0,0 +1,55 @@ +import platform +import os +import sys +import psutil +print('='*50) + +# 显示系统信息 +print('hello world') +print('-'*50) +print('系统信息') +print("操作系统:", platform.system()) +print("架构:", platform.machine()) +print("版本:", platform.version()) +print("平台:", platform.platform()) + +# 显示硬件信息 +print('-'*50) +print('CPU 信息') +print(f"CPU 核心数: {psutil.cpu_count(logical=False)}") +print(f"逻辑处理器数: {psutil.cpu_count(logical=True)}") +print("处理器信息:", platform.processor()) +cpu_times = psutil.cpu_times() +print(f"用户时间: {cpu_times.user}") +print(f"系统时间: {cpu_times.system}") +print(f"空闲时间: {cpu_times.idle}") + +memory_info = psutil.virtual_memory() + +print('-'*50) +print('内存 信息') +print(f"总内存: {memory_info.total / (1024 ** 3)} GB") +print(f"空闲内存: {memory_info.free / (1024 ** 3)} GB") +print(f"已用内存: {memory_info.used / (1024 ** 3)} GB") +print(f"可用内存: {memory_info.available / (1024 ** 3)} GB") + +# 获取内存详细信息 +print('-'*50) +print('交换内存 信息') +swap_memory = psutil.swap_memory() +print(f"交换内存总量: {swap_memory.total / (1024 ** 3)} GB") +print(f"已用交换内存: {swap_memory.used / (1024 ** 3)} GB") +print(f"可用交换内存: {swap_memory.free / (1024 ** 3)} GB") + +print("系统编码:", sys.getdefaultencoding()) +print("文件系统编码:", sys.getfilesystemencoding()) + + + +# 显示Python信息 +print("Python版本:", sys.version) +print("Python路径:", sys.executable) +print("当前工作目录:", os.getcwd()) + + +print('='*50) diff --git a/package/nuitka_build.py b/package/nuitka_build.py index d19853f..3854918 100644 --- a/package/nuitka_build.py +++ b/package/nuitka_build.py @@ -5,10 +5,43 @@ import platform import argparse from pathlib import Path -# from zip import zip_files_and_folders import uuid import shutil +def normalize_path(path_str): + """将路径字符串中的反斜杠转换为当前系统的分隔符""" + return Path(path_str.replace('\\', os.sep)) + +def delete_folders(directory): + """删除指定目录下的所有文件夹,但保留文件""" + if os.path.basename(directory) == '' or os.path.basename(directory): + dir_name = os.path.basename(os.path.dirname(directory)) + else: + dir_name = os.path.basename(directory) + print(f'清理文件夹({dir_name})下的文件夹') + try: + # 确保目录存在 + if not os.path.exists(directory): + print(f"目录不存在: {directory}") + return True + + # 遍历目录中的所有项 + for item in os.listdir(directory): + item_path = os.path.join(directory, item) + # 如果是文件夹,则删除 + if os.path.isdir(item_path): + # print(f"删除文件夹: {item_path}") + rm_item_dir = ','.join(item_path) + shutil.rmtree(item_path) + # else: + # print(f"保留文件: {item_path}") + print(f'清理文件夹({dir_name})下的文件夹完成: {rm_item_dir}') + print("操作完成") + return True + except Exception as e: + print(f"发生错误: {e}") + return False + def main(): print("="*50) print("="*50) @@ -21,28 +54,39 @@ def main(): print("错误: 请使用Python 3.7或更高版本") return - Machine = platform.system() - arrch = platform.machine() + system_os = platform.system() + arch = platform.machine() - print(f"当前操作系统: {Machine} {arrch}") + print(f"当前操作系统: {system_os}") + print(f'架构: {arch}') print(f"平台详情: {platform.platform()}") + print("CPU核心数:", os.cpu_count()) + print("处理器信息:", platform.processor()) print(f"Python版本: {sys.version}") + print(f'工作目录: {os.getcwd()}') # 解析命令行参数 parser = argparse.ArgumentParser(description='Nuitka打包脚本') parser.add_argument('config', help='配置文件路径') args = parser.parse_args() - - # 读取配置文件 - with open(args.config, 'r', encoding='utf-8') as f: - config = yaml.safe_load(f) # 基础路径设置 - base_dir = Path(__file__).parent.parent # 项目根目录 - upx_dir = base_dir / './upx/' # UPX目录 + base_dir = Path(__file__).resolve().parent.parent # 项目根目录 + upx_dir = base_dir / 'upx' # UPX目录 + dist_path = base_dir / 'dist' + # 读取配置文件 + # config_path = base_dir / args.config + config_path = args.config + if not config_path.exists(): + print(f"错误: 配置文件不存在 {config_path}") + sys.exit(1) + + with config_path.open('r', encoding='utf-8') as f: + config = yaml.safe_load(f) success_count = 0 task_error_list = [] + # 遍历所有打包任务 for i, task in enumerate(config, start=1): try: @@ -50,116 +94,171 @@ def main(): print(f"开始打包任务: [{i}/{len(config)}] {task['name']}") print(f"{'='*40}") - # 解析任务参数 - python_file = base_dir / task['python-file'] - dist_path = base_dir / task['distpath'] + # 解析任务参数 - 使用路径规范化 + python_file = base_dir / normalize_path(task['python-file']) + # dist_path = base_dir / normalize_path(task['distpath']) requirements = task.get('install-requirements', []) - use_upx = task.get('upx', False) - # onefile = task.get('onefile', 0) + enable_plugins = task.get('enable-plugins', []) + icon = task.get('icon') windows_disable_console = task.get('windows-disable-console', False) name = task.get('name') version = task.get('version') timeout = task.get('timeout', 60 * 45) - output_name_template = task.get('output-name-template', '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}') - if arrch == "AMD64": - arrch = "x64" - output_name = output_name_template.replace('{{name}}', name).replace('{{version}}', version).replace('{{arch}}', arrch).replace('{{os}}', Machine) - - # 检查操作系统和架构 - # if Machine not in task.get('os', []): - # print(f"警告: 任务 [{i}/{len(config)} {task['name']}] 不支持当前操作系统 {Machine}") - # continue - # if arrch not in task.get('arch', []): - # print(f"警告: 任务 [{i}/{len(config)} {task['name']}] 不支持当前架构 {arrch}") - # continue + + # 处理输出文件名模板 + output_name_template = task.get('output-name-template', '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}{{exe_suffix}}') + + # 处理架构名称统一 + normalized_arch = "x64" if arch == "AMD64" else arch + exe_suffix = '.exe' if system_os == 'Windows' else '' + + output_name = output_name_template.replace('{{name}}', name) \ + .replace('{{version}}', version) \ + .replace('{{arch}}', normalized_arch) \ + .replace('{{os}}', system_os) \ + .replace('{{exe_suffix}}', exe_suffix) + + custom_command = task.get('custom-command') + only_linux_command = task.get('only-linux-command') + only_windows_command = task.get('only-windows-command') # 检查Python文件是否存在 if not python_file.exists(): print(f"错误: Python文件不存在 {python_file}") continue + # 创建输出目录 + dist_path.mkdir(parents=True, exist_ok=True) + # 安装依赖 if requirements: print(f"安装依赖: {', '.join(requirements)}") subprocess.run([sys.executable, '-m', 'pip', 'install'] + requirements, check=True) - # 构建PyInstaller命令 + # 构建Nuitka命令 cmd = [ sys.executable, '-m', 'nuitka', - f'--output-filename={output_name}.exe', - f'--output-dir={dist_path}', # 输出目录 - '--onefile', # 单文件 + f'--output-filename={output_name}', + f'--output-dir={dist_path}', # 输出目录 + '--onefile', # 单文件 '--standalone', - '--mingw64', - # '--mode', - '--assume-yes-for-downloads', #自动下载外部代码 - # '--show-memory' - + f'--jobs={os.cpu_count()}', # 多线程 + '--assume-yes-for-downloads', # 自动下载外部代码 ] - # 添加窗口模式选项 - if windows_disable_console: - cmd.append('--windows-disable-console') - - # 添加图标选项 - if icon: - icon_path = base_dir / icon - if icon_path.exists(): - cmd.append(f'--windows-icon-from-ico={str(icon_path)}') - else: - print(f"警告: 图标文件不存在 {icon_path}") - - - if arrch == "ARM64": - print("UPX不支持当前架构") + # Windows特定参数 + if system_os == 'Windows': + cmd.append('--mingw64') + if windows_disable_console: + cmd.append('--windows-disable-console') + + if icon: + icon_path = base_dir / normalize_path(icon) + if icon_path.exists(): + cmd.append(f'--windows-icon-from-ico={icon_path}') + else: + print(f"警告: 图标文件不存在 {icon_path}") + if only_windows_command: + if isinstance(only_windows_command, str): + cmd.extend(only_windows_command.split()) + elif isinstance(only_windows_command, list): + cmd.extend(only_windows_command) + elif system_os == 'Linux': + if only_linux_command: + if isinstance(only_linux_command, str): + cmd.extend(only_linux_command.split()) + elif isinstance(only_linux_command, list): + cmd.extend(only_linux_command) + cmd.append('--clang') else: - if use_upx: - if upx_dir.exists(): - cmd.append('--plugin-enable=upx') - cmd.append(f'--upx-binary={str(upx_dir)}') - print(f"使用UPX压缩: {upx_dir}") + # Linux/macOS 使用 clang + cmd.append('--clang') + + # 启用插件 + if enable_plugins: + plugin_list = ','.join(enable_plugins) + cmd.append(f'--plugin-enable={plugin_list}') + + # UPX处理 + if 'upx' in enable_plugins: + upx_exe = 'upx.exe' if system_os == 'Windows' else 'upx' + upx_path = upx_dir / upx_exe + + if upx_path.exists(): + cmd.append(f'--upx-binary={upx_path}') + print(f"使用UPX压缩: {upx_path}") else: - print(f"警告: UPX目录不存在 {upx_dir}") - else: - print("不使用UPX压缩") + print(f"警告: UPX可执行文件不存在 {upx_path}") + + # 添加自定义命令 + if custom_command: + if isinstance(custom_command, str): + cmd.extend(custom_command.split()) + elif isinstance(custom_command, list): + cmd.extend(custom_command) - # 添加主Python文件 - t_file = str(uuid.uuid4()) + ".py" - t_file_path = base_dir / t_file - shutil.copy(str(python_file), t_file_path) - cmd.append(str(t_file_path)) + # 创建临时文件避免中文路径问题 + temp_file = base_dir / f"{uuid.uuid4().hex}.py" + shutil.copy(python_file, temp_file) + cmd.append(str(temp_file)) # 打印并执行命令 print("执行命令:", ' '.join(cmd)) - if timeout: - try: - result = subprocess.run(cmd,timeout=timeout) - except subprocess.TimeoutExpired: - print(f"任务[{i}/{len(config)} {task['name']}] 执行超时 {timeout} 秒") - print(f"任务[{i}/{len(config)} {task['name']}]失败: {e}") - task_error_list.append(task['name']) - continue - else: - result = subprocess.run(cmd) - if result.returncode == 0: + try: + # 执行打包命令 + result = subprocess.run( + cmd, + timeout=timeout, + check=True + ) + print(f"打包成功: {dist_path / output_name}") success_count += 1 - else: - print(f"打包失败,退出码: {result.returncode}") + + except subprocess.TimeoutExpired: + print(f"任务[{i}/{len(config)} {task['name']}] 执行超时 {timeout} 秒") + task_error_list.append(task['name']) + except subprocess.CalledProcessError as e: + print(f"打包失败,退出码: {e.returncode}") + print(f"错误输出: {e.stderr}") + task_error_list.append(task['name']) + finally: + # 确保临时文件被删除 + if temp_file.exists(): + temp_file.unlink() + except Exception as e: - print(f"任务[{i}/{len(config)} {task['name']}]失败: {e}") + print(f"任务[{i}/{len(config)} {task['name']}]失败: {str(e)}") + import traceback + traceback.print_exc() task_error_list.append(task['name']) - continue + + # 输出最终结果 + print("\n" + "="*50) + print(f"打包完成: 成功 {success_count} 个, 失败 {len(task_error_list)} 个") + if success_count != 0: - print(f"打包完成,成功打包 [{success_count}/{len(config)}] 个任务") - if task_error_list != []: - print(f"打包失败的任务: {', '.join(task_error_list)}") - else: - print("打包失败,没有成功打包任何任务") + files_list = [] + + # 遍历目录下的所有条目 + for entry in os.listdir(str(base_dir / 'dist')): + # 拼接完整的文件路径 + full_path = os.path.join(str(base_dir / 'dist'), entry) + # 检查该路径是否为文件 + if os.path.isfile(full_path): + files_list.append(entry) + + # 输出文件列表 + print(f'Dist: {str(files_list)}') + # 清理文件夹 + if delete_folders(dist_path): + print(f"已清理dist目录下文件夹: {dist_path}") + + if task_error_list: print(f"失败的任务: {', '.join(task_error_list)}") sys.exit(1) if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/package/nuitka_config.yml b/package/nuitka_config.yml index d900093..b27c113 100644 --- a/package/nuitka_config.yml +++ b/package/nuitka_config.yml @@ -1,6 +1,6 @@ - name: 'novel_crawler' version: 'v.25.07.08' - python-file: 'novel_crawler\novel_crawler_v.25.07.08.py' + python-file: 'novel_crawler/novel_crawler_v.25.07.08.py' install-requirements: [ 'beautifulsoup4', 'requests', @@ -8,73 +8,98 @@ 'rich', 'Pillow' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 2 # 0:文件夹 1:单文件 2:两者 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'Keyboard_monitoring' version: 'v.24.07.16' - python-file: '键盘监听\v.24.07.16.py' + python-file: '键盘监听/v.24.07.16.py' install-requirements: [ 'keyboard', 'configparser', 'pywin32', 'psutil' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'NetEase_Cloud_Music_Download' version: 'v.25-07-08' - python-file: '网易云音乐歌单批量下载歌曲\v.25-07-08.py' + python-file: '网易云音乐歌单批量下载歌曲/v.25-07-08.py' install-requirements: [ 'quote', 'requests', 'tabulate', 'mutagen' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'ftp_server' version: 'v.25-05-02' - python-file: 'ftp_server\ftp_server_v.25-05-02.py' + python-file: 'ftp_server/ftp_server_v.25-05-02.py' install-requirements: [ 'pyftpdlib' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'sunrise_sunset_info' version: 'v.25.05.02' - python-file: 'sunrise_sunset_info\sunrise_sunset_info_v.25.05.02.py' + python-file: 'sunrise_sunset_info/sunrise_sunset_info_v.25.05.02.py' install-requirements: [ 'pyftpdlib', 'astropy' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 # 0:文件夹 1:单文件 2:两者 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] diff --git a/package/nuitka_test_config.yml b/package/nuitka_test_config.yml new file mode 100644 index 0000000..1860375 --- /dev/null +++ b/package/nuitka_test_config.yml @@ -0,0 +1,18 @@ +- name: 'hello_world' + version: 'v.25.07.08' + python-file: 'package/hello_world.py' + install-requirements: [ + 'psutil' + ] + enable-plugins: [ + 'upx' + ] + # onefile: 2 # 0:文件夹 1:单文件 2:两者 + icon: package/assets/favicon.ico + windows-disable-console: False + distpath: 'dist' + timeout: 2700 + output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] From fecf58359ae29f3905f76b71cd128d08aabe64e7 Mon Sep 17 00:00:00 2001 From: Kissablecho Date: Thu, 10 Jul 2025 00:03:34 +0800 Subject: [PATCH 2/3] Revert "Merge branch 'dev' into main(#25)" (#27) This reverts commit 18fd015d1143c319d5b620630d05963d347bac15. --- .github/workflows/dev_package_and_upload.yml | 153 ++--------- .github/workflows/nuitka_package_release.yml | 143 ++-------- novel_crawler/novel_crawler_v.25.07.08.py | 2 +- package/hello_world.py | 55 ---- package/nuitka_build.py | 269 ++++++------------- package/nuitka_config.yml | 55 ++-- package/nuitka_test_config.yml | 18 -- 7 files changed, 140 insertions(+), 555 deletions(-) delete mode 100644 package/hello_world.py delete mode 100644 package/nuitka_test_config.yml diff --git a/.github/workflows/dev_package_and_upload.yml b/.github/workflows/dev_package_and_upload.yml index 1252b40..dc149f7 100644 --- a/.github/workflows/dev_package_and_upload.yml +++ b/.github/workflows/dev_package_and_upload.yml @@ -2,120 +2,37 @@ name: Nuitka Package and Upload(dev) on: workflow_dispatch: - inputs: - test: - description: '测试' - required: true - type: boolean - default: true - config_path: - description: '测试模式时用的配置文件路径(非测试时请忽略)' - required: true - type: string - default: 'package/nuitka_test_config.yml' - # push: - # branches: - # - dev - # paths: - # - 'package/nuitka_config.yml' + push: + branches: + - dev + paths: + - 'package/nuitka_config.yml' jobs: package-and-upload: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest,ubuntu-24.04-arm,windows-latest] # windows-11-arm没有对应的 Python - env: - PYTHON_VERSION: '3.10' - NUITKA_CACHE_DIR: ${{ github.workspace }}/nuitka-cache - UPXVERSION: '5.0.1' + runs-on: windows-latest # 添加必要的权限 permissions: contents: write # 允许创建发布和上传资源 steps: - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set Timezone to China Standard Time on Windows - if: ${{ runner.os == 'Windows' }} + - name: Set Timezone to China Standard Time run: tzutil /s "China Standard Time" shell: pwsh - - name: Set Timezone to China Standard Time on Linux - if: ${{ runner.os == 'Linux' }} - run: sudo timedatectl set-timezone Asia/Shanghai - + - name: Checkout code + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Cache UPX - id: cache-upx - uses: actions/cache@v4 - with: - path: upx - key: ${{ runner.os }}-${{ runner.arch }}-upx-v${{ env.UPXVERSION }} - restore-keys: | - ${{ runner.os }}-${{ runner.arch }}-upx- - - - name: Create UPX directory - if: ${{ steps.cache-upx.outputs.cache-hit != 'true' }} - run: mkdir -p ./upx - - - name: Install UPX on Linux - if: ${{ runner.os == 'Linux' && steps.cache-upx.outputs.cache-hit != 'true' }} - run: | - - UPX_URL="https://github.com/upx/upx/releases/download/v${{ env.UPXVERSION }}/upx-${{ env.UPXVERSION }}-${{ runner.arch == 'X64' && 'amd64' || 'arm64' }}_linux.tar.xz" - curl -L "$UPX_URL" -o upx.tar.xz - tar -xf upx.tar.xz -C ./upx --strip-components=1 - chmod +x ./upx/upx - - shell: bash - - - name: Install UPX on Windows - if: ${{ runner.os == 'Windows' && steps.cache-upx.outputs.cache-hit != 'true' }} - run: | - $arch = if (("${{ runner.arch }}" -eq "amd64") -or ("${{ runner.arch }}" -eq "X64")) { "win64" } else { "win32" } - $upxVersion = "${{ env.UPXVERSION }}" - $upxUrl = "https://github.com/upx/upx/releases/download/v$upxVersion/upx-$upxVersion-$arch.zip" - - Invoke-WebRequest -Uri $upxUrl -OutFile upx.zip - Expand-Archive -Path upx.zip -DestinationPath ./upx -Force - - # Windows 版本的 UPX 解压后在子目录中,需要移动到根目录 - Move-Item -Path "./upx/upx-$upxVersion-$arch/*" -Destination ./upx -Force - - shell: pwsh + python-version: '3.10' - - name: Verify UPX installation + - name: UPX Setup run: | - ./upx/upx --version - shell: bash - - - name: get pip cache dir on Windows - if: ${{ runner.os == 'Windows' }} - id: pip-cache-dir-window - run: echo "pip-cache-dir=$(pip cache dir)" >> $env:GITHUB_OUTPUT - - - name: get pip cache dir on Linux - if: ${{ runner.os == 'Linux' }} - id: pip-cache-dir-linux - run: echo "pip-cache-dir=$(pip cache dir)" >> $GITHUB_OUTPUT - - - name: pip cache - uses: actions/cache@v4 - with: - path: ${{ runner.os == 'Windows' && steps.pip-cache-dir-window.outputs.pip-cache-dir || steps.pip-cache-dir-linux.outputs.pip-cache-dir }} - key: ${{ runner.os }}-${{ runner.arch }}-pip-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} - restore-keys: | - ${{ runner.os }}-${{ runner.arch }}-pip- - + mkdir upx + curl -o upx/upx.exe https://assets.ksable.top/github/upx/upx/v5.0.1/windows-amd64/upx.exe - name: Install dependencies run: | @@ -135,56 +52,22 @@ jobs: # [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # # 设置控制台编码为UTF-8 # chcp.com 65001 - - - name: Install ccache on Linux - if: ${{ runner.os == 'Linux' }} - run: | - sudo apt-get update -y - sudo apt-get install -y ccache - - - name: Cache Nuitka cache directory - uses: actions/cache@v4 - with: - path: ${{ env.NUITKA_CACHE_DIR }} - key: nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}-nuitka-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} - restore-keys: | - nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}- - nuitka-${{ runner.os }}-${{ runner.arch }}- - - - name: Run packaging script on Windows - if: ${{ !github.event.inputs.test && runner.os == 'Windows' }} - run: | - # 设置Python使用UTF-8编码 - [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') - # 设置控制台编码为UTF-8 - chcp.com 65001 - python ./package/nuitka_build.py ./package/nuitka_config.yml - - name: Run Test packaging script on Windows - if: ${{ github.event.inputs.test && runner.os == 'Windows' }} + - name: Run packaging script run: | # 设置Python使用UTF-8编码 [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # 设置控制台编码为UTF-8 chcp.com 65001 - python ./package/nuitka_build.py ${{ github.event.inputs.config_path }} - - - name: Run packaging script on Linux - if: ${{ !github.event.inputs.test && runner.os == 'Linux' }} - run: | - python ./package/nuitka_build.py ./package/nuitka_config.yml - - - name: Run Test packaging script on Linux - if: ${{ github.event.inputs.test && runner.os == 'Linux' }} - run: | - python ./package/nuitka_build.py ${{ github.event.inputs.config_path }} + cd package + python nuitka_build.py nuitka_config.yml - name: Upload files with wildcards uses: actions/upload-artifact@v4 with: - name: ${{ runner.os }}-${{ runner.arch }}-${{ github.event.inputs.test && 'test-' || '' }}artifact + name: Artifact path: | - ./dist/* + ./dist/*.exe retention-days: 14 if-no-files-found: warn overwrite: true diff --git a/.github/workflows/nuitka_package_release.yml b/.github/workflows/nuitka_package_release.yml index 7b4fb95..490faf2 100644 --- a/.github/workflows/nuitka_package_release.yml +++ b/.github/workflows/nuitka_package_release.yml @@ -1,4 +1,4 @@ -name: Nuitka Package and Upload(dev) +name: Nuitka Package and Release on: workflow_dispatch: @@ -9,122 +9,41 @@ on: - 'package/nuitka_config.yml' jobs: - package-and-upload: + package-and-release: runs-on: windows-latest - # runs-on: ${{ matrix.os }} - # strategy: - # matrix: - # os: [ubuntu-latest,ubuntu-24.04-arm,windows-latest] # windows-11-arm没有对应的 Python - env: - PYTHON_VERSION: '3.10' - NUITKA_CACHE_DIR: ${{ github.workspace }}/nuitka-cache - UPXVERSION: '5.0.1' # 添加必要的权限 permissions: contents: write # 允许创建发布和上传资源 steps: + - name: Set Timezone to China Standard Time + run: tzutil /s "China Standard Time" + shell: pwsh - name: Checkout code uses: actions/checkout@v4 - - name: Set Timezone to China Standard Time on Windows - if: ${{ runner.os == 'Windows' }} - run: tzutil /s "China Standard Time" - shell: pwsh - - - name: Set Timezone to China Standard Time on Linux - if: ${{ runner.os == 'Linux' }} - run: sudo timedatectl set-timezone Asia/Shanghai - - - name: Generate version tag on Windows - if: ${{ runner.os == 'Windows' }} + - name: Generate version tag + id: version run: | # 使用 UTC 时间确保一致性 $date = (Get-Date).ToUniversalTime().ToString("yy.MM.dd") $tag = "v$date" $release = "Release $date" - echo "VERSION_TAG=$tag" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "RELEASE_NAME=$release" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - shell: pwsh - - - name: Generate version tag on Linux - if: ${{ runner.os == 'Linux' }} - run: | - # 使用 UTC 时间确保一致性 - DATE=$(date -u +%y.%m.%d) - echo "VERSION_TAG=v$DATE" >> $GITHUB_ENV - echo "RELEASE_NAME=Release $DATE" >> $GITHUB_ENV - shell: bash - + echo "tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + echo "release_name=$release" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append + + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Cache UPX - id: cache-upx - uses: actions/cache@v4 - with: - path: upx - key: ${{ runner.os }}-${{ runner.arch }}-upx-v${{ env.UPXVERSION }} - restore-keys: | - ${{ runner.os }}-${{ runner.arch }}-upx- - - - name: Create UPX directory - if: ${{ steps.cache-upx.outputs.cache-hit != 'true' }} - run: mkdir -p ./upx - - - name: Install UPX on Linux - if: ${{ runner.os == 'Linux' && steps.cache-upx.outputs.cache-hit != 'true' }} - run: | - - UPX_URL="https://github.com/upx/upx/releases/download/v${{ env.UPXVERSION }}/upx-${{ env.UPXVERSION }}-${{ runner.arch == 'X64' && 'amd64' || 'arm64' }}_linux.tar.xz" - curl -L "$UPX_URL" -o upx.tar.xz - tar -xf upx.tar.xz -C ./upx --strip-components=1 - chmod +x ./upx/upx - - shell: bash + python-version: '3.10' - - name: Install UPX on Windows - if: ${{ runner.os == 'Windows' && steps.cache-upx.outputs.cache-hit != 'true' }} + - name: UPX Setup run: | - $arch = if (("${{ runner.arch }}" -eq "amd64") -or ("${{ runner.arch }}" -eq "X64")) { "win64" } else { "win32" } - $upxVersion = "${{ env.UPXVERSION }}" - $upxUrl = "https://github.com/upx/upx/releases/download/v$upxVersion/upx-$upxVersion-$arch.zip" - - Invoke-WebRequest -Uri $upxUrl -OutFile upx.zip - Expand-Archive -Path upx.zip -DestinationPath ./upx -Force - - # Windows 版本的 UPX 解压后在子目录中,需要移动到根目录 - Move-Item -Path "./upx/upx-$upxVersion-$arch/*" -Destination ./upx -Force - - shell: pwsh - - - name: Verify UPX installation - run: | - ./upx/upx --version - shell: bash - - - name: get pip cache dir on Windows - if: ${{ runner.os == 'Windows' }} - id: pip-cache-dir-window - run: echo "pip-cache-dir=$(pip cache dir)" >> $env:GITHUB_OUTPUT - - - name: get pip cache dir on Linux - if: ${{ runner.os == 'Linux' }} - id: pip-cache-dir-linux - run: echo "pip-cache-dir=$(pip cache dir)" >> $GITHUB_OUTPUT - - - name: pip cache - uses: actions/cache@v4 - with: - path: ${{ runner.os == 'Windows' && steps.pip-cache-dir-window.outputs.pip-cache-dir || steps.pip-cache-dir-linux.outputs.pip-cache-dir }} - key: ${{ runner.os }}-${{ runner.arch }}-pip-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} - restore-keys: | - ${{ runner.os }}-${{ runner.arch }}-pip- - + mkdir upx + curl -o upx/upx.exe https://assets.ksable.top/github/upx/upx/v5.0.1/windows-amd64/upx.exe - name: Install dependencies run: | @@ -145,34 +64,14 @@ jobs: # # 设置控制台编码为UTF-8 # chcp.com 65001 - - name: Install ccache on Linux - if: ${{ runner.os == 'Linux' }} - run: | - sudo apt-get update -y - sudo apt-get install -y ccache - - - name: Cache Nuitka cache directory - uses: actions/cache@v4 - with: - path: ${{ env.NUITKA_CACHE_DIR }} - key: nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}-nuitka-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} - restore-keys: | - nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}- - nuitka-${{ runner.os }}-${{ runner.arch }}- - - - name: Run packaging script on Windows - if: ${{ runner.os == 'Windows' }} + - name: Run packaging script run: | # 设置Python使用UTF-8编码 [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # 设置控制台编码为UTF-8 chcp.com 65001 - python ./package/nuitka_build.py ./package/nuitka_config.yml - - - name: Run packaging script on Linux - if: ${{ runner.os == 'Linux' }} - run: | - python ./package/nuitka_build.py ./package/nuitka_config.yml + cd package + python nuitka_build.py nuitka_config.yml - name: Create Release id: create_release @@ -180,11 +79,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ env.VERSION_TAG }} - name: ${{ env.RELEASE_NAME }} + tag_name: ${{ steps.version.outputs.tag }} + name: ${{ steps.version.outputs.release_name }} generate_release_notes: true draft: false prerelease: false overwrite_files: true files: | - dist/* + dist/*.exe diff --git a/novel_crawler/novel_crawler_v.25.07.08.py b/novel_crawler/novel_crawler_v.25.07.08.py index b6269ee..91fe75b 100644 --- a/novel_crawler/novel_crawler_v.25.07.08.py +++ b/novel_crawler/novel_crawler_v.25.07.08.py @@ -417,7 +417,7 @@ def download_chapter(chapter_info, progress, task_id, chapter_count): # 主函数开始 def main(): - print_header("小说爬虫工具") + print_header("小说爬虫工具\n版本 v.25.07.07") if debug: logger.debug("Debug模式已开启") diff --git a/package/hello_world.py b/package/hello_world.py deleted file mode 100644 index ed9692d..0000000 --- a/package/hello_world.py +++ /dev/null @@ -1,55 +0,0 @@ -import platform -import os -import sys -import psutil -print('='*50) - -# 显示系统信息 -print('hello world') -print('-'*50) -print('系统信息') -print("操作系统:", platform.system()) -print("架构:", platform.machine()) -print("版本:", platform.version()) -print("平台:", platform.platform()) - -# 显示硬件信息 -print('-'*50) -print('CPU 信息') -print(f"CPU 核心数: {psutil.cpu_count(logical=False)}") -print(f"逻辑处理器数: {psutil.cpu_count(logical=True)}") -print("处理器信息:", platform.processor()) -cpu_times = psutil.cpu_times() -print(f"用户时间: {cpu_times.user}") -print(f"系统时间: {cpu_times.system}") -print(f"空闲时间: {cpu_times.idle}") - -memory_info = psutil.virtual_memory() - -print('-'*50) -print('内存 信息') -print(f"总内存: {memory_info.total / (1024 ** 3)} GB") -print(f"空闲内存: {memory_info.free / (1024 ** 3)} GB") -print(f"已用内存: {memory_info.used / (1024 ** 3)} GB") -print(f"可用内存: {memory_info.available / (1024 ** 3)} GB") - -# 获取内存详细信息 -print('-'*50) -print('交换内存 信息') -swap_memory = psutil.swap_memory() -print(f"交换内存总量: {swap_memory.total / (1024 ** 3)} GB") -print(f"已用交换内存: {swap_memory.used / (1024 ** 3)} GB") -print(f"可用交换内存: {swap_memory.free / (1024 ** 3)} GB") - -print("系统编码:", sys.getdefaultencoding()) -print("文件系统编码:", sys.getfilesystemencoding()) - - - -# 显示Python信息 -print("Python版本:", sys.version) -print("Python路径:", sys.executable) -print("当前工作目录:", os.getcwd()) - - -print('='*50) diff --git a/package/nuitka_build.py b/package/nuitka_build.py index 3854918..d19853f 100644 --- a/package/nuitka_build.py +++ b/package/nuitka_build.py @@ -5,43 +5,10 @@ import platform import argparse from pathlib import Path +# from zip import zip_files_and_folders import uuid import shutil -def normalize_path(path_str): - """将路径字符串中的反斜杠转换为当前系统的分隔符""" - return Path(path_str.replace('\\', os.sep)) - -def delete_folders(directory): - """删除指定目录下的所有文件夹,但保留文件""" - if os.path.basename(directory) == '' or os.path.basename(directory): - dir_name = os.path.basename(os.path.dirname(directory)) - else: - dir_name = os.path.basename(directory) - print(f'清理文件夹({dir_name})下的文件夹') - try: - # 确保目录存在 - if not os.path.exists(directory): - print(f"目录不存在: {directory}") - return True - - # 遍历目录中的所有项 - for item in os.listdir(directory): - item_path = os.path.join(directory, item) - # 如果是文件夹,则删除 - if os.path.isdir(item_path): - # print(f"删除文件夹: {item_path}") - rm_item_dir = ','.join(item_path) - shutil.rmtree(item_path) - # else: - # print(f"保留文件: {item_path}") - print(f'清理文件夹({dir_name})下的文件夹完成: {rm_item_dir}') - print("操作完成") - return True - except Exception as e: - print(f"发生错误: {e}") - return False - def main(): print("="*50) print("="*50) @@ -54,39 +21,28 @@ def main(): print("错误: 请使用Python 3.7或更高版本") return - system_os = platform.system() - arch = platform.machine() + Machine = platform.system() + arrch = platform.machine() - print(f"当前操作系统: {system_os}") - print(f'架构: {arch}') + print(f"当前操作系统: {Machine} {arrch}") print(f"平台详情: {platform.platform()}") - print("CPU核心数:", os.cpu_count()) - print("处理器信息:", platform.processor()) print(f"Python版本: {sys.version}") - print(f'工作目录: {os.getcwd()}') # 解析命令行参数 parser = argparse.ArgumentParser(description='Nuitka打包脚本') parser.add_argument('config', help='配置文件路径') args = parser.parse_args() - - # 基础路径设置 - base_dir = Path(__file__).resolve().parent.parent # 项目根目录 - upx_dir = base_dir / 'upx' # UPX目录 - dist_path = base_dir / 'dist' + # 读取配置文件 - # config_path = base_dir / args.config - config_path = args.config - if not config_path.exists(): - print(f"错误: 配置文件不存在 {config_path}") - sys.exit(1) - - with config_path.open('r', encoding='utf-8') as f: + with open(args.config, 'r', encoding='utf-8') as f: config = yaml.safe_load(f) + # 基础路径设置 + base_dir = Path(__file__).parent.parent # 项目根目录 + upx_dir = base_dir / './upx/' # UPX目录 + success_count = 0 task_error_list = [] - # 遍历所有打包任务 for i, task in enumerate(config, start=1): try: @@ -94,171 +50,116 @@ def main(): print(f"开始打包任务: [{i}/{len(config)}] {task['name']}") print(f"{'='*40}") - # 解析任务参数 - 使用路径规范化 - python_file = base_dir / normalize_path(task['python-file']) - # dist_path = base_dir / normalize_path(task['distpath']) + # 解析任务参数 + python_file = base_dir / task['python-file'] + dist_path = base_dir / task['distpath'] requirements = task.get('install-requirements', []) - enable_plugins = task.get('enable-plugins', []) - + use_upx = task.get('upx', False) + # onefile = task.get('onefile', 0) icon = task.get('icon') windows_disable_console = task.get('windows-disable-console', False) name = task.get('name') version = task.get('version') timeout = task.get('timeout', 60 * 45) - - # 处理输出文件名模板 - output_name_template = task.get('output-name-template', '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}{{exe_suffix}}') - - # 处理架构名称统一 - normalized_arch = "x64" if arch == "AMD64" else arch - exe_suffix = '.exe' if system_os == 'Windows' else '' - - output_name = output_name_template.replace('{{name}}', name) \ - .replace('{{version}}', version) \ - .replace('{{arch}}', normalized_arch) \ - .replace('{{os}}', system_os) \ - .replace('{{exe_suffix}}', exe_suffix) - - custom_command = task.get('custom-command') - only_linux_command = task.get('only-linux-command') - only_windows_command = task.get('only-windows-command') + output_name_template = task.get('output-name-template', '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}') + if arrch == "AMD64": + arrch = "x64" + output_name = output_name_template.replace('{{name}}', name).replace('{{version}}', version).replace('{{arch}}', arrch).replace('{{os}}', Machine) + + # 检查操作系统和架构 + # if Machine not in task.get('os', []): + # print(f"警告: 任务 [{i}/{len(config)} {task['name']}] 不支持当前操作系统 {Machine}") + # continue + # if arrch not in task.get('arch', []): + # print(f"警告: 任务 [{i}/{len(config)} {task['name']}] 不支持当前架构 {arrch}") + # continue # 检查Python文件是否存在 if not python_file.exists(): print(f"错误: Python文件不存在 {python_file}") continue - # 创建输出目录 - dist_path.mkdir(parents=True, exist_ok=True) - # 安装依赖 if requirements: print(f"安装依赖: {', '.join(requirements)}") subprocess.run([sys.executable, '-m', 'pip', 'install'] + requirements, check=True) - # 构建Nuitka命令 + # 构建PyInstaller命令 cmd = [ sys.executable, '-m', 'nuitka', - f'--output-filename={output_name}', - f'--output-dir={dist_path}', # 输出目录 - '--onefile', # 单文件 + f'--output-filename={output_name}.exe', + f'--output-dir={dist_path}', # 输出目录 + '--onefile', # 单文件 '--standalone', - f'--jobs={os.cpu_count()}', # 多线程 - '--assume-yes-for-downloads', # 自动下载外部代码 - ] - - # Windows特定参数 - if system_os == 'Windows': - cmd.append('--mingw64') - if windows_disable_console: - cmd.append('--windows-disable-console') + '--mingw64', + # '--mode', + '--assume-yes-for-downloads', #自动下载外部代码 + # '--show-memory' - if icon: - icon_path = base_dir / normalize_path(icon) - if icon_path.exists(): - cmd.append(f'--windows-icon-from-ico={icon_path}') - else: - print(f"警告: 图标文件不存在 {icon_path}") - if only_windows_command: - if isinstance(only_windows_command, str): - cmd.extend(only_windows_command.split()) - elif isinstance(only_windows_command, list): - cmd.extend(only_windows_command) - elif system_os == 'Linux': - if only_linux_command: - if isinstance(only_linux_command, str): - cmd.extend(only_linux_command.split()) - elif isinstance(only_linux_command, list): - cmd.extend(only_linux_command) - cmd.append('--clang') - else: - # Linux/macOS 使用 clang - cmd.append('--clang') + ] - # 启用插件 - if enable_plugins: - plugin_list = ','.join(enable_plugins) - cmd.append(f'--plugin-enable={plugin_list}') - - # UPX处理 - if 'upx' in enable_plugins: - upx_exe = 'upx.exe' if system_os == 'Windows' else 'upx' - upx_path = upx_dir / upx_exe + # 添加窗口模式选项 + if windows_disable_console: + cmd.append('--windows-disable-console') + + # 添加图标选项 + if icon: + icon_path = base_dir / icon + if icon_path.exists(): + cmd.append(f'--windows-icon-from-ico={str(icon_path)}') + else: + print(f"警告: 图标文件不存在 {icon_path}") - if upx_path.exists(): - cmd.append(f'--upx-binary={upx_path}') - print(f"使用UPX压缩: {upx_path}") + + if arrch == "ARM64": + print("UPX不支持当前架构") + else: + if use_upx: + if upx_dir.exists(): + cmd.append('--plugin-enable=upx') + cmd.append(f'--upx-binary={str(upx_dir)}') + print(f"使用UPX压缩: {upx_dir}") else: - print(f"警告: UPX可执行文件不存在 {upx_path}") - - # 添加自定义命令 - if custom_command: - if isinstance(custom_command, str): - cmd.extend(custom_command.split()) - elif isinstance(custom_command, list): - cmd.extend(custom_command) + print(f"警告: UPX目录不存在 {upx_dir}") + else: + print("不使用UPX压缩") - # 创建临时文件避免中文路径问题 - temp_file = base_dir / f"{uuid.uuid4().hex}.py" - shutil.copy(python_file, temp_file) - cmd.append(str(temp_file)) + # 添加主Python文件 + t_file = str(uuid.uuid4()) + ".py" + t_file_path = base_dir / t_file + shutil.copy(str(python_file), t_file_path) + cmd.append(str(t_file_path)) # 打印并执行命令 print("执行命令:", ' '.join(cmd)) + if timeout: + try: + result = subprocess.run(cmd,timeout=timeout) + except subprocess.TimeoutExpired: + print(f"任务[{i}/{len(config)} {task['name']}] 执行超时 {timeout} 秒") + print(f"任务[{i}/{len(config)} {task['name']}]失败: {e}") + task_error_list.append(task['name']) + continue + else: + result = subprocess.run(cmd) - try: - # 执行打包命令 - result = subprocess.run( - cmd, - timeout=timeout, - check=True - ) - + if result.returncode == 0: print(f"打包成功: {dist_path / output_name}") success_count += 1 - - except subprocess.TimeoutExpired: - print(f"任务[{i}/{len(config)} {task['name']}] 执行超时 {timeout} 秒") - task_error_list.append(task['name']) - except subprocess.CalledProcessError as e: - print(f"打包失败,退出码: {e.returncode}") - print(f"错误输出: {e.stderr}") - task_error_list.append(task['name']) - finally: - # 确保临时文件被删除 - if temp_file.exists(): - temp_file.unlink() - + else: + print(f"打包失败,退出码: {result.returncode}") except Exception as e: - print(f"任务[{i}/{len(config)} {task['name']}]失败: {str(e)}") - import traceback - traceback.print_exc() + print(f"任务[{i}/{len(config)} {task['name']}]失败: {e}") task_error_list.append(task['name']) - - # 输出最终结果 - print("\n" + "="*50) - print(f"打包完成: 成功 {success_count} 个, 失败 {len(task_error_list)} 个") - + continue if success_count != 0: - files_list = [] - - # 遍历目录下的所有条目 - for entry in os.listdir(str(base_dir / 'dist')): - # 拼接完整的文件路径 - full_path = os.path.join(str(base_dir / 'dist'), entry) - # 检查该路径是否为文件 - if os.path.isfile(full_path): - files_list.append(entry) - - # 输出文件列表 - print(f'Dist: {str(files_list)}') - # 清理文件夹 - if delete_folders(dist_path): - print(f"已清理dist目录下文件夹: {dist_path}") - - if task_error_list: + print(f"打包完成,成功打包 [{success_count}/{len(config)}] 个任务") + if task_error_list != []: + print(f"打包失败的任务: {', '.join(task_error_list)}") + else: + print("打包失败,没有成功打包任何任务") print(f"失败的任务: {', '.join(task_error_list)}") sys.exit(1) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/package/nuitka_config.yml b/package/nuitka_config.yml index b27c113..d900093 100644 --- a/package/nuitka_config.yml +++ b/package/nuitka_config.yml @@ -1,6 +1,6 @@ - name: 'novel_crawler' version: 'v.25.07.08' - python-file: 'novel_crawler/novel_crawler_v.25.07.08.py' + python-file: 'novel_crawler\novel_crawler_v.25.07.08.py' install-requirements: [ 'beautifulsoup4', 'requests', @@ -8,98 +8,73 @@ 'rich', 'Pillow' ] - enable-plugins: [ - 'upx' - ] + upx: true # onefile: 2 # 0:文件夹 1:单文件 2:两者 - icon: package/assets/favicon.ico + icon: package\assets\favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' - custom-command: [] - only-linux-command: [] - only-windows-command: [] - name: 'Keyboard_monitoring' version: 'v.24.07.16' - python-file: '键盘监听/v.24.07.16.py' + python-file: '键盘监听\v.24.07.16.py' install-requirements: [ 'keyboard', 'configparser', 'pywin32', 'psutil' ] - enable-plugins: [ - 'upx' - ] + upx: true # onefile: 1 - icon: package/assets/favicon.ico + icon: package\assets\favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' - custom-command: [] - only-linux-command: [] - only-windows-command: [] - name: 'NetEase_Cloud_Music_Download' version: 'v.25-07-08' - python-file: '网易云音乐歌单批量下载歌曲/v.25-07-08.py' + python-file: '网易云音乐歌单批量下载歌曲\v.25-07-08.py' install-requirements: [ 'quote', 'requests', 'tabulate', 'mutagen' ] - enable-plugins: [ - 'upx' - ] + upx: true # onefile: 1 - icon: package/assets/favicon.ico + icon: package\assets\favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' - custom-command: [] - only-linux-command: [] - only-windows-command: [] - name: 'ftp_server' version: 'v.25-05-02' - python-file: 'ftp_server/ftp_server_v.25-05-02.py' + python-file: 'ftp_server\ftp_server_v.25-05-02.py' install-requirements: [ 'pyftpdlib' ] - enable-plugins: [ - 'upx' - ] + upx: true # onefile: 1 - icon: package/assets/favicon.ico + icon: package\assets\favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' - custom-command: [] - only-linux-command: [] - only-windows-command: [] - name: 'sunrise_sunset_info' version: 'v.25.05.02' - python-file: 'sunrise_sunset_info/sunrise_sunset_info_v.25.05.02.py' + python-file: 'sunrise_sunset_info\sunrise_sunset_info_v.25.05.02.py' install-requirements: [ 'pyftpdlib', 'astropy' ] - enable-plugins: [ - 'upx' - ] + upx: true # onefile: 1 # 0:文件夹 1:单文件 2:两者 - icon: package/assets/favicon.ico + icon: package\assets\favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' - custom-command: [] - only-linux-command: [] - only-windows-command: [] diff --git a/package/nuitka_test_config.yml b/package/nuitka_test_config.yml deleted file mode 100644 index 1860375..0000000 --- a/package/nuitka_test_config.yml +++ /dev/null @@ -1,18 +0,0 @@ -- name: 'hello_world' - version: 'v.25.07.08' - python-file: 'package/hello_world.py' - install-requirements: [ - 'psutil' - ] - enable-plugins: [ - 'upx' - ] - # onefile: 2 # 0:文件夹 1:单文件 2:两者 - icon: package/assets/favicon.ico - windows-disable-console: False - distpath: 'dist' - timeout: 2700 - output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' - custom-command: [] - only-linux-command: [] - only-windows-command: [] From 4e5e27b74987f3be16c10f1b31e39f7fbbaf6721 Mon Sep 17 00:00:00 2001 From: Kissablecho Date: Thu, 10 Jul 2025 00:05:48 +0800 Subject: [PATCH 3/3] Merge branch 'main' into dev (#28) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dev_package_and_upload.yml (#17) * 更新 NetEase_Cloud_Music_Download * sync (#19) * Update dev_package_and_upload.yml * Update README.md * update nuitka_build.py * Update pyinstaller_package_and_release.yml * Update nuitka_package_release.yml * Update nuitka_build.py * 更新 NetEase_Cloud_Music_Download (#18) * Update dev_package_and_upload.yml (#17) * 更新 NetEase_Cloud_Music_Download * 更新依赖项,添加psutil和astropy库 * 添加favicon.ico图标文件,并在配置中启用UPX压缩 * Nuitka Build 启用多核并行编译 * test cache * 删去错误版本信息 * fix dev_package_and_upload.yml * fix dev_package_and_upload.yml * fix dev_package_and_upload.yml pip-cache-dir * Update dev_package_and_upload.yml fix type * 添加对插件的支持,更新配置文件以启用UPX插件和自定义命令 * 禁用 Nuitka Package and Upload(dev) 自动流程,启用手动触发,添加测试流程 * fix Nuitka Package and Upload(dev) * try fix nuitka_build.py * Nuitka Package and Upload(dev) update upx installer and use more os bulid * Nuitka Package and Upload(dev) fix value * Nuitka Package and Upload(dev) fix Timezone * update * update nuitka 兼容Linux Windows平台 * remove windows-11-arm * update * more option * fix artifact upload * update Package * fix workflows name and fix nuitka_build.py --- .github/workflows/dev_package_and_upload.yml | 153 +++++++++-- .github/workflows/nuitka_package_release.yml | 141 ++++++++-- novel_crawler/novel_crawler_v.25.07.08.py | 2 +- package/hello_world.py | 55 ++++ package/nuitka_build.py | 269 +++++++++++++------ package/nuitka_config.yml | 55 ++-- package/nuitka_test_config.yml | 18 ++ 7 files changed, 554 insertions(+), 139 deletions(-) create mode 100644 package/hello_world.py create mode 100644 package/nuitka_test_config.yml diff --git a/.github/workflows/dev_package_and_upload.yml b/.github/workflows/dev_package_and_upload.yml index dc149f7..1252b40 100644 --- a/.github/workflows/dev_package_and_upload.yml +++ b/.github/workflows/dev_package_and_upload.yml @@ -2,37 +2,120 @@ name: Nuitka Package and Upload(dev) on: workflow_dispatch: - push: - branches: - - dev - paths: - - 'package/nuitka_config.yml' + inputs: + test: + description: '测试' + required: true + type: boolean + default: true + config_path: + description: '测试模式时用的配置文件路径(非测试时请忽略)' + required: true + type: string + default: 'package/nuitka_test_config.yml' + # push: + # branches: + # - dev + # paths: + # - 'package/nuitka_config.yml' jobs: package-and-upload: - runs-on: windows-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest,ubuntu-24.04-arm,windows-latest] # windows-11-arm没有对应的 Python + env: + PYTHON_VERSION: '3.10' + NUITKA_CACHE_DIR: ${{ github.workspace }}/nuitka-cache + UPXVERSION: '5.0.1' # 添加必要的权限 permissions: contents: write # 允许创建发布和上传资源 steps: - - name: Set Timezone to China Standard Time - run: tzutil /s "China Standard Time" - shell: pwsh - name: Checkout code uses: actions/checkout@v4 + + - name: Set Timezone to China Standard Time on Windows + if: ${{ runner.os == 'Windows' }} + run: tzutil /s "China Standard Time" + shell: pwsh + + - name: Set Timezone to China Standard Time on Linux + if: ${{ runner.os == 'Linux' }} + run: sudo timedatectl set-timezone Asia/Shanghai + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: ${{ env.PYTHON_VERSION }} + + - name: Cache UPX + id: cache-upx + uses: actions/cache@v4 + with: + path: upx + key: ${{ runner.os }}-${{ runner.arch }}-upx-v${{ env.UPXVERSION }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-upx- + + - name: Create UPX directory + if: ${{ steps.cache-upx.outputs.cache-hit != 'true' }} + run: mkdir -p ./upx + + - name: Install UPX on Linux + if: ${{ runner.os == 'Linux' && steps.cache-upx.outputs.cache-hit != 'true' }} + run: | + + UPX_URL="https://github.com/upx/upx/releases/download/v${{ env.UPXVERSION }}/upx-${{ env.UPXVERSION }}-${{ runner.arch == 'X64' && 'amd64' || 'arm64' }}_linux.tar.xz" + curl -L "$UPX_URL" -o upx.tar.xz + tar -xf upx.tar.xz -C ./upx --strip-components=1 + chmod +x ./upx/upx + + shell: bash + + - name: Install UPX on Windows + if: ${{ runner.os == 'Windows' && steps.cache-upx.outputs.cache-hit != 'true' }} + run: | + $arch = if (("${{ runner.arch }}" -eq "amd64") -or ("${{ runner.arch }}" -eq "X64")) { "win64" } else { "win32" } + $upxVersion = "${{ env.UPXVERSION }}" + $upxUrl = "https://github.com/upx/upx/releases/download/v$upxVersion/upx-$upxVersion-$arch.zip" + + Invoke-WebRequest -Uri $upxUrl -OutFile upx.zip + Expand-Archive -Path upx.zip -DestinationPath ./upx -Force + + # Windows 版本的 UPX 解压后在子目录中,需要移动到根目录 + Move-Item -Path "./upx/upx-$upxVersion-$arch/*" -Destination ./upx -Force + + shell: pwsh - - name: UPX Setup + - name: Verify UPX installation run: | - mkdir upx - curl -o upx/upx.exe https://assets.ksable.top/github/upx/upx/v5.0.1/windows-amd64/upx.exe + ./upx/upx --version + shell: bash + + - name: get pip cache dir on Windows + if: ${{ runner.os == 'Windows' }} + id: pip-cache-dir-window + run: echo "pip-cache-dir=$(pip cache dir)" >> $env:GITHUB_OUTPUT + + - name: get pip cache dir on Linux + if: ${{ runner.os == 'Linux' }} + id: pip-cache-dir-linux + run: echo "pip-cache-dir=$(pip cache dir)" >> $GITHUB_OUTPUT + + - name: pip cache + uses: actions/cache@v4 + with: + path: ${{ runner.os == 'Windows' && steps.pip-cache-dir-window.outputs.pip-cache-dir || steps.pip-cache-dir-linux.outputs.pip-cache-dir }} + key: ${{ runner.os }}-${{ runner.arch }}-pip-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-pip- + - name: Install dependencies run: | @@ -52,22 +135,56 @@ jobs: # [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # # 设置控制台编码为UTF-8 # chcp.com 65001 + + - name: Install ccache on Linux + if: ${{ runner.os == 'Linux' }} + run: | + sudo apt-get update -y + sudo apt-get install -y ccache + + - name: Cache Nuitka cache directory + uses: actions/cache@v4 + with: + path: ${{ env.NUITKA_CACHE_DIR }} + key: nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}-nuitka-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}- + nuitka-${{ runner.os }}-${{ runner.arch }}- + + - name: Run packaging script on Windows + if: ${{ !github.event.inputs.test && runner.os == 'Windows' }} + run: | + # 设置Python使用UTF-8编码 + [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') + # 设置控制台编码为UTF-8 + chcp.com 65001 + python ./package/nuitka_build.py ./package/nuitka_config.yml - - name: Run packaging script + - name: Run Test packaging script on Windows + if: ${{ github.event.inputs.test && runner.os == 'Windows' }} run: | # 设置Python使用UTF-8编码 [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # 设置控制台编码为UTF-8 chcp.com 65001 - cd package - python nuitka_build.py nuitka_config.yml + python ./package/nuitka_build.py ${{ github.event.inputs.config_path }} + + - name: Run packaging script on Linux + if: ${{ !github.event.inputs.test && runner.os == 'Linux' }} + run: | + python ./package/nuitka_build.py ./package/nuitka_config.yml + + - name: Run Test packaging script on Linux + if: ${{ github.event.inputs.test && runner.os == 'Linux' }} + run: | + python ./package/nuitka_build.py ${{ github.event.inputs.config_path }} - name: Upload files with wildcards uses: actions/upload-artifact@v4 with: - name: Artifact + name: ${{ runner.os }}-${{ runner.arch }}-${{ github.event.inputs.test && 'test-' || '' }}artifact path: | - ./dist/*.exe + ./dist/* retention-days: 14 if-no-files-found: warn overwrite: true diff --git a/.github/workflows/nuitka_package_release.yml b/.github/workflows/nuitka_package_release.yml index 490faf2..e081768 100644 --- a/.github/workflows/nuitka_package_release.yml +++ b/.github/workflows/nuitka_package_release.yml @@ -9,41 +9,122 @@ on: - 'package/nuitka_config.yml' jobs: - package-and-release: + package-and-upload: runs-on: windows-latest + # runs-on: ${{ matrix.os }} + # strategy: + # matrix: + # os: [ubuntu-latest,ubuntu-24.04-arm,windows-latest] # windows-11-arm没有对应的 Python + env: + PYTHON_VERSION: '3.10' + NUITKA_CACHE_DIR: ${{ github.workspace }}/nuitka-cache + UPXVERSION: '5.0.1' # 添加必要的权限 permissions: contents: write # 允许创建发布和上传资源 steps: - - name: Set Timezone to China Standard Time - run: tzutil /s "China Standard Time" - shell: pwsh - name: Checkout code uses: actions/checkout@v4 - - name: Generate version tag - id: version + - name: Set Timezone to China Standard Time on Windows + if: ${{ runner.os == 'Windows' }} + run: tzutil /s "China Standard Time" + shell: pwsh + + - name: Set Timezone to China Standard Time on Linux + if: ${{ runner.os == 'Linux' }} + run: sudo timedatectl set-timezone Asia/Shanghai + + - name: Generate version tag on Windows + if: ${{ runner.os == 'Windows' }} run: | # 使用 UTC 时间确保一致性 $date = (Get-Date).ToUniversalTime().ToString("yy.MM.dd") $tag = "v$date" $release = "Release $date" - echo "tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - echo "release_name=$release" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - - + echo "VERSION_TAG=$tag" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "RELEASE_NAME=$release" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + shell: pwsh + + - name: Generate version tag on Linux + if: ${{ runner.os == 'Linux' }} + run: | + # 使用 UTC 时间确保一致性 + DATE=$(date -u +%y.%m.%d) + echo "VERSION_TAG=v$DATE" >> $GITHUB_ENV + echo "RELEASE_NAME=Release $DATE" >> $GITHUB_ENV + shell: bash + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: ${{ env.PYTHON_VERSION }} + + - name: Cache UPX + id: cache-upx + uses: actions/cache@v4 + with: + path: upx + key: ${{ runner.os }}-${{ runner.arch }}-upx-v${{ env.UPXVERSION }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-upx- + + - name: Create UPX directory + if: ${{ steps.cache-upx.outputs.cache-hit != 'true' }} + run: mkdir -p ./upx + + - name: Install UPX on Linux + if: ${{ runner.os == 'Linux' && steps.cache-upx.outputs.cache-hit != 'true' }} + run: | + + UPX_URL="https://github.com/upx/upx/releases/download/v${{ env.UPXVERSION }}/upx-${{ env.UPXVERSION }}-${{ runner.arch == 'X64' && 'amd64' || 'arm64' }}_linux.tar.xz" + curl -L "$UPX_URL" -o upx.tar.xz + tar -xf upx.tar.xz -C ./upx --strip-components=1 + chmod +x ./upx/upx + + shell: bash - - name: UPX Setup + - name: Install UPX on Windows + if: ${{ runner.os == 'Windows' && steps.cache-upx.outputs.cache-hit != 'true' }} run: | - mkdir upx - curl -o upx/upx.exe https://assets.ksable.top/github/upx/upx/v5.0.1/windows-amd64/upx.exe + $arch = if (("${{ runner.arch }}" -eq "amd64") -or ("${{ runner.arch }}" -eq "X64")) { "win64" } else { "win32" } + $upxVersion = "${{ env.UPXVERSION }}" + $upxUrl = "https://github.com/upx/upx/releases/download/v$upxVersion/upx-$upxVersion-$arch.zip" + + Invoke-WebRequest -Uri $upxUrl -OutFile upx.zip + Expand-Archive -Path upx.zip -DestinationPath ./upx -Force + + # Windows 版本的 UPX 解压后在子目录中,需要移动到根目录 + Move-Item -Path "./upx/upx-$upxVersion-$arch/*" -Destination ./upx -Force + + shell: pwsh + + - name: Verify UPX installation + run: | + ./upx/upx --version + shell: bash + + - name: get pip cache dir on Windows + if: ${{ runner.os == 'Windows' }} + id: pip-cache-dir-window + run: echo "pip-cache-dir=$(pip cache dir)" >> $env:GITHUB_OUTPUT + + - name: get pip cache dir on Linux + if: ${{ runner.os == 'Linux' }} + id: pip-cache-dir-linux + run: echo "pip-cache-dir=$(pip cache dir)" >> $GITHUB_OUTPUT + + - name: pip cache + uses: actions/cache@v4 + with: + path: ${{ runner.os == 'Windows' && steps.pip-cache-dir-window.outputs.pip-cache-dir || steps.pip-cache-dir-linux.outputs.pip-cache-dir }} + key: ${{ runner.os }}-${{ runner.arch }}-pip-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-pip- + - name: Install dependencies run: | @@ -64,14 +145,34 @@ jobs: # # 设置控制台编码为UTF-8 # chcp.com 65001 - - name: Run packaging script + - name: Install ccache on Linux + if: ${{ runner.os == 'Linux' }} + run: | + sudo apt-get update -y + sudo apt-get install -y ccache + + - name: Cache Nuitka cache directory + uses: actions/cache@v4 + with: + path: ${{ env.NUITKA_CACHE_DIR }} + key: nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}-nuitka-${{ github.event.inputs.test && hashFiles(github.event.inputs.config_path) || hashFiles('package/nuitka_build.py') }} + restore-keys: | + nuitka-${{ runner.os }}-${{ runner.arch }}-python-${{ env.PYTHON_VERSION }}- + nuitka-${{ runner.os }}-${{ runner.arch }}- + + - name: Run packaging script on Windows + if: ${{ runner.os == 'Windows' }} run: | # 设置Python使用UTF-8编码 [System.Environment]::SetEnvironmentVariable('PYTHONUTF8', '1', 'Process') # 设置控制台编码为UTF-8 chcp.com 65001 - cd package - python nuitka_build.py nuitka_config.yml + python ./package/nuitka_build.py ./package/nuitka_config.yml + + - name: Run packaging script on Linux + if: ${{ runner.os == 'Linux' }} + run: | + python ./package/nuitka_build.py ./package/nuitka_config.yml - name: Create Release id: create_release @@ -79,11 +180,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ steps.version.outputs.tag }} - name: ${{ steps.version.outputs.release_name }} + tag_name: ${{ env.VERSION_TAG }} + name: ${{ env.RELEASE_NAME }} generate_release_notes: true draft: false prerelease: false overwrite_files: true files: | - dist/*.exe + dist/* diff --git a/novel_crawler/novel_crawler_v.25.07.08.py b/novel_crawler/novel_crawler_v.25.07.08.py index 91fe75b..b6269ee 100644 --- a/novel_crawler/novel_crawler_v.25.07.08.py +++ b/novel_crawler/novel_crawler_v.25.07.08.py @@ -417,7 +417,7 @@ def download_chapter(chapter_info, progress, task_id, chapter_count): # 主函数开始 def main(): - print_header("小说爬虫工具\n版本 v.25.07.07") + print_header("小说爬虫工具") if debug: logger.debug("Debug模式已开启") diff --git a/package/hello_world.py b/package/hello_world.py new file mode 100644 index 0000000..ed9692d --- /dev/null +++ b/package/hello_world.py @@ -0,0 +1,55 @@ +import platform +import os +import sys +import psutil +print('='*50) + +# 显示系统信息 +print('hello world') +print('-'*50) +print('系统信息') +print("操作系统:", platform.system()) +print("架构:", platform.machine()) +print("版本:", platform.version()) +print("平台:", platform.platform()) + +# 显示硬件信息 +print('-'*50) +print('CPU 信息') +print(f"CPU 核心数: {psutil.cpu_count(logical=False)}") +print(f"逻辑处理器数: {psutil.cpu_count(logical=True)}") +print("处理器信息:", platform.processor()) +cpu_times = psutil.cpu_times() +print(f"用户时间: {cpu_times.user}") +print(f"系统时间: {cpu_times.system}") +print(f"空闲时间: {cpu_times.idle}") + +memory_info = psutil.virtual_memory() + +print('-'*50) +print('内存 信息') +print(f"总内存: {memory_info.total / (1024 ** 3)} GB") +print(f"空闲内存: {memory_info.free / (1024 ** 3)} GB") +print(f"已用内存: {memory_info.used / (1024 ** 3)} GB") +print(f"可用内存: {memory_info.available / (1024 ** 3)} GB") + +# 获取内存详细信息 +print('-'*50) +print('交换内存 信息') +swap_memory = psutil.swap_memory() +print(f"交换内存总量: {swap_memory.total / (1024 ** 3)} GB") +print(f"已用交换内存: {swap_memory.used / (1024 ** 3)} GB") +print(f"可用交换内存: {swap_memory.free / (1024 ** 3)} GB") + +print("系统编码:", sys.getdefaultencoding()) +print("文件系统编码:", sys.getfilesystemencoding()) + + + +# 显示Python信息 +print("Python版本:", sys.version) +print("Python路径:", sys.executable) +print("当前工作目录:", os.getcwd()) + + +print('='*50) diff --git a/package/nuitka_build.py b/package/nuitka_build.py index d19853f..948c98f 100644 --- a/package/nuitka_build.py +++ b/package/nuitka_build.py @@ -5,10 +5,43 @@ import platform import argparse from pathlib import Path -# from zip import zip_files_and_folders import uuid import shutil +def normalize_path(path_str): + """将路径字符串中的反斜杠转换为当前系统的分隔符""" + return Path(path_str.replace('\\', os.sep)) + +def delete_folders(directory): + """删除指定目录下的所有文件夹,但保留文件""" + if os.path.basename(directory) == '' or os.path.basename(directory): + dir_name = os.path.basename(os.path.dirname(directory)) + else: + dir_name = os.path.basename(directory) + print(f'清理文件夹({dir_name})下的文件夹') + try: + # 确保目录存在 + if not os.path.exists(directory): + print(f"目录不存在: {directory}") + return True + + # 遍历目录中的所有项 + for item in os.listdir(directory): + item_path = os.path.join(directory, item) + # 如果是文件夹,则删除 + if os.path.isdir(item_path): + # print(f"删除文件夹: {item_path}") + rm_item_dir = ','.join(item_path) + shutil.rmtree(item_path) + # else: + # print(f"保留文件: {item_path}") + print(f'清理文件夹({dir_name})下的文件夹完成: {rm_item_dir}') + print("操作完成") + return True + except Exception as e: + print(f"发生错误: {e}") + return False + def main(): print("="*50) print("="*50) @@ -21,28 +54,39 @@ def main(): print("错误: 请使用Python 3.7或更高版本") return - Machine = platform.system() - arrch = platform.machine() + system_os = platform.system() + arch = platform.machine() - print(f"当前操作系统: {Machine} {arrch}") + print(f"当前操作系统: {system_os}") + print(f'架构: {arch}') print(f"平台详情: {platform.platform()}") + print("CPU核心数:", os.cpu_count()) + print("处理器信息:", platform.processor()) print(f"Python版本: {sys.version}") + print(f'工作目录: {os.getcwd()}') # 解析命令行参数 parser = argparse.ArgumentParser(description='Nuitka打包脚本') parser.add_argument('config', help='配置文件路径') args = parser.parse_args() - - # 读取配置文件 - with open(args.config, 'r', encoding='utf-8') as f: - config = yaml.safe_load(f) # 基础路径设置 - base_dir = Path(__file__).parent.parent # 项目根目录 - upx_dir = base_dir / './upx/' # UPX目录 + base_dir = Path(__file__).resolve().parent.parent # 项目根目录 + upx_dir = base_dir / 'upx' # UPX目录 + dist_path = base_dir / 'dist' + # 读取配置文件 + # config_path = base_dir / args.config + config_path = Path(args.config) + if not config_path.exists(): + print(f"错误: 配置文件不存在 {config_path}") + sys.exit(1) + + with config_path.open('r', encoding='utf-8') as f: + config = yaml.safe_load(f) success_count = 0 task_error_list = [] + # 遍历所有打包任务 for i, task in enumerate(config, start=1): try: @@ -50,116 +94,171 @@ def main(): print(f"开始打包任务: [{i}/{len(config)}] {task['name']}") print(f"{'='*40}") - # 解析任务参数 - python_file = base_dir / task['python-file'] - dist_path = base_dir / task['distpath'] + # 解析任务参数 - 使用路径规范化 + python_file = base_dir / normalize_path(task['python-file']) + # dist_path = base_dir / normalize_path(task['distpath']) requirements = task.get('install-requirements', []) - use_upx = task.get('upx', False) - # onefile = task.get('onefile', 0) + enable_plugins = task.get('enable-plugins', []) + icon = task.get('icon') windows_disable_console = task.get('windows-disable-console', False) name = task.get('name') version = task.get('version') timeout = task.get('timeout', 60 * 45) - output_name_template = task.get('output-name-template', '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}') - if arrch == "AMD64": - arrch = "x64" - output_name = output_name_template.replace('{{name}}', name).replace('{{version}}', version).replace('{{arch}}', arrch).replace('{{os}}', Machine) - - # 检查操作系统和架构 - # if Machine not in task.get('os', []): - # print(f"警告: 任务 [{i}/{len(config)} {task['name']}] 不支持当前操作系统 {Machine}") - # continue - # if arrch not in task.get('arch', []): - # print(f"警告: 任务 [{i}/{len(config)} {task['name']}] 不支持当前架构 {arrch}") - # continue + + # 处理输出文件名模板 + output_name_template = task.get('output-name-template', '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}{{exe_suffix}}') + + # 处理架构名称统一 + normalized_arch = "x64" if arch == "AMD64" else arch + exe_suffix = '.exe' if system_os == 'Windows' else '' + + output_name = output_name_template.replace('{{name}}', name) \ + .replace('{{version}}', version) \ + .replace('{{arch}}', normalized_arch) \ + .replace('{{os}}', system_os) \ + .replace('{{exe_suffix}}', exe_suffix) + + custom_command = task.get('custom-command') + only_linux_command = task.get('only-linux-command') + only_windows_command = task.get('only-windows-command') # 检查Python文件是否存在 if not python_file.exists(): print(f"错误: Python文件不存在 {python_file}") continue + # 创建输出目录 + dist_path.mkdir(parents=True, exist_ok=True) + # 安装依赖 if requirements: print(f"安装依赖: {', '.join(requirements)}") subprocess.run([sys.executable, '-m', 'pip', 'install'] + requirements, check=True) - # 构建PyInstaller命令 + # 构建Nuitka命令 cmd = [ sys.executable, '-m', 'nuitka', - f'--output-filename={output_name}.exe', - f'--output-dir={dist_path}', # 输出目录 - '--onefile', # 单文件 + f'--output-filename={output_name}', + f'--output-dir={dist_path}', # 输出目录 + '--onefile', # 单文件 '--standalone', - '--mingw64', - # '--mode', - '--assume-yes-for-downloads', #自动下载外部代码 - # '--show-memory' - + f'--jobs={os.cpu_count()}', # 多线程 + '--assume-yes-for-downloads', # 自动下载外部代码 ] - # 添加窗口模式选项 - if windows_disable_console: - cmd.append('--windows-disable-console') - - # 添加图标选项 - if icon: - icon_path = base_dir / icon - if icon_path.exists(): - cmd.append(f'--windows-icon-from-ico={str(icon_path)}') - else: - print(f"警告: 图标文件不存在 {icon_path}") - - - if arrch == "ARM64": - print("UPX不支持当前架构") + # Windows特定参数 + if system_os == 'Windows': + cmd.append('--mingw64') + if windows_disable_console: + cmd.append('--windows-disable-console') + + if icon: + icon_path = base_dir / normalize_path(icon) + if icon_path.exists(): + cmd.append(f'--windows-icon-from-ico={icon_path}') + else: + print(f"警告: 图标文件不存在 {icon_path}") + if only_windows_command: + if isinstance(only_windows_command, str): + cmd.extend(only_windows_command.split()) + elif isinstance(only_windows_command, list): + cmd.extend(only_windows_command) + elif system_os == 'Linux': + if only_linux_command: + if isinstance(only_linux_command, str): + cmd.extend(only_linux_command.split()) + elif isinstance(only_linux_command, list): + cmd.extend(only_linux_command) + cmd.append('--clang') else: - if use_upx: - if upx_dir.exists(): - cmd.append('--plugin-enable=upx') - cmd.append(f'--upx-binary={str(upx_dir)}') - print(f"使用UPX压缩: {upx_dir}") + # Linux/macOS 使用 clang + cmd.append('--clang') + + # 启用插件 + if enable_plugins: + plugin_list = ','.join(enable_plugins) + cmd.append(f'--plugin-enable={plugin_list}') + + # UPX处理 + if 'upx' in enable_plugins: + upx_exe = 'upx.exe' if system_os == 'Windows' else 'upx' + upx_path = upx_dir / upx_exe + + if upx_path.exists(): + cmd.append(f'--upx-binary={upx_path}') + print(f"使用UPX压缩: {upx_path}") else: - print(f"警告: UPX目录不存在 {upx_dir}") - else: - print("不使用UPX压缩") + print(f"警告: UPX可执行文件不存在 {upx_path}") + + # 添加自定义命令 + if custom_command: + if isinstance(custom_command, str): + cmd.extend(custom_command.split()) + elif isinstance(custom_command, list): + cmd.extend(custom_command) - # 添加主Python文件 - t_file = str(uuid.uuid4()) + ".py" - t_file_path = base_dir / t_file - shutil.copy(str(python_file), t_file_path) - cmd.append(str(t_file_path)) + # 创建临时文件避免中文路径问题 + temp_file = base_dir / f"{uuid.uuid4().hex}.py" + shutil.copy(python_file, temp_file) + cmd.append(str(temp_file)) # 打印并执行命令 print("执行命令:", ' '.join(cmd)) - if timeout: - try: - result = subprocess.run(cmd,timeout=timeout) - except subprocess.TimeoutExpired: - print(f"任务[{i}/{len(config)} {task['name']}] 执行超时 {timeout} 秒") - print(f"任务[{i}/{len(config)} {task['name']}]失败: {e}") - task_error_list.append(task['name']) - continue - else: - result = subprocess.run(cmd) - if result.returncode == 0: + try: + # 执行打包命令 + result = subprocess.run( + cmd, + timeout=timeout, + check=True + ) + print(f"打包成功: {dist_path / output_name}") success_count += 1 - else: - print(f"打包失败,退出码: {result.returncode}") + + except subprocess.TimeoutExpired: + print(f"任务[{i}/{len(config)} {task['name']}] 执行超时 {timeout} 秒") + task_error_list.append(task['name']) + except subprocess.CalledProcessError as e: + print(f"打包失败,退出码: {e.returncode}") + print(f"错误输出: {e.stderr}") + task_error_list.append(task['name']) + finally: + # 确保临时文件被删除 + if temp_file.exists(): + temp_file.unlink() + except Exception as e: - print(f"任务[{i}/{len(config)} {task['name']}]失败: {e}") + print(f"任务[{i}/{len(config)} {task['name']}]失败: {str(e)}") + import traceback + traceback.print_exc() task_error_list.append(task['name']) - continue + + # 输出最终结果 + print("\n" + "="*50) + print(f"打包完成: 成功 {success_count} 个, 失败 {len(task_error_list)} 个") + if success_count != 0: - print(f"打包完成,成功打包 [{success_count}/{len(config)}] 个任务") - if task_error_list != []: - print(f"打包失败的任务: {', '.join(task_error_list)}") - else: - print("打包失败,没有成功打包任何任务") + files_list = [] + + # 遍历目录下的所有条目 + for entry in os.listdir(str(base_dir / 'dist')): + # 拼接完整的文件路径 + full_path = os.path.join(str(base_dir / 'dist'), entry) + # 检查该路径是否为文件 + if os.path.isfile(full_path): + files_list.append(entry) + + # 输出文件列表 + print(f'Dist: {str(files_list)}') + # 清理文件夹 + if delete_folders(dist_path): + print(f"已清理dist目录下文件夹: {dist_path}") + + if task_error_list: print(f"失败的任务: {', '.join(task_error_list)}") sys.exit(1) if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/package/nuitka_config.yml b/package/nuitka_config.yml index d900093..b27c113 100644 --- a/package/nuitka_config.yml +++ b/package/nuitka_config.yml @@ -1,6 +1,6 @@ - name: 'novel_crawler' version: 'v.25.07.08' - python-file: 'novel_crawler\novel_crawler_v.25.07.08.py' + python-file: 'novel_crawler/novel_crawler_v.25.07.08.py' install-requirements: [ 'beautifulsoup4', 'requests', @@ -8,73 +8,98 @@ 'rich', 'Pillow' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 2 # 0:文件夹 1:单文件 2:两者 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'Keyboard_monitoring' version: 'v.24.07.16' - python-file: '键盘监听\v.24.07.16.py' + python-file: '键盘监听/v.24.07.16.py' install-requirements: [ 'keyboard', 'configparser', 'pywin32', 'psutil' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'NetEase_Cloud_Music_Download' version: 'v.25-07-08' - python-file: '网易云音乐歌单批量下载歌曲\v.25-07-08.py' + python-file: '网易云音乐歌单批量下载歌曲/v.25-07-08.py' install-requirements: [ 'quote', 'requests', 'tabulate', 'mutagen' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'ftp_server' version: 'v.25-05-02' - python-file: 'ftp_server\ftp_server_v.25-05-02.py' + python-file: 'ftp_server/ftp_server_v.25-05-02.py' install-requirements: [ 'pyftpdlib' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] - name: 'sunrise_sunset_info' version: 'v.25.05.02' - python-file: 'sunrise_sunset_info\sunrise_sunset_info_v.25.05.02.py' + python-file: 'sunrise_sunset_info/sunrise_sunset_info_v.25.05.02.py' install-requirements: [ 'pyftpdlib', 'astropy' ] - upx: true + enable-plugins: [ + 'upx' + ] # onefile: 1 # 0:文件夹 1:单文件 2:两者 - icon: package\assets\favicon.ico + icon: package/assets/favicon.ico windows-disable-console: False distpath: 'dist' timeout: 2700 output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: [] diff --git a/package/nuitka_test_config.yml b/package/nuitka_test_config.yml new file mode 100644 index 0000000..1860375 --- /dev/null +++ b/package/nuitka_test_config.yml @@ -0,0 +1,18 @@ +- name: 'hello_world' + version: 'v.25.07.08' + python-file: 'package/hello_world.py' + install-requirements: [ + 'psutil' + ] + enable-plugins: [ + 'upx' + ] + # onefile: 2 # 0:文件夹 1:单文件 2:两者 + icon: package/assets/favicon.ico + windows-disable-console: False + distpath: 'dist' + timeout: 2700 + output-name-template: '{{name}}_{{version}}_nuitka_{{os}}_{{arch}}' + custom-command: [] + only-linux-command: [] + only-windows-command: []