indexOF

Une requête, tous vos trackers, et le torrent part vers qBittorrent en un clic.
indexOF est une interface web auto-hébergée qui s'appuie sur Prowlarr pour interroger l'ensemble de vos indexeurs en une seule recherche. Pas de base à alimenter, pas de scraper maison : Prowlarr sait déjà parler à vos trackers — indexOF rend ses résultats lisibles, comparables et exploitables.
Stack : PHP 8.1+ · nginx + php-fpm · SQLite · Docker Compose · MIT
Le problème
Chercher une release sur cinq trackers, c'est cinq onglets, cinq sessions, et au bout du compte une liste de noms comme The.Matrix.1999.REMASTERED.MULTi.2160p.BluRay.REMUX.DV.HDR-REBiRTH dont on ne sait même pas de quel film il s'agit sans ouvrir la fiche du tracker.
indexOF supprime ce détour : une seule requête, une seule liste, et assez d'informations sur chaque ligne pour décider sans aller ailleurs.
Ce que ça fait
Chercher
- Recherche dynamique sans rechargement, état partageable par URL (
?q=…&days=…&trackers=…)
- Tri par pertinence par défaut : le titre qui contient toute la requête passe devant celui qui n'en a qu'un mot, avant même les seeders
- Vue « Top » : les derniers uploads de tous les trackers, sans taper de requête
- Filtres en un seul panneau — période, catégories, indexeurs, puis affinage (seeders minimum, freeleech, qualité, tranches de taille) ; les filtres actifs remontent en jetons retirables
- Exclusion de mots directement dans la requête :
matrix -animated
- Doublons regroupés : la même release sur cinq trackers tient sur une ligne, menée par la source la mieux seedée
- Contenu du
.torrent dépliable avant téléchargement — un fichier ou un pack de quarante épisodes ?
- Santé des indexeurs : latence, volume et échecs de chacun, pour comprendre une recherche qui traîne
- Raccourcis clavier complets (
/, j/k, Entrée, d, e, c, ?)
Comprendre ce qu'on regarde
Chaque ligne porte l'affiche et la fiche de l'œuvre — année, note, durée, genres, synopsis — directement dans la liste.
- Zéro configuration supplémentaire : la fonctionnalité s'allume dès que Radarr ou Sonarr est renseigné, ce sont eux qui interrogent TMDB / TheTVDB. Aucune clé API de plus à obtenir.
- Titres réparés en amont : beaucoup de trackers publient de l'UTF-8 relu en Latin-1 (« Deuxième » → « Deuxième »). C'était la première cause d'affiche manquante.
- Candidats classés, pas pris au hasard : sur « GAME OF THRONES INTEGRAL », Sonarr propose la bonne série en quatrième position. Les titres alternatifs comptent — c'est par eux que « Dune : Deuxième partie » rejoint « Dune: Part Two ».
- Une affiche fausse est pire qu'une case vide : une année connue mais démentie par tous les candidats vaut refus.
- Résultat mesuré sur 20 recherches réelles (1 200 films et séries) : 98 % de fiches trouvées.
- Le navigateur ne contacte jamais TMDB ni TheTVDB — tout passe par un proxy serveur avec cache. Ni votre IP, ni ce que vous regardez ne sortent.
Récupérer
- Téléchargement du
.torrent via un proxy chiffré, ouverture ou copie du magnet
- Envoi vers qBittorrent avec choix de la catégorie
- Ou relais vers Sonarr / Radarr / Lidarr / Readarr (
release/push), avec le retour affiché tel quel : « acceptée », ou le motif du refus. Pas de faux succès.
- Recherches enregistrées rejouables en un clic — et abonnables en RSS depuis qBittorrent, pour qu'il récupère les nouveautés tout seul
- Notifications Discord optionnelles sur les recherches surveillées
- « Déjà pris » : les releases déjà envoyées sont marquées dans les résultats, avec date et destination
- Vue Transferts : progression, ratio, vitesses, état, actions groupées — sans quitter l'app
Regarder
- Bibliothèque en grille d'affiches de ce qui est réellement sur le disque
- Lecture dans le navigateur pour ce qu'il sait décoder, lien VLC pour le reste — et l'interface le dit avant le clic plutôt que d'afficher une vidéo noire
- Envoi sur le téléviseur (Cast) : MiBox, Chromecast, Android TV découverts automatiquement, avec déplacement dans le film et durée complète, y compris sur un fichier converti
- Conversion à la volée, mais seulement du nécessaire — la décision se prend sur les codecs réels (
ffprobe), jamais sur l'extension :
| Mode | Quand | Coût |
direct | Conteneur et codecs compatibles | Aucun processus |
remux | Codecs bons, conteneur non (MKV H.264/AAC) | Quasiment gratuit |
audio | Image bonne, son non (AC3, DTS, TrueHD) | Audio seul réencodé |
full | L'image aussi (HEVC, VC-1, XviD) | Le seul cas lourd |
- Masquer ≠ supprimer : masquer retire le fichier de la vue, il reste partagé. Désencombrer sa liste ne doit pas coûter son ratio.
Partager l'accès
Comptes utilisateurs optionnels, avec cloisonnement par indexeur : chaque personne peut avoir ses propres identifiants de tracker dans Prowlarr, et ne voir que les siens. Ses téléchargements comptent sur son ratio, pas le vôtre. La restriction s'applique côté serveur sur tous les chemins — recherche, statistiques, flux RSS, veille Discord.
Catégorie qBittorrent attribuable par compte. Sauvegarde/restauration de la base par VACUUM INTO.
Sécurité
Le sujet a été pris au sérieux dès le départ, pas ajouté après coup :
- Clé API Prowlarr jamais exposée au navigateur — le client reçoit un jeton chiffré (AES-256-GCM) à durée de vie limitée
- Proxy
.torrent anti-SSRF : http(s) uniquement, rejet des IP privées, épinglage de l'IP validée (anti-DNS-rebinding), re-validation à chaque redirection
- Envoi Cast borné aux plages RFC 1918 : « non publique » laisserait passer
169.254.169.254 et ferait de l'endpoint un scanner de ports
- Lecture cloisonnée : dossier médias monté en lecture seule,
realpath() obligatoire, nginx sert depuis un emplacement internal
- Anti-brute-force :
limit_req nginx + verrouillage applicatif, quota séparé pour les affiches
- CSP stricte (pas d'inline, pas de CDN), conteneurs non-root,
cap_drop: ALL, FS en lecture seule, ports sur la loopback
- CI hebdomadaire : PHPStan niveau 7, PHPUnit sur PHP 8.3 et 8.5,
composer audit, Trivy, CodeQL. Une CVE publiée après le merge n'apparaît dans aucun scan déclenché par un commit.
Démarrage
cp exemple.env .env
sed -i "s/^APP_SECRET=.*/APP_SECRET=$(openssl rand -hex 32)/" .env
docker compose up -d --build
L'application est sur http://localhost:8080, Prowlarr sur :9696, qBittorrent sur :8081 — tous liés à la loopback, à exposer derrière un reverse-proxy TLS.
Il reste à récupérer la clé API Prowlarr (Settings → General → Security) et à la reporter dans .env. S'il manque un réglage, l'app ne démarre pas : elle affiche un écran qui les liste tous, avec le remède pour chacun.
Sonarr/Radarr, la veille Discord et la découverte Cast sont derrière des profils Compose — rien ne démarre sans le demander.
Ce que ce n'est pas
Ce n'est pas un serveur de médias. Pas de reprise de lecture, pas de sous-titres incrustés, pas de segmentation HLS sur la lecture navigateur. Pour une bibliothèque complète, Jellyfin sur le même dossier ./data/downloads reste plus adapté — les deux cohabitent sans se gêner.
indexOF fait une chose : rendre la recherche et la récupération agréables.
Liens
Contributions bienvenues (CONTRIBUTING.md). Les failles de sécurité se signalent en privé, pas dans une issue publique (SECURITY.md).