diff --git a/.github/workflows/build-nuitka.yml b/.github/workflows/build-nuitka.yml new file mode 100644 index 0000000..2021246 --- /dev/null +++ b/.github/workflows/build-nuitka.yml @@ -0,0 +1,179 @@ +name: Build with Nuitka + +on: + push: + tags: + - 'v*' + branches: + - main + - master + - dev + paths: + - 'linux_do_gui.py' + - 'requirements.txt' + - 'icon.ico' + - 'docs/**' + pull_request: + paths: + - 'linux_do_gui.py' + - 'requirements.txt' + workflow_dispatch: + inputs: + version: + description: 'Version tag for release (e.g., v8.1.0)' + required: false + default: '' + +env: + APP_NAME: LinuxDoHelper + PYTHON_VERSION: '3.11' + +jobs: + build: + name: Build on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-24.04 + artifact_name: LinuxDoHelper-nuitka-linux-amd64 + - os: ubuntu-24.04-arm + artifact_name: LinuxDoHelper-nuitka-linux-arm64 + - os: macos-15 + artifact_name: LinuxDoHelper-nuitka-macos-arm64.app.zip + app_dir_name: LinuxDoHelper-nuitka-macos-arm64.app + - os: windows-2025 + artifact_name: LinuxDoHelper-nuitka-windows-amd64.exe + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install nuitka ordered-set zstandard + + - name: Install C compiler (Ubuntu) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y build-essential patchelf + + - name: Install C compiler (macOS) + if: runner.os == 'macOS' + run: | + xcode-select --install || true + + - name: Build with Nuitka (macOS) + if: runner.os == 'macOS' + run: | + python -m nuitka \ + --mode=app \ + --assume-yes-for-downloads \ + --enable-plugin=tk-inter \ + --include-package=DrissionPage \ + --include-package=pystray \ + --include-package=PIL \ + --include-data-file=icon.ico=icon.ico \ + --output-filename=${{ env.APP_NAME }} \ + --output-dir=dist \ + linux_do_gui.py + + - name: Build with Nuitka (Linux) + if: runner.os == 'Linux' + run: | + python -m nuitka \ + --onefile \ + --standalone \ + --assume-yes-for-downloads \ + --enable-plugin=tk-inter \ + --include-package=DrissionPage \ + --include-package=pystray \ + --include-package=PIL \ + --include-data-file=icon.ico=icon.ico \ + --output-filename=${{ env.APP_NAME }} \ + --output-dir=dist \ + linux_do_gui.py + + - name: Build with Nuitka (Windows) + if: runner.os == 'Windows' + run: | + python -m nuitka --onefile --standalone --assume-yes-for-downloads --enable-plugin=tk-inter --include-package=DrissionPage --include-package=pystray --include-package=PIL --include-data-file=icon.ico=icon.ico --output-filename=${{ env.APP_NAME }} --output-dir=dist linux_do_gui.py + + - name: Rename artifact (macOS) + if: runner.os == 'macOS' + run: | + mv dist/${{ env.APP_NAME }}.app dist/${{ matrix.app_dir_name }} + + - name: Zip macOS app + if: runner.os == 'macOS' + run: | + ditto -c -k --sequesterRsrc --keepParent dist/${{ matrix.app_dir_name }} dist/${{ matrix.artifact_name }} + + - name: Rename artifact (Linux) + if: runner.os == 'Linux' + run: | + mv dist/${{ env.APP_NAME }} dist/${{ matrix.artifact_name }} + + - name: Rename artifact (Windows) + if: runner.os == 'Windows' + run: | + move dist\${{ env.APP_NAME }}.exe dist\${{ matrix.artifact_name }} + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact_name }} + path: dist/${{ matrix.artifact_name }} + retention-days: 30 + + release: + name: Create Release + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + - name: Display artifacts + run: find artifacts/ -type f -o -type d + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: ${{ env.APP_NAME }} ${{ github.ref_name }} (Nuitka) + body: | + ## ${{ env.APP_NAME }} ${{ github.ref_name }} (Nuitka Build) + + ### Downloads + - **Linux (x64)**: `LinuxDoHelper-nuitka-linux-amd64` + - **Linux (ARM64)**: `LinuxDoHelper-nuitka-linux-arm64` + - **macOS (Apple Silicon)**: `LinuxDoHelper-nuitka-macos-arm64.app.zip` + - **Windows (x64)**: `LinuxDoHelper-nuitka-windows-amd64.exe` + + ### Build Info + - Builder: Nuitka (compiled to native code) + - Python: ${{ env.PYTHON_VERSION }} + + ### Note + macOS builds use `--mode=app` to support GUI frameworks (Foundation/Tkinter). + files: | + artifacts/**/* + generate_release_notes: true + draft: false + prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-pyinstaller.yml b/.github/workflows/build-pyinstaller.yml new file mode 100644 index 0000000..2ea94a9 --- /dev/null +++ b/.github/workflows/build-pyinstaller.yml @@ -0,0 +1,158 @@ +name: Build with PyInstaller + +on: + push: + tags: + - 'v*' + branches: + - main + - master + - dev + pull_request: + workflow_dispatch: + +env: + APP_NAME: LinuxDoHelper + PYTHON_VERSION: '3.11' + +jobs: + build: + name: Build on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-24.04 + platform: linux-amd64 + ext: '' + - os: ubuntu-24.04-arm + platform: linux-arm64 + ext: '' + - os: macos-15 + platform: macos-arm64 + ext: '' + - os: windows-2025 + platform: windows-amd64 + ext: '.exe' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + + - name: Resolve version + id: version + shell: bash + run: | + if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then + VERSION="${GITHUB_REF_NAME}" + else + VERSION="dev-${GITHUB_SHA::7}" + fi + echo "VERSION=${VERSION}" >> "$GITHUB_ENV" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + + - name: Install system deps (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y tk tcl libgtk-3-0 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pyinstaller + + - name: Build with PyInstaller (Unix) + if: runner.os != 'Windows' + run: | + pyinstaller --onefile --windowed --clean --noconfirm \ + --name "${APP_NAME}" \ + --hidden-import tkinter \ + --hidden-import tkinter.ttk \ + --hidden-import tkinter.scrolledtext \ + --hidden-import DrissionPage \ + --hidden-import pystray \ + --hidden-import PIL \ + --add-data "icon.ico:." \ + linux_do_gui.py + + - name: Build with PyInstaller (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + pyinstaller --onefile --windowed --clean --noconfirm ` + --name "${env:APP_NAME}" ` + --hidden-import tkinter ` + --hidden-import tkinter.ttk ` + --hidden-import tkinter.scrolledtext ` + --hidden-import DrissionPage ` + --hidden-import pystray ` + --hidden-import PIL ` + --add-data "icon.ico;." ` + --icon icon.ico ` + linux_do_gui.py + + - name: Rename artifact (Unix) + if: runner.os != 'Windows' + run: | + mv "dist/${APP_NAME}" "dist/${APP_NAME}-pyinstaller-${{ steps.version.outputs.version }}-${{ matrix.platform }}" + + - name: Rename artifact (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + Move-Item "dist\\${env:APP_NAME}.exe" "dist\\${env:APP_NAME}-pyinstaller-${{ steps.version.outputs.version }}-${{ matrix.platform }}${{ matrix.ext }}" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.APP_NAME }}-pyinstaller-${{ steps.version.outputs.version }}-${{ matrix.platform }}${{ matrix.ext }} + path: dist/${{ env.APP_NAME }}-pyinstaller-${{ steps.version.outputs.version }}-${{ matrix.platform }}${{ matrix.ext }} + retention-days: 30 + + release: + name: Create Release (PyInstaller) + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + - name: Display artifacts + run: find artifacts/ -type f + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: ${{ env.APP_NAME }} ${{ github.ref_name }} (PyInstaller) + body: | + ## ${{ env.APP_NAME }} ${{ github.ref_name }} (PyInstaller Build) + + ### Downloads + - Linux (x64): `${{ env.APP_NAME }}-pyinstaller-${{ github.ref_name }}-linux-amd64` + - Linux (ARM64): `${{ env.APP_NAME }}-pyinstaller-${{ github.ref_name }}-linux-arm64` + - macOS (Apple Silicon): `${{ env.APP_NAME }}-pyinstaller-${{ github.ref_name }}-macos-arm64` + - Windows (x64): `${{ env.APP_NAME }}-pyinstaller-${{ github.ref_name }}-windows-amd64.exe` + + ### Build Info + - Builder: PyInstaller + - Python: ${{ env.PYTHON_VERSION }} + files: | + artifacts/** + generate_release_notes: true + draft: false + prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index c29c432..efa27f2 100644 --- a/.gitignore +++ b/.gitignore @@ -26,12 +26,14 @@ wheels/ *.log # Local files -*.json -*.txt -*.html -*.png -*.pyw -nul +*.json +*.txt +*.html +*.png +*.pyw +nul +!requirements.txt +!requirements-*.txt # IDE .idea/ @@ -54,3 +56,4 @@ LDStatusPro/ # Dist folder (exe files are too large for git) dist/ +.DS_Store diff --git a/README.md b/README.md index ba623d0..ff31262 100644 --- a/README.md +++ b/README.md @@ -86,11 +86,11 @@ - Python 3.8+ - Chrome 浏览器 -#### 安装依赖 - -```bash -pip install DrissionPage pystray pillow -``` +#### 安装依赖 + +```bash +pip install -r requirements.txt +``` #### 运行程序 @@ -165,7 +165,7 @@ python linux_do_gui.py ## 更新日志 -### v8.1 (2025-01-14) +### v8.1 (2026-01-14) - 新增系统托盘功能,支持最小化到托盘 - 新增托盘图标状态显示(就绪/运行中/已完成) - 新增托盘悬停提示,显示实时统计信息 @@ -195,33 +195,40 @@ python linux_do_gui.py 由于 PyInstaller 不支持跨平台打包(Windows 上无法打包 macOS/Linux 版本),我创建了: - 1. build.py - 通用打包脚本,在对应系统上运行即可自动打包 - 2. BUILD_GUIDE.md - 详细的打包指南,包含: - - macOS 打包步骤 - - Linux 打包步骤 - - 环境准备命令 - - 常见问题解决 - -### 在 macOS 上打包 - - pip3 install DrissionPage pyinstaller - python3 build.py - -### 在 Linux 上打包 - - pip3 install DrissionPage pyinstaller - python3 build.py - -### 项目文件结构 - -linuxdo/ -├── linux_do_gui.py # 主程序 - -├── build.py # 打包脚本 - -├── README.md # 项目说明 - -└── BUILD_GUIDE.md # 打包指南 + 1. build.py - 通用打包脚本,在对应系统上运行即可自动打包 + 2. docs/BUILD_GUIDE.md - 详细的打包指南,包含: + - macOS 打包步骤 + - Linux 打包步骤 + - 环境准备命令 + - 常见问题解决 + 3. docs/Linux 环境安装指南.md - Linux 环境安装说明 + +### 在 macOS 上打包 + + pip3 install -r requirements.txt + pip3 install pyinstaller + python3 build.py + +### 在 Linux 上打包 + + pip3 install -r requirements.txt + pip3 install pyinstaller + python3 build.py + +### 项目文件结构 + +linuxdo/ +├── linux_do_gui.py # 主程序 + +├── build.py # 打包脚本 + +├── README.md # 项目说明 + +├── requirements.txt # 依赖列表 + +└── docs/ + ├── BUILD_GUIDE.md # 打包指南 + └── Linux 环境安装指南.md # Linux 环境安装指南 ## 技术栈 diff --git a/build.py b/build.py index 24d1946..a29c268 100644 --- a/build.py +++ b/build.py @@ -42,27 +42,33 @@ def clean_build(): os.remove(f) print(f"已清理: {f}") -def build_windows(): +def build_windows(): """打包 Windows exe""" print("\n" + "=" * 50) print("开始打包 Windows 版本...") print("=" * 50) - cmd = [ - "pyinstaller", - "--onefile", - "--windowed", - "--name", f"{APP_NAME}_v{APP_VERSION}_Windows", - "--add-data", f"{MAIN_SCRIPT};.", - "--hidden-import", "tkinter", - "--hidden-import", "tkinter.ttk", - "--hidden-import", "tkinter.scrolledtext", - "--hidden-import", "DrissionPage", - "--clean", - "--noconfirm", - MAIN_SCRIPT - ] - + cmd = [ + "pyinstaller", + "--onefile", + "--windowed", + "--name", f"{APP_NAME}_v{APP_VERSION}_Windows", + "--add-data", f"{MAIN_SCRIPT};.", + "--hidden-import", "tkinter", + "--hidden-import", "tkinter.ttk", + "--hidden-import", "tkinter.scrolledtext", + "--hidden-import", "DrissionPage", + "--hidden-import", "pystray", + "--hidden-import", "PIL", + "--clean", + "--noconfirm", + MAIN_SCRIPT + ] + + # 打包图标数据,供运行时托盘与窗口图标使用 + if os.path.exists(ICON_WIN): + cmd.extend(["--add-data", f"{ICON_WIN};."]) + # 如果有图标文件 if os.path.exists(ICON_WIN): cmd.extend(["--icon", ICON_WIN]) @@ -76,26 +82,32 @@ def build_windows(): print(f"打包失败: {e}") return False -def build_macos(): +def build_macos(): """打包 macOS app""" print("\n" + "=" * 50) print("开始打包 macOS 版本...") print("=" * 50) - cmd = [ - "pyinstaller", - "--onefile", - "--windowed", - "--name", f"{APP_NAME}_v{APP_VERSION}_macOS", - "--hidden-import", "tkinter", - "--hidden-import", "tkinter.ttk", - "--hidden-import", "tkinter.scrolledtext", - "--hidden-import", "DrissionPage", - "--clean", - "--noconfirm", - MAIN_SCRIPT - ] - + cmd = [ + "pyinstaller", + "--onefile", + "--windowed", + "--name", f"{APP_NAME}_v{APP_VERSION}_macOS", + "--hidden-import", "tkinter", + "--hidden-import", "tkinter.ttk", + "--hidden-import", "tkinter.scrolledtext", + "--hidden-import", "DrissionPage", + "--hidden-import", "pystray", + "--hidden-import", "PIL", + "--clean", + "--noconfirm", + MAIN_SCRIPT + ] + + # 打包图标数据,供运行时托盘与窗口图标使用 + if os.path.exists(ICON_WIN): + cmd.extend(["--add-data", f"{ICON_WIN}:."]) + # 如果有图标文件 if os.path.exists(ICON_MAC): cmd.extend(["--icon", ICON_MAC]) @@ -109,26 +121,32 @@ def build_macos(): print(f"打包失败: {e}") return False -def build_linux(): +def build_linux(): """打包 Linux 版本""" print("\n" + "=" * 50) print("开始打包 Linux 版本...") print("=" * 50) - cmd = [ - "pyinstaller", - "--onefile", - "--windowed", - "--name", f"{APP_NAME}_v{APP_VERSION}_Linux", - "--hidden-import", "tkinter", - "--hidden-import", "tkinter.ttk", - "--hidden-import", "tkinter.scrolledtext", - "--hidden-import", "DrissionPage", - "--clean", - "--noconfirm", - MAIN_SCRIPT - ] - + cmd = [ + "pyinstaller", + "--onefile", + "--windowed", + "--name", f"{APP_NAME}_v{APP_VERSION}_Linux", + "--hidden-import", "tkinter", + "--hidden-import", "tkinter.ttk", + "--hidden-import", "tkinter.scrolledtext", + "--hidden-import", "DrissionPage", + "--hidden-import", "pystray", + "--hidden-import", "PIL", + "--clean", + "--noconfirm", + MAIN_SCRIPT + ] + + # 打包图标数据,供运行时托盘与窗口图标使用 + if os.path.exists(ICON_WIN): + cmd.extend(["--add-data", f"{ICON_WIN}:."]) + try: subprocess.run(cmd, check=True) print(f"\nLinux 版本打包成功!") diff --git a/BUILD_GUIDE.md b/docs/BUILD_GUIDE.md similarity index 57% rename from BUILD_GUIDE.md rename to docs/BUILD_GUIDE.md index a0d4c38..837bed5 100644 --- a/BUILD_GUIDE.md +++ b/docs/BUILD_GUIDE.md @@ -1,11 +1,12 @@ # Linux.do 刷帖助手 - 多平台打包指南 -## Windows 版本 - -Windows exe 已打包完成,位于 `dist/LinuxDoHelper_v8.0_Windows.exe` - -### 直接运行 -双击 `LinuxDoHelper_v8.0_Windows.exe` 即可运行 +## Windows 版本 + +Windows 可执行文件请优先从 GitHub Releases 或 Actions 构建产物获取,文件名示例: +- `LinuxDoHelper-pyinstaller--windows-amd64.exe` +- `LinuxDoHelper-nuitka-windows-amd64.exe` + +如需本地打包,请参考下文 PyInstaller/Nuitka 的命令并在 Windows 上执行。 --- @@ -17,8 +18,9 @@ Windows exe 已打包完成,位于 `dist/LinuxDoHelper_v8.0_Windows.exe` # 1. 安装 Python 3.8+ brew install python@3.11 -# 2. 安装依赖 -pip3 install DrissionPage pyinstaller +# 2. 安装依赖 +pip3 install -r requirements.txt +pip3 install pyinstaller # 3. 安装 Chrome 浏览器 # 从 https://www.google.com/chrome/ 下载安装 @@ -31,29 +33,32 @@ pip3 install DrissionPage pyinstaller cd /path/to/linuxdo # 执行打包 -pyinstaller --onefile --windowed \ - --name "LinuxDoHelper_v8.0_macOS" \ - --hidden-import tkinter \ - --hidden-import tkinter.ttk \ - --hidden-import tkinter.scrolledtext \ - --hidden-import DrissionPage \ - --clean --noconfirm \ - linux_do_gui.py +pyinstaller --onefile --windowed \ + --name "LinuxDoHelper_v_macOS" \ + --hidden-import tkinter \ + --hidden-import tkinter.ttk \ + --hidden-import tkinter.scrolledtext \ + --hidden-import DrissionPage \ + --hidden-import pystray \ + --hidden-import PIL \ + --add-data "icon.ico:." \ + --clean --noconfirm \ + linux_do_gui.py # 或者使用打包脚本 python3 build.py ``` -### 输出文件 -- `dist/LinuxDoHelper_v8.0_macOS` (可执行文件) +### 输出文件 +- `dist/LinuxDoHelper_v_macOS` (可执行文件) ### 运行方式 ```bash -# 赋予执行权限 -chmod +x dist/LinuxDoHelper_v8.0_macOS - -# 运行 -./dist/LinuxDoHelper_v8.0_macOS +# 赋予执行权限 +chmod +x dist/LinuxDoHelper_v_macOS + +# 运行 +./dist/LinuxDoHelper_v_macOS ``` ### macOS 安全提示 @@ -78,8 +83,9 @@ sudo yum install python3 python3-pip python3-tkinter # Arch Linux sudo pacman -S python python-pip tk -# 安装依赖 -pip3 install DrissionPage pyinstaller +# 安装依赖 +pip3 install -r requirements.txt +pip3 install pyinstaller # 安装 Chrome 浏览器 # Ubuntu/Debian @@ -95,29 +101,32 @@ sudo apt-get install -f cd /path/to/linuxdo # 执行打包 -pyinstaller --onefile --windowed \ - --name "LinuxDoHelper_v8.0_Linux" \ - --hidden-import tkinter \ - --hidden-import tkinter.ttk \ - --hidden-import tkinter.scrolledtext \ - --hidden-import DrissionPage \ - --clean --noconfirm \ - linux_do_gui.py +pyinstaller --onefile --windowed \ + --name "LinuxDoHelper_v_Linux" \ + --hidden-import tkinter \ + --hidden-import tkinter.ttk \ + --hidden-import tkinter.scrolledtext \ + --hidden-import DrissionPage \ + --hidden-import pystray \ + --hidden-import PIL \ + --add-data "icon.ico:." \ + --clean --noconfirm \ + linux_do_gui.py # 或者使用打包脚本 python3 build.py ``` -### 输出文件 -- `dist/LinuxDoHelper_v8.0_Linux` (可执行文件) +### 输出文件 +- `dist/LinuxDoHelper_v_Linux` (可执行文件) ### 运行方式 ```bash -# 赋予执行权限 -chmod +x dist/LinuxDoHelper_v8.0_Linux - -# 运行 -./dist/LinuxDoHelper_v8.0_Linux +# 赋予执行权限 +chmod +x dist/LinuxDoHelper_v_Linux + +# 运行 +./dist/LinuxDoHelper_v_Linux ``` ### Linux 注意事项 @@ -142,8 +151,8 @@ A: 检查是否安装了 Chrome 浏览器 #### Q: 提示找不到 chromedriver A: DrissionPage 会自动下载,确保网络通畅 -#### Q: macOS 提示"已损坏,无法打开" -A: 执行 `xattr -cr /path/to/LinuxDoHelper_v8.0_macOS` +#### Q: macOS 提示"已损坏,无法打开" +A: 执行 `xattr -cr /path/to/LinuxDoHelper_v_macOS` #### Q: Linux 提示 tkinter 相关错误 A: 安装 python3-tk 包 @@ -154,24 +163,46 @@ A: 安装 python3-tk 包 如果打包版本有问题,可以直接从源码运行: -```bash -# 安装依赖 -pip install DrissionPage - -# 运行 -python linux_do_gui.py -``` +```bash +# 安装依赖 +pip install -r requirements.txt + +# 运行 +python linux_do_gui.py +``` + +--- + +## GitHub Actions 自动打包(PyInstaller + Nuitka) + +仓库已提供 GitHub Actions 工作流,可在提交或打 Tag 时自动打包多平台可执行文件: + +- PyInstaller 工作流: `.github/workflows/build-pyinstaller.yml` +- Nuitka 工作流: `.github/workflows/build-nuitka.yml` + +### 使用方式 + +1. 创建并推送版本 Tag(示例): + ```bash + git tag v8.1.0 + git push origin v8.1.0 + ``` +2. GitHub Actions 将自动构建并上传对应平台的产物到 Release。 +3. 如需手动触发,可在 Actions 页面使用 `workflow_dispatch` 并填写 `version`。 --- ## 文件说明 ``` -linuxdo/ -├── linux_do_gui.py # 主程序 -├── build.py # 打包脚本 -├── README.md # 项目说明 -├── BUILD_GUIDE.md # 本文档 -└── dist/ - └── LinuxDoHelper_v8.0_Windows.exe # Windows 可执行文件 +linuxdo/ +├── linux_do_gui.py # 主程序 +├── build.py # 打包脚本 +├── README.md # 项目说明 +├── requirements.txt # 依赖列表 +├── docs/ +│ ├── BUILD_GUIDE.md # 本文档 +│ └── Linux 环境安装指南.md # Linux 环境安装指南 +└── dist/ + └── LinuxDoHelper_<...> # 构建产物示例 ``` diff --git "a/Linux \347\216\257\345\242\203\345\256\211\350\243\205\346\214\207\345\215\227.md" "b/docs/Linux \347\216\257\345\242\203\345\256\211\350\243\205\346\214\207\345\215\227.md" similarity index 94% rename from "Linux \347\216\257\345\242\203\345\256\211\350\243\205\346\214\207\345\215\227.md" rename to "docs/Linux \347\216\257\345\242\203\345\256\211\350\243\205\346\214\207\345\215\227.md" index 1f5a88c..2e2535e 100644 --- "a/Linux \347\216\257\345\242\203\345\256\211\350\243\205\346\214\207\345\215\227.md" +++ "b/docs/Linux \347\216\257\345\242\203\345\256\211\350\243\205\346\214\207\345\215\227.md" @@ -14,7 +14,7 @@ Linux 环境安装指南 2. 安装 Python 依赖 - pip3 install DrissionPage + pip3 install -r requirements.txt 3. 安装 Chrome 浏览器 @@ -41,7 +41,7 @@ Linux 环境安装指南 sudo apt install python3-tk Q: 提示 No module named 'DrissionPage' - pip3 install DrissionPage + pip3 install -r requirements.txt Q: 程序启动但浏览器打不开 确保安装了 Chrome 浏览器: diff --git a/linux_do_gui.py b/linux_do_gui.py index b24ed95..4365058 100644 --- a/linux_do_gui.py +++ b/linux_do_gui.py @@ -488,12 +488,13 @@ def do_reply(s, content=None): s._random_delay(1.5, 3, "等待编辑器") # 输入内容 - 使用安全的方式传递内容 + safe_content = json.dumps(content) s.pg.run_js(f""" (function() {{ const textarea = document.querySelector('#reply-control textarea, .d-editor-input'); if (textarea) {{ textarea.focus(); - textarea.value = '{content}'; + textarea.value = {safe_content}; textarea.dispatchEvent(new Event('input', {{bubbles: true}})); }} }})(); @@ -700,6 +701,7 @@ def __init__(s): s.tray_icon = None s.tray_thread = None s._running_status = "就绪" + s._stop_requested = False s._ui() @@ -1368,6 +1370,7 @@ def _start(s): # 重置初始数据 s.initial_requirements = [] + s._stop_requested = False s.bot = Bot(s.cfg, s.cats, s._lg, s._update_info, s._update_progress) s.th = threading.Thread(target=s._run, daemon=True) @@ -1382,17 +1385,24 @@ def _run(s): def _done(s): s.start_btn.config(state=tk.NORMAL) s.stop_btn.config(state=tk.DISABLED) - s.status.set("已完成") - - # 更新托盘状态 - if s.bot: - s._update_tray_status("已完成", s.bot.stats) + if s._stop_requested: + s.status.set("已停止") + if s.bot: + s._update_tray_status("已停止", s.bot.stats) + else: + s._update_tray_status("已停止") else: - s._update_tray_status("已完成") + s.status.set("已完成") + if s.bot: + s._update_tray_status("已完成", s.bot.stats) + else: + s._update_tray_status("已完成") + s._stop_requested = False def _stop(s): if s.bot: s.bot.stop() + s._stop_requested = True s.status.set("正在停止...") s._update_tray_status("已停止") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..385e989 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +DrissionPage +pystray +pillow