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: []