Files
archive-clients/docs/service-apis.md
T

7.4 KiB
Raw Blame History

qBittorrent and Syncthing integration

Adapters are version-aware boundaries. Core orchestration consumes normalized resource, route, and progress models and never branches on raw service response shapes.

qBittorrent Web API

The implementation targets qBittorrent 4.54.6 and 5.x releases and detects the application and Web API versions at startup. The authoritative references are the official 5.0 WebUI API and 4.1-compatible WebUI API.

Adapter capabilities

Need Web API family Archive Control rule
Authenticate auth/login, cookie session Log no credentials/cookies; reauthenticate once on expiry
Detect compatibility app/version, app/webapiVersion, build info Require qBittorrent 4.5.0+ because exact metainfo export is mandatory
List/lookup torrents/info, properties On-demand and hash-scoped where possible
Read file state torrents/files Normalize indices, paths, selected/skipped, size, progress
Export metainfo torrents/export Required before staging; fail if exact metainfo unavailable
Add target torrents/add Explicit save path, stopped/paused, manual management
Set selection torrents/filePrio / selection endpoint Encode only selected vs skipped, never preserve priority levels
Recheck torrents/recheck plus state polling Keep stopped; any download activity fails the job
Remove entry torrents/delete Eviction uses deleteFiles=false only

The adapter accounts for terminology/behavior changes such as paused versus stopped states. It does not mutate qBittorrent preferences, categories, tags, limits, queueing defaults, or global save-path behavior.

Syncthing route validation normalizes both absolute and ~/ folder-path spellings under the configured sync root before comparing an existing folder; an equivalent pre-existing pair is adopted without rewriting it.

Inventory normalization

For each torrent the client derives canonical v1/v2 identity from reliable API and exported-metainfo data, keeps the qB-local hash separately, and calculates:

  • total and selected-complete logical bytes;
  • normalized selected and selected-complete file-index sets;
  • torrent runtime state;
  • canonical path flag and content revision;
  • a save-path fingerprint based on validated path mapping, never a leaked absolute host path.

qBittorrent 5 may expose a pure-v2 or hybrid torrent under the first 20 bytes of its v2 hash while separately advertising full infohash_v1 and infohash_v2 values. Lookup matches all advertised identities, rejects ambiguous matches, validates the canonical hashes from exported metainfo, and uses only qBittorrent's returned local hash for later mutation calls.

Complete content trees are built only for a chosen resource or job preflight. All entries retain qBittorrent's stable torrent file index. Renamed/noncanonical content paths are rejected in v1 because they cannot be transported and merged without ambiguity.

Verification guard

The client captures transfer counters and state before recheck, issues recheck, and watches until success, timeout/stall, or failure. Success requires every selected file complete and no missing/error pieces. Any downloading state or increase in received payload bytes causes immediate stop and a failed job with the affected path/piece detail available from the adapter when possible.

Syncthing REST and events APIs

Clients authenticate using the configured API key header and discover exact service version/capabilities. Primary references are Syncthing's official REST conventions, configuration model, and DownloadProgress event.

Discovery and route management

The adapter reads system status/version and configuration, then selects folders that:

  • are sendreceive;
  • map beneath the configured API-visible and local sync roots;
  • contain exactly the local device and one peer device;
  • pair one registered cache with one registered archive client;
  • have a safe relative filesystem path.

The folder's native ID becomes route_id. Multi-device, send-only, receive-only, out-of-root, or ambiguous folders are reported as unsupported and left unchanged.

Syncthing may serialize a folder path relative to its home as ~/.... The client normalizes that notation beneath the configured API-visible sync root before applying the API-to-local root mapping. Deployments must mirror Syncthing's nested bind mounts into the client so the normalized API path and the client filesystem path refer to the same bytes.

Provisioning uses idempotent device and folder configuration updates. Each client receives its peer device ID and optional advertised addresses (dynamic by default). It changes only the specific device/folder objects owned by the provisioning command. Read-back verification must agree before nonce exchange begins.

Transfer progress and completion

DownloadProgress events are filtered to the job's exact staging prefix and used for live block-level byte estimates. Their percentage is advisory. The adapter falls back to coarser polling if events are unavailable.

Final completion combines:

  • job-prefix files present and matching manifest logical sizes;
  • Syncthing folder/local-global completion from the official db/completion response;
  • per-file state from db/file where supported;
  • no relevant outstanding entries from db/need;
  • valid manifest digest and ready marker.

The client can request a scoped rescan after publishing/cleanup. It does not declare transfer success from a 100% progress event alone.

Error normalization

Each adapter maps transport errors, authentication failure, incompatible API, missing torrent/folder, stale external state, permission failures, and service health into stable protocol error codes. Responses and exception text are redacted before logging because service products may echo URLs, headers, or filesystem paths. Authentication failures are permanent until configuration changes; transient service absence moves an active job to waiting.

Bot-free control adapter

The loopback-only test adapter calls the same ArchiveControlService used by Telegram:

  • GET /test/v1/resources?operation=archive|unarchive|evict_cache performs a complete, paged, on-demand summary scan and reconciles placements.
  • GET /test/v1/resources/{info_hash}/tree?client_id={client} fetches one complete revisioned content tree.
  • POST /test/v1/jobs/preview fetches fresh source and target summaries and full trees, expands optional selected_paths or selected_file_indices, and returns an immutable definition plus its preview_revision.
  • POST /test/v1/jobs consumes {preview_revision, definition} and rejects a deterministic protobuf SHA-256 mismatch.
  • Job list/detail/cancel/hide/clear endpoints expose the shared ownerless job state, while GET /test/v1/placements exposes reconciled generations.

Lower-level inventory-query, route, scheduler, and backup endpoints remain for contract and failure-injection tests. This adapter must never bind outside loopback.