qBittorrent Shim and Automation FR - Kheopsian/Hydranos GitHub Wiki
S'applique à Hydranos 4.4.
Pour vous qui branchez Sonarr, Radarr, Lidarr, autobrr, cross-seed ou un script sur Hydranos comme s'il s'agissait de qBittorrent : ce que fait réellement chaque appel, ce qui est constant ou ignoré, et les réglages qui fonctionnent pour chaque application (Recettes par application ci-dessous). Vous migrez une installation qBittorrent existante ? Suivez d'abord Migrer depuis qBittorrent.
Le shim qBittorrent est l'ensemble des routes sous /api/v2/*, sur le même port que l'interface web, port 8199 par défaut ([daemon] api_port). Il imite l'API WebUI de qBittorrent d'assez près pour les outils d'automatisation courants :
-
GET /api/v2/app/versionrépondv4.6.0(texte brut). -
GET /api/v2/app/webapiVersionrépond2.9.3.
Ces deux valeurs sont figées exprès : les outils choisissent leurs appels en fonction d'elles. Les ajouts suivent la règle de placement habituelle (catégorie → moteur et chemin de sauvegarde, voir Catégories & routage). Le shim liste tous les moteurs (moteurs supplémentaires compris), chaque torrent une seule fois, mais n'ajoute que dans race ou hoard (selon la catégorie) : il n'a aucun champ pour désigner un moteur.
Tant qu'Hydranos charge encore ses torrents au démarrage, toutes les routes /api/v2/*, login compris, répondent 503 avec un corps JSON et Retry-After: 5 ; les clients réessaient.
POST /api/v2/auth/login prend un corps de formulaire (application/x-www-form-urlencoded) avec username et password. Deux types d'identifiants sont acceptés :
| Nom d'utilisateur | Mot de passe | Accepté quand |
|---|---|---|
le nom du compte admin ([auth] username, par défaut admin) |
le mot de passe admin | le hachage bcrypt de [auth] password_hash correspond |
| n'importe lequel | la clé API ([daemon] api_key) |
la clé correspond exactement |
La réponse est toujours HTTP 200 : Ok. avec un en-tête Set-Cookie: SID=…, ou Fails. (même réponse pour tout identifiant erroné). Un corps JSON n'est pas lu : envoyez un formulaire.
La session SID expire après 1 heure sans requête (chaque requête authentifiée la prolonge), 256 au plus existent en même temps (la plus ancienne est supprimée), et toutes sont perdues au redémarrage d'Hydranos : les clients se reconnectent alors. Le cookie est Path=/; HttpOnly; SameSite=Lax, sans Secure, il fonctionne donc en HTTP simple. Il ouvre aussi toute l'API REST native : traitez-le comme la clé API.
Toutes les autres routes du shim exigent une authentification ; un script peut à la place envoyer la clé API dans un en-tête X-Api-Key ou un paramètre de requête apikey. Un appel au shim non authentifié reçoit 403 Forbidden. (texte brut), comme le vrai qBittorrent (l'API REST native répond 401). POST /api/v2/auth/logout termine la session et ne demande aucun identifiant.
Les règles sur le compte, la clé API et l'exposition sont sur Sécurité & accès.
# Log in (admin account, or any username + YOUR_API_KEY as password), keep the cookie
curl -i -c jar.txt \
--data-urlencode 'username=admin' --data-urlencode 'password=YOUR_PASSWORD' \
http://hydranos.example.org:8199/api/v2/auth/login
# Or skip the login and send the key
curl -H 'X-Api-Key: YOUR_API_KEY' http://hydranos.example.org:8199/api/v2/app/versionfull = comme qBittorrent ; partial = fonctionne, différences indiquées ; constant = valeurs figées ; refused = répond 409 avec la raison en texte brut et ne change rien.
| Endpoint | Verbes | Fidélité | Ce que fait Hydranos |
|---|---|---|---|
auth/login |
POST | full | Voir Se connecter. |
auth/logout |
POST | full | Révoque la session et fait expirer le cookie. |
app/version |
tous | constant |
v4.6.0. |
app/webapiVersion |
tous | constant |
2.9.3. |
app/buildInfo |
tous | constant | Les versions de bibliothèques d'un vrai qBittorrent 4.6.0 (qt 6.5.3, libtorrent 2.0.9.0…), aucune n'est utilisée par Hydranos. |
app/preferences |
tous | partial | Réels : dht, pex, listen_port, max_connec, max_uploads_per_torrent, queueing_enabled, max_active_downloads, les clés des torrents lents (dont_count_slow_torrents, slow_torrent_*) (toutes depuis [race]) ; max_active_uploads/max_active_torrents (depuis [race] quand queueing est activé, sinon 50/100) ; lsd ; up_limit/dl_limit (plafonds globaux du client, octets/s, 0 = aucun) ; les clés de limite de partage (max_ratio_enabled, max_ratio, max_seeding_time*, max_inactive_seeding_time*, max_ratio_act) du moteur race ; save_path (vide tant qu'un client ne l'a pas défini avec setPreferences) ; web_ui_port (= api_port) ; create_subfolder_enabled (= [daemon] create_torrent_folder). Constantes : encryption 1, locale en, les *_enabled annexes à false. |
app/setPreferences |
POST | partial | Applique les limites de partage, les plafonds de débit, dht/pex/lsd, les nombres d'actifs, la règle des torrents lents et save_path ; les autres clés répondent 200 et ne font rien. Chacune n'est écrite (sur chaque moteur local) que si elle diffère de ce qu'affiche app/preferences : renvoyer la page telle quelle ne change donc rien, valeurs de [hoard] comprises. Voir Limites. |
app/defaultSavePath |
tous | full | Le save_path défini via setPreferences, vide sinon. |
transfer/info |
tous | partial |
dl_info_data/up_info_data = octets transférés pendant cette session ; vitesses = somme de tous les moteurs ; dht_nodes réel ; *_rate_limit = les plafonds globaux du client. connection_status vaut toujours connected. |
transfer/uploadLimit, transfer/downloadLimit
|
tous | full | Le plafond global du client, octets/s, 0 = aucun. |
transfer/setUploadLimit, transfer/setDownloadLimit
|
POST | full |
limit en octets/s, 0 ou négatif = aucun ; un seul plafond sur tous les moteurs de cet hôte, conservé après redémarrage. 400 sans limit. |
sync/maindata |
tous | partial | Toujours full_update: true (jamais de delta) : torrents (les lignes de torrents/info indexées par hash), categories, tags, server_state ; trackers vaut {} ; rid croît pendant toute la vie du processus. |
torrents/info |
tous | partial | Voir La liste des torrents vue par les *arr ci-dessous. |
torrents/count |
tous | full | Le nombre de lignes que liste torrents/info sans filtre. |
torrents/properties |
tous | partial | Réels : totaux de transfert, share_ratio, seeding_time, eta, totaux de session, vitesses moyennes, peers (connectés), peers_total/seeds_total (tracker), creation_date, created_by, comment (lus dans le .torrent stocké, creation_date -1 s'il est absent), up_limit/dl_limit, clés de limite de partage. seeds et total_wasted valent 0. hash complet de 40 caractères ; 404 si inconnu. |
torrents/files |
tous | partial | Réels : noms (les noms multi-fichiers commencent par le dossier du torrent), tailles, piece_range, progress par fichier, priority (1, 6 ou 7, jamais 0), is_seed. availability vaut toujours 1. |
torrents/trackers |
tous | partial |
** [DHT] **, ** [PeX] ** (statut 2, compteurs à 0), ** [LSD] ** (statut 0 avec This torrent is private ou LSD is off for this engine, sinon 2 avec les pairs du LAN trouvés), puis les vrais trackers avec leur palier. status est une seule valeur pour tout le torrent : 1 pas encore contacté, 2 fonctionne, 4 dernière annonce échouée (avec msg) ; num_peers et num_downloaded valent 0. 404 pour un hash inconnu. |
torrents/export |
tous | full | Le .torrent stocké (application/x-bittorrent) ; 404 s'il n'y en a pas. |
torrents/add |
POST | partial | Voir Ajouter des torrents via le shim. |
torrents/delete |
POST | full |
hashes, deleteFiles=true|1. Supprime chaque copie du torrent, dans tous les moteurs. Les fichiers partagés avec un autre torrent chargé sont conservés. Toujours 200. |
torrents/pause, torrents/stop
|
POST | full | Arrêt (intention utilisateur persistée) sur chaque copie. pause et stop sont les noms qBittorrent 4 et 5 du même appel. |
torrents/resume, torrents/start
|
POST | full | Démarre chaque copie. |
torrents/recheck |
POST | full | Revérifie le hash de chaque copie, avec la même garde que Vérifier à nouveau (Recheck) du menu contextuel : si un fichier est aussi nommé par un autre torrent avec un autre contenu, la copie est arrêtée et ces fichiers sont vérifiés d'abord ; elle n'est revérifiée (et redémarrée si elle tournait) que s'ils sont valides, sinon elle reste arrêtée en erreur avec la raison. Toujours 200 ; la ligne de journal qbit bulk recheck compte les copies vérifiées et celles refusées (une copie supprimée entre-temps) ; un magnet encore en résolution n'a pas encore de copie et est ignoré. |
torrents/reannounce |
POST | full | Demande au planificateur d'annonces de chaque copie une annonce immédiate. Toujours 200 ; les comptes vont dans le journal. |
torrents/setLocation |
POST | partial |
hashes, location : un job de déplacement par copie, comme Déplacer vers un dossier… (Set location…) (onglet Jobs). 400 sans location ; 409 avec la raison quand rien n'a pu être mis en file. |
torrents/setShareLimits |
POST | partial |
ratioLimit et seedingTimeLimit (minutes) obligatoires (400 sinon), inactiveSeedingTimeLimit facultatif ; -2 = suivre le moteur, -1 = pas de limite. Voir Limites. |
torrents/setForceStart |
POST | partial |
value=true marque chaque copie comme forcée (comme Forcer le téléchargement) et la démarre : la file la fait tourner au-delà de tout plafond sans la compter. value=false retire la marque. Les lignes indiquent toujours force_start: false. |
torrents/uploadLimit, torrents/downloadLimit
|
tous | full |
{hash: octets/s}, 0 = aucun. |
torrents/setUploadLimit, torrents/setDownloadLimit
|
POST | full |
hashes, limit (octets/s, 0 ou négatif = aucun), sur chaque copie. 400 sans limit. |
torrents/filePrio |
POST | partial |
hash, id (séparés par |), priority 1, 6 ou 7 : l'ordre dans lequel les fichiers sont récupérés. La priorité 0 est refusée : chaque fichier est toujours téléchargé. 400 pour une priorité absente ou invalide, 409 pour un id de fichier hors limites. |
torrents/toggleSequentialDownload, torrents/toggleFirstLastPiecePrio
|
POST | full | Inverse l'indicateur ; chaque copie prend la nouvelle valeur de la première. |
torrents/rename |
POST | refused | Le nom est celui du .torrent. 404 pour un hash inconnu. |
torrents/topPrio, bottomPrio, increasePrio, decreasePrio
|
POST | refused |
Torrent queueing is not enabled quand aucun moteur qui détient les torrents n'a de file ; sinon une raison indiquant que Hydranos ordonne sa file lui-même et que le démarrage forcé fait passer un torrent devant. |
torrents/categories |
tous | partial |
{name: {"name", "savePath"}}. Le mode de la catégorie n'apparaît pas. |
torrents/createCategory |
POST | partial |
category, savePath. Crée toujours le mode hoard ; un nom existant répond 409 Category already exists. |
torrents/editCategory |
POST | partial | Change seulement le chemin de sauvegarde ; crée une catégorie hoard si le nom est inconnu. |
torrents/removeCategories |
POST | full |
categories, séparées par des retours à la ligne ou des virgules. Les torrents perdent l'étiquette. |
torrents/setCategory |
POST | partial |
hashes, category (vide = retire). Étiquette seulement : aucun déplacement de fichiers, aucun changement de moteur, aucune vérification que la catégorie existe. |
torrents/tags |
tous | full | Les tags enregistrés. |
torrents/createTags |
POST | full | Enregistre des tags. |
torrents/deleteTags |
POST | full | Retire les tags de la liste et de chaque torrent. |
torrents/addTags, torrents/removeTags
|
POST | full |
hashes, tags (séparés par des virgules). Appliqué à chaque copie. |
torrents/addTrackers, torrents/removeTrackers
|
POST | partial | Champ de formulaire hash (singulier, hash complet) et urls (séparées par des retours à la ligne ou |). Chaque URL ajoutée devient son propre palier, à la fin, et les copies l'annoncent aussitôt. 400 si un champ est vide ou si le torrent a été ajouté il y a quelques secondes et que son .torrent n'est pas encore stocké (réessayez peu après) ; 404 pour un torrent inconnu. |
rss/* (13 routes) |
POST ; items, rules, matchingArticles tous |
full | L'API RSS de qBittorrent : addFolder, addFeed, setFeedURL, removeItem, moveItem, refreshItem, markAsRead, items, setRule, renameRule, removeRule, rules, matchingArticles. 400 Missing parameter: X ou valeur mal formée, 409 pour un refus. Voir RSS et téléchargements automatiques. |
Remarques :
-
hashesest découpé sur|ou,;alldésigne tous les torrents de tous les moteurs. Les endpoints d'écriture qui prennenthashesacceptent un préfixe de hash (le premier torrent stocké qui correspond l'emporte) et répondent un 200 vide comme qBittorrent, même quand aucun hash n'a correspondu : vérifiez avectorrents/info, pas avec le code de statut. Exceptions : les cas refused et 400 ci-dessus,addTrackers/removeTrackers(hash, pas deall),createCategory(400 sur un nom vide, 409 sur un nom existant),torrents/add(Ok./Fails.). Les appels qui prennent un seulhash(properties,files,filePrio,rename) exigent le hash complet. - Où sont lus les paramètres : les appels de lecture (
torrents/info,properties,files,trackers,export) et les appels ajoutés en 4.4 (setLocation,setShareLimits,setForceStart, les appels de limite,filePrio, les bascules,rss/*) les prennent dans la query string ou un corps de formulaire (cross-seed envoie tout en formulaire POST). Les anciens appels d'écriture (arrêt, démarrage, suppression, revérification, réannonce, tags, catégories, trackers) ne lisent que le corps du formulaire. - Les actions par hash atteignent chaque copie, moteurs supplémentaires compris. Pour cibler une seule copie, utilisez
?engine=sur l[[API REST|REST-API-FR]].
Ces routes ne sont pas enregistrées. Elles répondent HTTP 404 (un mauvais verbe sur une route existante répond 405) :
torrents/ setSuperSeeding, setAutoManagement, renameFile, renameFolder, editTracker, pieceStates, pieceHashes, webseeds ; app/shutdown ; transfer/ banPeers, toggleSpeedLimitsMode, speedLimitsMode ; sync/torrentPeers ; log/*, search/*.
Le shim annonce tout de même WebAPI 2.9.3, un outil peut donc les essayer. Pour la recherche, gardez Prowlarr ou autobrr.
torrents/info est l'appel que Sonarr, Radarr, autobrr et cross-seed interrogent en boucle. Il accepte, dans la query string ou un corps de formulaire :
| Paramètre | Comportement |
|---|---|
category |
Correspondance exacte sur la catégorie sous laquelle une ligne est rapportée (voir category ci-dessous). |
filter |
all, downloading, seeding, completed, paused = stopped, active, inactive, stalled, stalled_uploading, stalled_downloading, errored, resumed = running. Une valeur inconnue liste tout. |
tag |
Un seul tag, correspondance exacte. |
hashes |
Hashes complets séparés par | ou ,. all signifie aucun filtre. |
sort, reverse
|
N'importe quel champ de ligne ; par défaut added_on. reverse=true inverse l'ordre. |
limit, offset
|
Pagination ; 0 ou absent = pas de limite. |
Tous les moteurs sont listés, et chaque torrent une seule fois : le premier moteur qui le détient répond, dans l'ordre race, hoard, puis les moteurs supplémentaires. Un torrent détenu à la fois par race et hoard est donc rapporté comme sa copie race (save_path et content_path de race, et race comme catégorie de repli). torrents/count et sync/maindata listent les mêmes lignes.
| Champ | Valeur |
|---|---|
hash, name, size/total_size, progress, dlspeed, upspeed, added_on, completion_on, tags
|
Réels. |
num_seeds/num_complete, num_incomplete
|
Les seeders et leechers du tracker (dernière annonce ou dernier scrape). |
num_leechs |
Pairs connectés en ce moment. |
category |
La catégorie du torrent ; un torrent sans catégorie est rapporté sous le nom de son moteur (race, hoard ou l'identifiant du moteur supplémentaire). |
save_path |
Le dossier où le moteur garde les données. |
content_path |
save_path + / + name. C'est le chemin depuis lequel les *arr importent et cross-seed crée ses liens. |
state |
Voir le tableau suivant. |
uploaded, downloaded, ratio
|
Les compteurs à vie du torrent ; ratio = envoyé / téléchargé, deux décimales. Un torrent complet dont le compteur de téléchargement vaut 0 (ajouté en mode seed) rapporte downloaded = taille. |
amount_left, completed
|
Complet : 0 et la taille. Incomplet : taille moins les octets téléchargés, et les octets téléchargés. |
eta |
Octets restants divisés par le débit de téléchargement actuel ; 8640000 (l'« infini » de qBittorrent) quand rien n'est reçu. |
seeding_time |
Secondes de seed. |
tracker |
La première URL de la liste de trackers du torrent (la liste à laquelle il annonce) ; vide pour un torrent sans tracker. |
up_limit, dl_limit
|
Les plafonds de débit propres au torrent, octets/s, -1 = aucun. |
seq_dl, f_l_piece_prio
|
Téléchargement séquentiel et première/dernière pièce d'abord, tels que réglés. |
ratio_limit, seeding_time_limit, inactive_seeding_time_limit
|
Les limites de partage propres au torrent (-2 = suivre le moteur). |
max_ratio, max_seeding_time, max_inactive_seeding_time
|
Les limites en vigueur pour lui (-1 = aucune). |
time_active |
Maintenant moins added_on. |
availability, seen_complete, priority, auto_tmm, super_seeding, force_start, magnet_uri
|
0, false ou vide. |
Absents : infohash_v1, private, trackers_count, last_activity.
Depuis la 4.4, uploaded et ratio sont les vrais chiffres (la 4.3 les laissait à 0). Un objectif de seed réglé dans Sonarr, Radarr, Lidarr ou une règle autobrr agit désormais sur eux, et peut supprimer des torrents : voir Recettes par application.
| Situation dans Hydranos | state |
|---|---|
| Vous l'avez arrêté (persisté, survit aux redémarrages) |
stoppedUP (complet) / stoppedDL
|
Retenu par le moteur sans arrêt de votre part (par exemple en attente d'un emplacement de téléchargement, ou d'un emplacement de seed sous queueing) ; repart tout seul |
queuedUP / queuedDL
|
| En seed, envoie en ce moment / n'envoie pas en ce moment |
uploading / stalledUP
|
| En téléchargement, reçoit en ce moment / ne reçoit pas |
downloading / stalledDL
|
| Vérification du hash en cours |
checkingDL (aussi pour les torrents complets) |
| Erreur | error |
| Tout le reste |
stalledUP / stalledDL
|
Jamais renvoyés : pausedUP/pausedDL, forcedUP/forcedDL, metaDL, missingFiles, checkingUP, checkingResumeData, moving, allocating (un torrent en cours de déplacement garde son état). Un magnet qui attend encore ses métadonnées n'est pas listé du tout. Le filtre paused/stopped ne correspond qu'aux lignes stopped*.
POST /api/v2/torrents/add est un formulaire multipart :
| Champ | Lu ? | Signification |
|---|---|---|
torrents, file, fileselect
|
oui | Parties fichier .torrent ; plusieurs autorisées. |
urls |
oui | Une par ligne. Les liens magnet:? sont résolus en arrière-plan ; les liens http(s) sont téléchargés (délai 30 s, 15 MiB max, sans cookies). |
category |
oui | Choisit le moteur (mode de la catégorie) et le chemin de sauvegarde. |
savepath |
oui | Remplace le chemin de sauvegarde de la catégorie. |
tags |
oui | Séparés par des virgules. |
autoTMM |
oui |
true : quand la catégorie a un chemin de sauvegarde, savepath est ignoré. |
paused, stopped
|
oui |
true ou 1 : ajout à l'arrêt. |
stopCondition |
oui |
MetadataReceived ou FilesChecked : ajout à l'arrêt. |
skip_checking |
oui |
true ou 1 : mode seed, pas de vérification du hash des données déjà sur disque. Magnets aussi (appliqué à l'arrivée des métadonnées). |
upLimit, dlLimit
|
oui | Les plafonds de débit du torrent, octets/s ; 0 ou négatif = aucun. |
ratioLimit, seedingTimeLimit, inactiveSeedingTimeLimit
|
oui | Les limites de partage propres au torrent, comme setShareLimits (minutes ; -2 suivre le moteur, -1 aucune). Voir Limites. |
contentLayout |
oui |
Original, Subfolder (un fichier seul reçoit un dossier) ou NoSubfolder ; l'emporte sur root_folder. NoSubfolder sur un torrent multi-fichiers est refusé : le moteur l'écrit toujours sous son dossier. |
root_folder |
oui | Forme ancienne : true = Subfolder, false = NoSubfolder. Sans aucun des deux champs, [daemon] create_torrent_folder décide. |
sequentialDownload, firstLastPiecePrio
|
oui | Ordre de téléchargement (Ajouter des torrents & données existantes). |
| tout autre champ | non | Ignoré (encadré ci-dessous). |
Accepté mais ignoré en 4.4 : les champs d'ajout
renameetcookie(et tout autre champ inconnu) ressemblent à des options par torrent — Hydranos les ignore et journaliseqbit add: these fields have no effect in Hydranos— le torrent garde le nom de son.torrent; une URL.torrentqui exige un cookie doit être récupérée par l'outil et envoyée comme fichier.
Ce qui détermine la réponse :
-
Placement. Une catégorie connue donne le moteur (mode
hoard→hoard, tout le reste →race) et son chemin de sauvegarde ; une catégorie inconnue va dansrace. Sans dossier venant desavepathou de la catégorie, c'est le dossier qu'un client a défini avecsetPreferencessave_pathqui sert ; s'il n'y en a pas non plus, l'ajout est refusé (journal :no save path: category "X" is unknown and no savepath was given). Le shim ne peut pas désigner un moteur. - Déjà ajouté (même torrent déjà dans ce moteur) compte comme un succès.
-
Réponse :
Ok.(200) si au moins un élément a été accepté ;Fails.(HTTP 400) si tous les éléments ont été refusés ;Bad request(400) s'il n'y avait ni fichier ni URL. Exception : une URL.torrenthttp(s)qui se télécharge mais dont l'ajout est ensuite refusé (par exemple sans chemin de sauvegarde) reçoit quand mêmeOk.; vérifieztorrents/infoou le journal. -
Magnets :
Ok.signifie que la résolution a commencé. Le torrent n'entre dans le moteur, et danstorrents/info, qu'à l'arrivée de ses métadonnées ; d'ici là il reste dans la carte Magnets de l'onglet + Ajouter un torrent (+ Add Torrent) (quelques nouvelles tentatives, puis il y reste avec la raison). Les options d'ajout (plafonds, limites de partage, ordre de téléchargement, disposition,skip_checking) sont gardées avec la demande et appliquées une fois le magnet résolu ; un magnetNoSubfolderqui s'avère multi-fichiers échoue à ce moment-là avec cette raison. - Les données déjà sur disque sont vérifiées par hash, sauf si
skip_checkingest défini. Les workflows « à l'ajout » s'exécutent (pour les magnets, une fois résolus). Le corps de la requête est limité à 2 Mo.
Magnets, mode seed, URL .torrent et dédup sont expliqués sur Ajouter des torrents & données existantes.
H=http://hydranos.example.org:8199
# A .torrent file into the category "tv"
curl -b jar.txt -F '[email protected]' -F 'category=tv' $H/api/v2/torrents/add
# A magnet (use --form-string so curl does not interpret ; or @)
curl -b jar.txt \
--form-string 'urls=magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef01234567&tr=https://tracker.example.org/announce' \
-F 'category=tv' $H/api/v2/torrents/add
# Seed mode on data already in place, explicit folder
curl -b jar.txt -F '[email protected]' -F 'savepath=/data/movies' -F 'skip_checking=true' $H/api/v2/torrents/add
# List a category, remove a torrent with its files
curl -b jar.txt "$H/api/v2/torrents/info?category=tv&filter=downloading"
curl -b jar.txt -d 'hashes=0123456789abcdef0123456789abcdef01234567&deleteFiles=true' $H/api/v2/torrents/deleteVoici ce que reçoit Hydranos quand autobrr envoie un magnet :
sequenceDiagram
participant AB as autobrr
participant SH as Shim qBittorrent Hydranos
participant MR as Résolveur de magnets BEP 9
participant EN as Moteur race ou hoard
AB->>SH: POST auth/login (username, password)
SH-->>AB: 200 Ok. et cookie SID
AB->>SH: POST torrents/add (urls = lien magnet, category)
alt pas de savepath, pas de chemin de sauvegarde de catégorie, pas de save_path de préférences
SH-->>AB: 400 Fails.
else placement trouvé
SH->>MR: enregistre la demande de magnet et lance la résolution
SH-->>AB: 200 Ok.
MR->>MR: récupère les métadonnées auprès des pairs et les vérifie contre l'info hash
MR->>EN: ajoute le torrent à son chemin de sauvegarde (savepath, catégorie ou setPreferences), démarré sauf ajout à l'arrêt
end
AB->>SH: POST torrents/reannounce (hashes)
Note over SH,EN: un magnet encore en résolution n'a pas encore de copie, rien n'est annoncé
SH->>EN: annonce immédiate, chaque copie
SH-->>AB: 200 (corps vide)
Créez vos catégories dans Hydranos (onglet Catégories (Categories), + Nouveau (+ New) : Nom (Name), Mode Race/Hoard, Chemin d'enregistrement (Save Path)) avant d'y faire pointer un outil, et utilisez les mêmes noms dans l'outil. Les appels de catégorie du shim ne peuvent pas définir de mode :
-
createCategoryenregistre toujours le modehoard. Sur un nom qui existe déjà, il répond 409Category already existset laisse la catégorie intacte (mode, Passer vers (Graduate to) et réglages de transit conservés). - Une catégorie créée par un outil avec un
savePathvide est enregistrée sans chemin de sauvegarde, et tout ajout ultérieur dans celle-ci est refusé, sauf si l'outil envoiesavepath(ou a défini un dossier par défaut avecsetPreferencessave_path). -
setCategoryne change que l'étiquette ; les données et le moteur ne bougent pas. Pour déplacer les données, utilisez Changer de catégorie + déplacer les fichiers › (Change category + move files ›) dans l'interface web (voir Catégories & routage).
Les tags sont des étiquettes sans effet sur le placement (Catégories & routage). deleteTags retire un tag de la liste et de chaque torrent ; removeCategories retire aussi cette étiquette des torrents.
Chaque application utilise son type de client de téléchargement qBittorrent ; les réglages non mentionnés restent à leur valeur par défaut. Ci-dessous, hydranos désigne l'hôte, qui dépend de l'endroit où tourne Hydranos :
- même réseau Docker que l'application : le nom du service,
hydranos; - derrière un conteneur gluetun (
network_mode: "service:gluetun") :gluetun, car Hydranos n'a pas de réseau à lui et le nomhydranosne se résout vers rien (VPN & sortie réseau) ; - réseaux différents, ou en cas de doute (par exemple le bridge par défaut d'Unraid) : l'adresse LAN de la machine hôte, par exemple
192.0.2.10, avec le port 8199 publié.
Chemins. Le shim rapporte save_path et content_path tels qu'Hydranos les voit. Montez le même dossier de l'hôte au même chemin de conteneur dans les deux conteneurs (Docker), ou ajoutez un remote path mapping dans l'application (host = l'hôte ci-dessus, remote = chemin côté Hydranos, local = son propre chemin).
Mode par catégorie. En cas de doute, classez vos catégories en Hoard. Race sert à courir sur les nouveaux uploads, et le drain race peut supprimer des torrents race avec leurs données ou les déplacer (Drain race & graduation).
Settings › Download Clients › + › qBittorrent :
| Réglage | Valeur |
|---|---|
| Host | hydranos |
| Port | 8199 |
| Use SSL | désactivé (activé seulement derrière un reverse proxy TLS, avec son port) |
| URL Base | vide |
| Username / Password | le compte admin, ou n'importe quel nom d'utilisateur + la clé API comme mot de passe |
| Category | une catégorie Hydranos existante, par exemple tv (Sonarr), movies (Radarr), music (Lidarr) |
| Post-Import Category | vide, ou une catégorie existante : elle ne fait que réétiqueter le torrent (aucun déplacement) |
| Recent / Older Priority | Laissez la valeur par défaut, Last : les appels de position dans la file répondent 409 (comme qBittorrent avec la file désactivée) |
| Initial State | Start ou Stop. Force Start démarre le torrent et le fait tourner au-delà de la file du moteur (active_downloads, 10 dans hoard tel que livré) |
| Sequential Order, First and Last First | Appliqués (ordre de téléchargement) |
| Content Layout | Appliqué ; No subfolder est refusé pour un torrent multi-fichiers, gardez Original
|
Ratio et durée de seed (réglages des indexeurs) fonctionnent désormais dans les deux sens :
- ils arrivent avec l'ajout sous forme de
ratioLimit/seedingTimeLimitet deviennent les limites de partage propres au torrent dans Hydranos ; - Sonarr/Radarr lisent les vrais
ratioetseeding_time, leur propre contrôle d'objectif de seed peut donc maintenant être atteint (et supprimer le torrent si la suppression des téléchargements terminés est activée dans l'application ; non testé par le mainteneur).
La limite de partage propre à Hydranos est en revanche retenue (journal share limit reached, held) tant que la durée minimale de seed déclarée pour le tracker n'est pas accomplie, et indéfiniment pour un tracker sans announce_min_seed_hours déclaré (un torrent sans aucun tracker n'est pas retenu) ; quand elle agit, elle applique la share_limit_action du moteur (stop par défaut), pas une action par torrent. Voir File d'attente, limites de partage et de débit. Un workflow reste l'autre moyen de faire le ménage après le seed.
Si Test échoue, vérifiez l'hôte, le port et les identifiants. Créez d'abord la catégorie dans Hydranos : Sonarr et Radarr n'appellent en général createCategory que pour une catégorie absente de torrents/categories, une catégorie existante n'est donc pas touchée, mais celle qu'ils créent n'a pas de chemin de sauvegarde et tout ajout dans celle-ci est refusé (non testé par le mainteneur).
Settings › Clients › Add new : type qBittorrent, host http://hydranos:8199, nom d'utilisateur et mot de passe comme ci-dessus (ou la clé API comme mot de passe). Dans l'action d'un filtre, choisissez ce client et réglez :
| Réglage de l'action | Effet dans Hydranos |
|---|---|
| Category | Doit exister dans Hydranos avec un chemin de sauvegarde, sinon renseignez Save Path. |
| Save Path | Envoyé comme savepath ; remplace le dossier de la catégorie. |
| Tags | Appliqués. |
| Add paused (le libellé peut varier selon la version) | Appliqué (ajout à l'arrêt). |
| Skip hash check | Appliqué, magnets compris (une fois résolus). |
| Reannounce (interval, attempts) | Fonctionne (torrents/reannounce). |
| Upload/download limits | Appliqués (plafonds propres au torrent). |
| Ratio limit, seed time limit | Enregistrés comme limites de partage du torrent ; même retenue par le minimum du tracker que ci-dessus. |
| Content layout | Appliqué ; NoSubfolder refusé pour un torrent multi-fichiers. |
autobrr envoie les magnets via urls (pris en charge). Ses règles client sur la vitesse, le ratio ou la quantité envoyée voient les vraies valeurs (transfer/info, torrents/info).
Faites pointer cross-seed vers le shim avec une URL qui porte les identifiants, puis utilisez l'injection :
// cross-seed config.js (v6 syntax; v5 uses qbittorrentUrl: "http://…" instead)
torrentClients: ["qbittorrent:http://admin:YOUR_PASSWORD@hydranos:8199"],
// or, with the API key: "qbittorrent:http://cross-seed:YOUR_API_KEY@hydranos:8199"
action: "inject",
skipRecheck: true,- cross-seed injecte avec un
savepathexplicite et, pour les correspondances complètes,skip_checking=true: Hydranos ajoute le torrent en mode seed dans ce dossier. Les correspondances partielles sont envoyées pour une revérification (non testé par le mainteneur). -
C'est la catégorie envoyée par cross-seed qui décide du moteur. Une catégorie inconnue d'Hydranos fonctionne quand même parce que cross-seed envoie un chemin de sauvegarde, mais le torrent atterrit alors dans le moteur race, où le drain peut le supprimer. Créez dans Hydranos les catégories qu'utilise cross-seed, avec le mode
hoardet un chemin de sauvegarde ; avecduplicateCategories, il envoie<category>.cross-seed, créez donc aussi celles-ci. - Tous les moteurs sont listés, cross-seed fait donc aussi correspondre les torrents détenus par des moteurs supplémentaires (il injecte dans
raceouhoard, selon la catégorie). Un torrent détenu par race et hoard est vu une seule fois, comme sa copie race. - cross-seed envoie ses appels en formulaires POST :
torrents/files,properties,trackers,exportetinfolisent lehashdans le corps.torrents/filesdonne les noms sous le dossier du torrent et les vraies plages de pièces, sa correspondance voit donc la vraie disposition.
Aucun rôle direct : Prowlarr fournit les indexeurs à Sonarr, Radarr et Lidarr. Pour récupérer depuis sa page de recherche, ajoutez Hydranos comme client de téléchargement avec les réglages Sonarr ci-dessus.
-
Limites de partage (
setShareLimits,ratioLimit/seedingTimeLimità l'ajout,setPreferencesmax_ratio*) : enregistrées et affichées, mais elles n'agissent qu'une fois accomplie la durée minimale de seed déclarée pour le tracker (announce_min_seed_hours), et jamais pour un tracker qui n'en a pas (un torrent sans aucun tracker n'est pas retenu) ; l'action est lashare_limit_actiondu moteur. Détails : File d'attente, limites de partage et de débit. -
app/setPreferencesexige un champjsonou un corps JSON (400 sans ; unsave_pathrelatif donne 400 avant toute écriture). Appliqués, à chaque moteur local :max_ratio*,max_seeding_time*,max_inactive_seeding_time*(chaque valeur seulement avec son*_enabled),max_ratio_act(2, super seeding, est journalisé et laisse l'action inchangée),up_limit/dl_limit(à chaud),max_active_downloads(à chaud),max_active_uploads/max_active_torrents(seulement siqueueingest déjà activé),dont_count_slow_torrentset les clésslow_torrent_*,save_path, etdht,pex,lsd(écrits dans le fichier, utilisés au prochain démarrage).queueinglui-même ne peut pas être basculé via le shim.
Accepté mais ignoré en 4.4 : les autres clés de
setPreferences(port d'écoute, chiffrement, limites de vitesse alternatives…) semblent enregistrées — elles répondent 200 et ne changent rien, journalisées soussetPreferences: these keys have no effect in Hydranos— utilisez l'onglet Config oudefault.toml.
Non implémenté en 4.4 : le téléchargement sélectif —
filePrio0 (ne pas télécharger) est refusé avec 409 et chaque fichier est toujours téléchargé — les priorités 1/6/7 ne changent que l'ordre. Manquent aussi : un delta depuissync/maindata(toujours une mise à jour complète), le statut et les nombres de pairs par tracker danstorrents/trackers,seeds/total_wasteddansproperties,availabilitypartout.
Autres fonctions de qBittorrent absentes : Migrer depuis qBittorrent.
Migrer depuis qBittorrent (bascule pas à pas, séquence d'ajout Sonarr) · Catégories & routage · Ajouter des torrents & données existantes · Sécurité & accès · Trackers & annonces · File d'attente, limites de partage et de débit · RSS et téléchargements automatiques · API REST