diff --git a/.github/workflows/site-adapter-collector.yml b/.github/workflows/site-adapter-collector.yml index 30403f8dd..2f3930faa 100644 --- a/.github/workflows/site-adapter-collector.yml +++ b/.github/workflows/site-adapter-collector.yml @@ -39,10 +39,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' cache: pip @@ -94,14 +94,14 @@ jobs: python -c "import hashlib, os; from pathlib import Path; path = Path('dist') / os.environ['ASSET_NAME']; path.with_name(path.name + '.sha256').write_text(f'{hashlib.sha256(path.read_bytes()).hexdigest()} {path.name}\n', encoding='utf-8')" - name: Upload collector artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.artifact_name }} path: | dist/${{ matrix.asset_name }} dist/${{ matrix.asset_name }}.sha256 if-no-files-found: error - retention-days: 14 + retention-days: 3 publish: name: Upload collectors to release @@ -114,7 +114,7 @@ jobs: steps: - name: Download collector artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: pattern: site-adapter-collector-* path: release-assets diff --git a/scripts/site_adapter_collector.py b/scripts/site_adapter_collector.py index aee03a0cc..fe02d0d67 100644 --- a/scripts/site_adapter_collector.py +++ b/scripts/site_adapter_collector.py @@ -1409,8 +1409,21 @@ def _parse_args() -> argparse.Namespace: return parser.parse_args() +def _configure_standard_streams() -> None: + """将可重配置的标准输出流统一为 UTF-8,避免 Windows 本地代码页无法输出中文。""" + for stream in (sys.stdout, sys.stderr): + reconfigure = getattr(stream, "reconfigure", None) + if not callable(reconfigure): + continue + try: + reconfigure(encoding="utf-8", errors="replace") + except (LookupError, OSError): + continue + + def main() -> int: """交互式读取采集参数并生成站点适配 ZIP。""" + _configure_standard_streams() args = _parse_args() print("MoviePilot 站点适配采集器") print("原始页面不会落盘;临时浏览器关闭后会清理登录状态,输出前会裁剪并脱敏。") diff --git a/tests/test_site_adapter_collector.py b/tests/test_site_adapter_collector.py index 3144bfad6..9891df175 100644 --- a/tests/test_site_adapter_collector.py +++ b/tests/test_site_adapter_collector.py @@ -1,5 +1,8 @@ import hashlib import json +import os +import subprocess +import sys import zipfile from contextlib import contextmanager from pathlib import Path @@ -467,3 +470,20 @@ def test_browser_capture_builds_archive_without_manual_cookie_input(monkeypatch, assert manifest["collector_version"] == "1.0.1" assert request["params"]["search"] == "{keyword}" assert b"very-secret-cookie-value" not in combined + + +def test_help_uses_utf8_when_parent_forces_legacy_code_page() -> None: + """父进程强制 cp1252 时,中文 argparse 帮助仍应以 UTF-8 正常输出。""" + environment = os.environ.copy() + environment["PYTHONIOENCODING"] = "cp1252" + + result = subprocess.run( + [sys.executable, str(Path(collector.__file__)), "--help"], + check=False, + capture_output=True, + env=environment, + timeout=30, + ) + + assert result.returncode == 0, result.stderr.decode("utf-8", errors="replace") + assert "站点适配" in result.stdout.decode("utf-8")