Back to Skills

Quark PanSou Collector

quark-pansou-collector

Search PanSou for Quark cloud-drive share candidates, apply deterministic policy filtering and link/title verification, then return one best Quark share link or, when explicitly requested, save the verified link into Quark drive with quarkpan.

SKILL.md

Quark PanSou Collector

When to Use

Use this skill when the user asks to search PanSou by keyword and return one best Quark share link. Also use it when the user asks to save, collect, archive, sync, or transfer that selected Quark share into Quark drive. The default save folder is /z-sync, and the user may request another Quark drive folder.

By default, this skill only returns one verified candidate link plus a compact verification summary. It saves to /z-sync only when the user explicitly asks to save/sync/collect/archive/transfer the result and does not name another destination folder. If the user says where to save, pass that folder with --save-folder. After a strong verified selected result is returned without --save, ask the user whether to save it; tell them to reply 1 to save to the shown folder. A reply of exactly 1 in that context is an explicit save request for the last selected result.

Before any strong verification or save operation, rely on the helper’s Quark environment check. It uses QUARK_CONFIG_DIR when already set; otherwise it defaults to ~/quarkpan-config on the current computer. It installs quarkpan with python3 -m pip install --user quarkpan if the CLI is missing, and checks the login state. When saving is requested and login is missing, the helper generates a QR code PNG in that config directory and waits for the user to scan it. In Codex chat, show that local PNG with Markdown image syntax so the user can scan it; interactive terminal QR output may be invisible to the user. In Telegram or other gateway chats that support native media, send the PNG as a native attachment using MEDIA:<qr_code_path> rather than only printing the local path. Prefer starting the login/check command as a tracked background process, record the start time, wait until qr_code_path exists with an mtime newer than that start time, send the image immediately, and then continue polling or ask the user to confirm after scanning; otherwise the short QR expiry window may pass before the user can see it. If a previous login attempt timed out, delete or ignore the stale quark-login-qr.png before sending a new QR; never send a QR file merely because it exists.

The agent is not the content adjudicator. It must run the deterministic policy filter first, then output only a candidate marked transferable. The agent may explain policy results and ask for missing inputs, but it must not override the policy gate or use subjective judgment to turn a blocked candidate into an output link. If the user explicitly requests account bypass, captcha bypass, or unlawful access, stop.

AI involvement is limited to: parsing the user’s keyword, reporting the selected link and explaining tool errors. Search filtering, URL handling, source allowlisting, risk labels, best-candidate selection, and link verification are programmatic.

Inputs

  • Required before searching: keyword.
  • Optional: PanSou endpoint, default https://s.panhunt.com.
  • Optional: source mode, default all; accepted PanSou values are all, tg, and plugin.
  • Optional: maximum candidates to show, default 10 and cap at 20 unless the user explicitly asks for more.
  • Optional: refresh, default false.
  • Optional: policy JSON path. Default to references/policy.default.json.
  • Optional: save selected link into /z-sync, default false and enabled only when the user explicitly asks to save/sync/collect/archive/transfer.
  • Optional: save folder, default /z-sync. If the user says “保存到 X” or otherwise names a destination folder, pass that Quark drive folder with --save-folder.
  • Optional: content choice, used only after the helper returns needs_user_selection: true. Pass the user’s selected option number with --content-choice <index> and rerun the same command.
  • Optional: Quark config directory. Defaults to existing QUARK_CONFIG_DIR, then ~/quarkpan-config on the current computer.
  • Optional: --check-quark-env for checking/installing quarkpan and login status without searching.

Execution

PanSou search is a public HTTP API call, not an oo package or connector. Prefer the bundled deterministic helper over ad hoc curl/jq, because it returns policy labels and redacts non-transferable URLs.

From the skill directory, run:

python3 scripts/pansou_collect.py \
  --keyword "<keyword>" \
  --endpoint "https://s.panhunt.com" \
  --src all \
  --limit 10 \
  --policy references/policy.default.json \
  --one \
  --verify-link

The helper automatically sets QUARK_CONFIG_DIR from --quark-config-dir, then any existing QUARK_CONFIG_DIR, then ~/quarkpan-config. To check the environment only, run:

python3 scripts/pansou_collect.py --check-quark-env --login-if-needed

If the JSON output contains event: quark_login_required with qr_code_path, display that PNG in the chat for scanning. After the user scans and confirms login in the Quark app, the helper continues until login succeeds or times out.

When the user explicitly asks to save/sync/collect/archive/transfer the selected result into Quark, add --save:

python3 scripts/pansou_collect.py \
  --keyword "<keyword>" \
  --endpoint "https://s.panhunt.com" \
  --src all \
  --limit 10 \
  --policy references/policy.default.json \
  --one \
  --verify-link \
  --save

The default save path is /z-sync. After selecting a transferable candidate with successful strong content verification, the helper resolves or creates the target Quark drive folder, obtains its real folder id, and saves the share with quark_client using that folder id. This avoids the ambiguous quarkpan save -f behavior where a missing destination folder can leave items in the root. If the user explicitly requests another Quark drive folder, pass it with --save-folder. Do not run quarkpan manually unless the helper is unavailable and you have already reproduced the same selection, verification, and target-folder rules.

If the user’s quarkpan login uses a different config directory, pass it explicitly:

python3 scripts/pansou_collect.py \
  --keyword "<keyword>" \
  --one \
  --verify-link \
  --quark-config-dir "/path/to/quarkpan/config"

The helper searches only Quark links, deduplicates by cleaned share URL, checks title relevance, applies source/pattern policy, and returns JSON candidates with status, risk, reasons, and link_verification. Link verification first tries the logged-in quark_client share-detail API; this can detect expired or unavailable shares and count files. If quarkpan is not logged in for the current working directory/config, it falls back to a weak HTTP page check and marks weak_verification: true.

In --one mode it returns only selected, using this rule: one transferable candidate with successful strong content verification after content disambiguation. Weak HTTP page checks are never enough for --one, because expired Quark shares may still return HTTP 200.

Before selecting one result, the helper groups transferable candidates by programmatic content variants. Seasons/parts,全集/合集/完整版 markers, explicit year versions such as 2008 版本 and 2016 版, and obvious same-title editions such as subtitles after are treated as different content variants. If more than one strongly verified variant exists, the helper returns needs_user_selection: true plus selection_options; do not output a link or save anything yet. Ask the user which option number they want, then rerun the same command with --content-choice <index>.

Do not ask the user when the remaining difference is only quality/encoding, for example 720p, 1080p, 4K, 2160p, 蓝光, WEB-DL, HDR, DV, or H.265. Within a single content variant, the helper automatically selects the highest-quality strongly verified candidate.

In --save mode it still uses the same --one selection rule before saving. If there is no strongly verified selected link, stop without saving.

If the helper is unavailable, this is the raw PanSou request shape:

curl -sS -X POST 'https://s.panhunt.com/api/search' \
  -H 'Content-Type: application/json' \
  --data '{"kw":"<keyword>","cloud_types":["quark"],"res":"merge","src":"all"}'

Use --data @payload.json instead of inline JSON when values contain quotes, newlines, or user-provided structured options. A minimal payload is:

{
  "kw": "<keyword>",
  "cloud_types": ["quark"],
  "res": "merge",
  "src": "all"
}

If the user asks to force a fresh lookup, add "refresh": true. For plugin-only or Telegram-only searches, set "src": "plugin" or "src": "tg".

When using the raw request, reproduce the helper’s policy behavior before showing anything to the user. Extract candidates from .data.merged_by_type.quark[]. Keep these fields: note as title, url, password, source, datetime, and images when present. Clean the list:

  • Keep only URLs matching https://pan.quark.cn/s/<id>.
  • Strip query strings and whitespace from share URLs.
  • Deduplicate by cleaned URL.
  • Remove obvious non-matches and empty titles.
  • Cap the displayed list to the requested maximum.
  • Mark candidates whose title does not contain the keyword as filtered.
  • Mark candidates matching configured blocked title patterns as blocked.
  • Redact URLs for every status except transferable.

Default policy lives at references/policy.default.json. A project or user may provide a stricter policy file with source allowlists or trusted internal endpoint hosts. The default public policy treats s.panhunt.com as a public endpoint. Public endpoint results become transferable only when they have no blocked/filter reasons and match at least one programmatic allow condition: trusted endpoint host, allowlisted source, or an allowed public-material title pattern such as government reports, white papers, manuals, open data, open source, public domain, or Creative Commons markers. Ordinary title matches from public endpoints are needs_authorization and their URLs stay redacted.

Return exactly one selected Quark URL when selected is present. Include the title, source, and verification summary. If --save was requested, also report the save result from save_result.

If selected is present and save_prompt.available is true, ask the user whether to save it after reporting the link. Use the prompt wording from save_prompt.message when present, for example: 回复 1 保存到 /z-sync. Do not save immediately unless the user has already asked to save/sync/collect/archive/ transfer, or unless the user’s next reply is exactly 1 in response to this save prompt. When the user replies 1, rerun the same search command with the same keyword, source, policy, and any previous --content-choice, adding --save and the same --save-folder if one was used.

If the helper returns needs_user_selection: true, report the numbered selection_options with their labels, representative titles, sources, and candidate counts, then ask the user to choose one number. Do not show any share URL until the user has selected an option and the rerun returns selected.

When strong verification sees an authentication failure such as not_logged_in, 认证失败, 访问被拒绝, HTTP 401, HTTP 403, or Cookie过期, the helper clears cookies.json, emits a fresh quark_login_required QR-code event, waits for the user to scan, and retries the same share verification once. In gateway chats, send the emitted qr_code_path image immediately with MEDIA:<path> and then continue after login completes; do not treat the first auth failure as a dead share until the retry also fails or the QR login times out.

Batch / Follow-up Handling

When the user provides multiple PanSou keywords in one message, process them as a batch but keep each keyword’s deterministic helper run independent. Use the same endpoint, source mode, policy, verification mode, and save folder unless the user gives per-item overrides. Summarize each item separately with one of these states: selected link, needs content selection, no selected candidate, or save result.

If a previous response reported several verified selected links and ended with save prompts, interpret a follow-up like 保存全部, 全部保存, or save all as an explicit request to save every previously reported selected item that had save_prompt.available: true. Rerun the helper once per item with the same keyword and any prior --content-choice, adding --save and the same --save-folder if one was used. Do not include keywords that had no selected result, were only selection prompts, or were explicitly declined.

If the user gives compact choices such as 海街日记 1 and 比海更深 1, treat the trailing number as that keyword’s --content-choice and rerun each selected keyword. If the same message also includes 保存 <keyword>, add --save for that item. When reporting batch saves, include destination folder, saved item names, and any partial failures; do not claim all succeeded unless every helper result has save_result.ok: true.

Result Handling

After the search step, report the one selected link:

  • title
  • URL
  • source
  • title match status
  • link verification status

Also report a short policy summary, for example: 1 selected; 16 transferable, 0 filtered, 0 blocked. Never report redacted URLs for non-transferable candidates. If PanSou returns no .data.merged_by_type.quark, or the helper returns no selected, say that no verified Quark link was found and suggest refining the keyword, switching src, or adjusting the policy.

When saving was requested, report whether quarkpan saved the selected link successfully based on save_result. Include the destination folder, number of files, and saved item names if visible in the command output. If saving fails, include the visible quarkpan failure message and do not invent a replacement link.

When a prior response ended with a save prompt and the user replies 1, treat that as a request to save the prior selected item. Do not reinterpret 1 as a new search keyword or content-selection choice unless the active prompt was a content selection prompt.

Failure Handling

  • User shorthand: if the user says pansou, <keyword> or PanSou,<keyword>, treat <keyword> as the search keyword and run the normal --one --verify-link flow. Do not ask what PanSou means.
  • When a verified selected result has just been shown with save_prompt.available: true, interpret a following exact 1 as confirmation to rerun the same keyword/content choice with --save; do not treat it as a new content-selection choice or search keyword.
  • Missing keyword: ask for the keyword.
  • Policy helper failure: report the helper error and do not fall back to saving raw PanSou results unless policy behavior is reproduced manually.
  • No selected candidate: stop without outputting a link.
  • PanSou HTTP/network failure: report the endpoint and status/error, then ask whether to retry later or use another PanSou endpoint.
  • PanSou schema changes: inspect the JSON shape, extract only Quark URLs if still obvious, otherwise stop and report the schema mismatch.
  • Link verification failure: if another transferable candidate exists, the helper should choose it; otherwise report the failed verification and do not invent a working link.
  • Save failure: report save_result.reason, stdout, or stderr. If quarkpan cannot be installed because the helper attempted python3 -m pip install --user quarkpan from a virtualenv where user site-packages are hidden, install the missing package into the active environment instead (for example python3 -m pip install quarkpan) and retry the helper. If login then fails with a missing QR/image dependency such as No module named 'PIL', install Pillow in the same environment with python3 -m pip install Pillow and retry. If login is missing, start the login/check command as a tracked background process, send the generated qr_code_path PNG as native media (MEDIA:<path> in Telegram), then ask the user to scan and confirm before rerunning the search/save. Because QR codes expire quickly, do not only report the local path.
  • Weak verification: tell the user the URL page responded but share contents but share contents were not confirmed. Ask them to log in with quarkpan in the same config context if content-level validation is required.
  • Legal or access concerns: follow the deterministic policy gate. If the user explicitly requests bypass or unlawful access, stop and ask for user-owned, licensed, public-domain, or otherwise authorized material.