# ⛩ Ohm Stream Downloader Application web **auto-hébergée** (homelab) : centre de contrôle unique pour découvrir, regarder et télécharger des animes et séries VOSTFR/VF. > MVP — Phase 1 : recherche multi-sources, fiches enrichies, streaming, gestionnaire > de téléchargements temps réel, bibliothèque locale, favoris, administration. > Phase 2 : intégration Sonarr/Prowlarr — OhmStreaming est un **indexeur Torznab** > et personnalise « Pour toi » avec vos téléchargements Sonarr. ## Démarrage rapide ```bash uv sync # ffmpeg requis pour les flux HLS (binaire statique dans ~/.local/bin, ou apt install ffmpeg) uv run uvicorn app.main:app --host 0.0.0.0 --port 8777 ``` Serveur persistant : `tmux new-session -d -s ohm 'cd ~/Développement/ohm_streaming && uv run uvicorn app.main:app --host 0.0.0.0 --port 8777'` Puis ouvrir http://localhost:8777 — le **premier compte créé est administrateur**. ## Configuration Variables d'environnement (préfixe `OHM_`, voir `.env.example`) : | Variable | Défaut | Rôle | |---|---|---| | `OHM_SECRET_KEY` | `change-me-in-production` | **À changer** — signature des tokens | | `OHM_DOWNLOAD_DIR` | `./downloads` | Dossier des fichiers téléchargés | | `OHM_DATABASE_PATH` | `./data/ohm.db` | Base SQLite | | `OHM_MAX_PARALLEL_DOWNLOADS` | `3` | Téléchargements simultanés | ## Fonctionnalités - **Recherche unifiée** sur plusieurs sources (Vostfree, French-Manga) — chaque source est un module interchangeable activable/désactivable à chaud (page Admin). - **Extraction en 2 niveaux** : page d'épisode → lecteurs embarqués → URL directe (Sibnet, SendVid, VidMoly, Uqload, Vidzy, Luluvdo). - **Proxy vidéo intégré** (`/api/proxy`) : contourne les protections (tokens liés à l'IP, Referer/UA obligatoires), réécrit les playlists HLS. - **Streaming HLS** via hls.js ; **téléchargement HLS** via ffmpeg (remux mp4, progression temps réel). - **Métadonnées enrichies** via Kitsu (synopsis, genres, note, images) avec cache 72 h. - **Téléchargements** : file parallèle, pause/reprise (HTTP Range), retry, anti-doublons, progression en temps réel (SSE), persistance au redémarrage. - **Bibliothèque locale** : streaming avec range requests, reprise de lecture, navigation épisode suivant/précédent. - **Comptes** : JWT court + refresh token (rotation), rôles admin/utilisateur, administration des comptes. - **Découverte** (`/discover`) : 🆕 nouveautés fusionnées de toutes les sources, triées par date de sortie réelle (enrichissement Kitsu, badge « en cours de diffusion »), 🔥 incontournables (top popularité Kitsu) et ✨ recommandations par genres déduites des téléchargements et favoris, titres déjà possédés exclus (cache mémoire). ## Intégration Sonarr / Prowlarr (*arr) OhmStreaming expose une **API Torznab** : la suite *arr le voit comme un indexeur de plus, et chaque grab Sonarr déclenche l'extraction + le téléchargement dans la file interne (les épisodes arrivent dans la bibliothèque OhmStreaming). ### 1. OhmStreaming comme indexeur Dans **Admin → Intégrations Sonarr / Prowlarr**, copier : | Champ | Valeur | |---|---| | URL | `http://:8777/torznab/api` | | Clé API | générée automatiquement (bouton Régénérer pour la changer) | - **Prowlarr** : Indexers → Add Indexer → *Generic Torznab* → coller URL + clé, puis synchroniser vers Sonarr. - **Sonarr** (direct) : Settings → Indexers → Add → *Torznab* → coller URL + clé. Catégories : TV (5000) / Anime (5070). - **Client de téléchargement** : « Torrent Blackhole » — Sonarr enregistre le `.torrent` de service tandis qu'OhmStreaming télécharge réellement l'épisode (extraction embed → HLS/HTTP → mp4 dans `downloads/`). Endpoints : `t=caps`, `t=tvsearch` (q, season, ep), `t=search` — auth par `?apikey=` ou en-tête `X-Api-Key`. ### 2. « Pour toi » personnalisé par Sonarr Toujours dans **Admin → Intégrations**, renseigner l'URL Sonarr (`http://sonarr:8989`) et sa clé API (*Settings → General → API Key*), puis « Enregistrer » et « Tester ». Les genres des séries téléchargées/grabées sur Sonarr alimentent la section ✨ **Pour toi** (et ce qui y est possédé n'est pas re-recommandé). Sonarr absent ou KO → dégradation gracieuse, rien ne casse. ## Architecture ``` app/ ├── main.py # FastAPI + lifespan (DB, download manager) ├── config.py # pydantic-settings (OHM_*) ├── db.py # SQLite (aiosqlite) — source de vérité unique ├── routers/ # auth, search, discover, downloads, library, admin, torznab, pages ├── scrapers/ │ ├── base.py # contrats SourceScraper/HosterExtractor + registres │ ├── configs/ # sélecteurs YAML externalisés (réparer sans coder) │ ├── sources/ # vostfree, french_manga ├── services/ # downloads, kitsu, discover, sonarr, torznab, settings └── templates/ + static/ # UI htmx + Alpine.js, thème sombre ``` **Ajouter une source** : créer `app/scrapers/sources/ma_source.py` qui implémente `SourceScraper`, la décorer `@register_source` — c'est tout (registre auto-découvert). ## Tests ```bash uv run pytest # 61 tests uv run ruff check . # lint ```