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

153 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-%28qBittorrent-5.0%29)
and [4.1-compatible WebUI API](https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-%28qBittorrent-4.1%29).
### 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](https://docs.syncthing.net/dev/rest.html),
[configuration model](https://docs.syncthing.net/users/config.html), and
[DownloadProgress event](https://docs.syncthing.net/events/downloadprogress.html).
### 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`](https://docs.syncthing.net/rest/db-completion-get.html)
response;
- per-file state from [`db/file`](https://docs.syncthing.net/v2.0.0/rest/db-file-get.html)
where supported;
- no relevant outstanding entries from
[`db/need`](https://docs.syncthing.net/v1.19.2/rest/db-need-get.html);
- 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.