Skill: tangqi00987/quark-subtitle-rescue (version 0.1.1)

--- name: quark-subtitle-rescue description: Bulk add subtitles to Quark movie folders with high success and low wrong-match risk. Best for "all subfolders" jobs, interrupted runs, and retrying failed titles with multi-source fallback (OpenSubtitles/SubHD/YIFY), strict matching, rollback safety, and completion reporting. --- # Quark Subtitle Rescue High-success, low-risk workflow for Quark 网盘字幕批处理。 ## What this skill solves - One-click style recovery for: “给电影文件夹所有子目录补字幕” - Resume from partial progress after interruptions/429/timeout - Reduce bad matches via strict retries and staged fallback - Keep an auditable trail: progress, failures, and final completion report ## Use this skill when - User asks for **batch subtitles across many Quark subfolders** - Previous run is partially done and needs **rescue/retry** - Need to switch subtitle providers for better hit rate - Need safe rollback/checks after suspected wrong matches ## Don’t use this skill when - User only needs subtitle for a **single local file** - There is no valid Quark login/cookie context ## Quick Start 1. Confirm tool root exists: `quark_subtitle_tool/`. 2. Ensure config exists: `~/.config/quark_subtitle.json` with valid `cookie`. 3. Activate venv: `source quark_subtitle_tool/venv/bin/activate`. 4. Run staged workflow (below), do not jump directly to aggressive retries. ### Minimal inputs expected - Quark target path (example: `全部文件/来自：分享/电影`) - Subtitle preference (default: bilingual zh+en) - Whether to allow Chinese-only fallback when bilingual is unavailable ## Staged Workflow ### Stage 1 — Baseline batch run Run: ```bash python quark_subtitle_tool/batch_subtitle_runner.py ``` Check output: - `quark_subtitle_tool/quark_work/batch_progress.json` - `quark_subtitle_tool/quark_work/batch_failures.jsonl` ### Stage 2 — Strict retry on failures Run strict retry (avoid broad fuzzy terms like director names): ```bash python quark_subtitle_tool/strict_top10_retry.py python quark_subtitle_tool/strict_remaining_retry.py ``` Rule: prioritize `title + year`; avoid generic query terms. ### Stage 3 — Folder-specific rescue If one folder remains stubborn, run dedicated script for that folder with filename-derived queries (example scripts in `quark_subtitle_tool/*_retry.py`). ### Stage 4 — Final two/small-tail manual precision For 1–5 leftovers, use explicit aliases (English original title + year), then run a targeted retry script. ## Provider Order and Matching Policy Default order: 1. OpenSubtitles 2. SubHD (射手系) 3. YIFY 4. Legacy providers (podnapisi/subtis/tvsubtitles) Policy: - If provider N hits, stop and do not query lower-priority providers. - **Default success target: bilingual (zh+en)**. If bilingual is unavailable, fall back to Chinese-only only when user allows it. - Treat “search page hit” and “download hit” separately; only download hit counts as success. ## Safety Guardrails (Mandatory) 1. Never use broad person-name queries (e.g., director name) for batch upload. 2. If many files suddenly “succeed” with same query, run hash-based spot check before declaring success. 3. If wrong-match batch is found, rollback before continuing. 4. Produce a clear report: total / success / failed / pending folders. Use helper: ```bash python skills/quark-subtitle-rescue/scripts/report_progress.py ``` ## Troubleshooting Read `references/troubleshooting.md` when you see: - OpenSubtitlesCom Bad Request - dogpile RegionNotConfigured - 429 rate limits - folder enter failures due to special chars - delete/rollback auth failures ## Resources - `scripts/report_progress.py`: summarize completion from generated JSON reports. - `references/workflow.md`: reusable decision flow for batch rescue. - `references/troubleshooting.md`: common failures and mitigations.

path: references/troubleshooting.md
content: # Troubleshooting

## OpenSubtitlesComError: Bad Request
- Symptom: list/search intermittently fails.
- Action: retry with lower frequency; keep OpenSubtitles fallback enabled.

## dogpile.cache.exception.RegionNotConfigured
- Symptom: download stage fails after listing many candidates.
- Action: treat as provider instability; continue fallback chain.

## HTTP 429 / rate limit
- Symptom: provider returns 429 or timeouts.
- Action: add wait between files, reduce concurrency, process in smaller batches.

## Folder enter failure (special chars)
- Symptom: cannot open folder by name.
- Action: use `fid`-based enter instead of name-only navigation.

## Rollback delete returns 401 guest
- Symptom: file delete API denied.
- Action: manual web delete or authenticated headed session.

## Preventing false success
- Symptom: many files marked ok but subtitle content identical.
- Action: hash check + content spot check; rollback bad batch.


path: references/workflow.md
content: # Workflow Reference

## Decision flow

1. Run baseline batch.
2. If success rate >= 70%, run strict remaining retry.
3. If one folder dominates failures, switch to folder-specific script.
4. If mismatch risk appears, pause and validate before uploads.
5. For final long-tail files, run explicit alias queries.

## Success criteria

- Batch-level: successful upload exists for target files.
- Quality-level: spot checks do not show repeated wrong subtitle content.
- Delivery-level: report lists completed and pending folders.

## Recommended cadence

- Large sets: process in batches and add small waits to reduce 429.
- Long-tail: 5–10 files per manual precision pass.


path: scripts/report_progress.py
content: #!/usr/bin/env python3
import json
from pathlib import Path

# Optional env override: QUARK_WORK_DIR=/path/to/quark_subtitle_tool/quark_work
ROOT = Path(__import__('os').environ.get('QUARK_WORK_DIR', 'quark_subtitle_tool/quark_work')).expanduser().resolve()


def load(p):
    return json.loads(p.read_text(encoding='utf-8')) if p.exists() else {}


def main():
    prog = load(ROOT / 'batch_progress.json')
    strict10 = load(ROOT / 'strict_top10_report.json')
    remain = load(ROOT / 'strict_remaining_report.json')
    final2 = load(ROOT / 'final_two_report.json')

    folders = prog.get('folders', {})
    total_videos = 0
    base_ok = 0
    base_fail = 0
    for _, fd in folders.items():
        vids = fd.get('videos', {})
        total_videos += len(vids)
        base_ok += sum(1 for v in vids.values() if v.get('status') == 'ok')
        base_fail += sum(1 for v in vids.values() if v.get('status') == 'fail')

    extra_ok = 0
    extra_ok += strict10.get('ok', 0) if isinstance(strict10.get('ok', 0), int) else 0
    extra_ok += remain.get('ok', 0) if isinstance(remain.get('ok', 0), int) else 0
    extra_ok += final2.get('ok', 0) if isinstance(final2.get('ok', 0), int) else 0

    print('=== Quark Subtitle Rescue Summary ===')
    print(f'Base: ok={base_ok}, fail={base_fail}, total={total_videos}')
    print(f'Extra recovered (strict/final): {extra_ok}')
    print(f'Approx final ok: {base_ok + extra_ok}')


if __name__ == '__main__':
    main()


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)