# Ombrora YTDLP Interface web de téléchargement de vidéos via [yt-dlp](https://github.com/yt-dlp/yt-dlp), avec file d'attente persistante, suivi en base de données et liens de téléchargement sécurisés. ## Fonctionnement 1. L'utilisateur soumet une URL depuis l'interface web. 2. La demande est enregistrée en base (statut `PENDING`). 3. Le worker (Node.js, arrière-plan, supervisé par pm2) dépile les jobs et exécute `yt-dlp` en parallèle (concurrence configurable). 4. Le fichier téléchargé est stocké localement ; un token signé (24h) est généré. 5. L'utilisateur est redirigé vers une page de statut qui se rafraîchit jusqu'à ce que le fichier soit prêt. 6. Un cron quotidien supprime les fichiers expirés et marque les entrées `FILE_DELETED` — la DB conserve l'historique complet. ## Stack technique | Couche | Technologie | |--------|-------------| | Framework | Next.js 16 (App Router) | | Base de données | MariaDB 11 via Prisma 7 | | Frontend | React 19, TypeScript | | Worker | Node.js (tsx), supervisé par pm2 | | Conteneur (dev) | Docker Compose | ## Prérequis - Node.js 20+ - Docker & Docker Compose (pour MariaDB en développement) - `yt-dlp` et `ffmpeg` (binaires précompilés dans `./bin/` ou dans le `PATH`) ## Démarrage rapide ```bash # 1. Cloner le dépôt git clone ombrora-ytdlp && cd ombrora-ytdlp # 2. Copier et remplir les variables d'environnement cp .env.example .env # 3. Démarrer MariaDB docker-compose up -d # 4. Installer les dépendances npm install # 5. Appliquer les migrations Prisma npm run db:migrate # 6. Lancer le serveur Next.js npm run dev # 7. Dans un autre terminal, lancer le worker npm run worker ``` L'interface est accessible sur [http://localhost:3000](http://localhost:3000). ## Variables d'environnement | Variable | Requis | Exemple | Description | |----------|--------|---------|-------------| | `DATABASE_URL` | oui | `mysql://ombrora:ombrora@localhost:3306/ombrora` | Connexion MariaDB | | `STORAGE_PATH` | oui | `/var/www/ombrora/storage` | Répertoire de stockage des fichiers téléchargés | | `BIN_DIR` | non | `./bin` | Répertoire contenant `yt-dlp` et `ffmpeg` (défaut : `./bin`) | ## Scripts npm | Script | Description | |--------|-------------| | `npm run dev` | Serveur de développement Next.js | | `npm run build` | Build de production | | `npm start` | Serveur de production | | `npm test` | Tests Jest | | `npm run worker` | Worker de téléchargement (boucle de polling, exécution directe/dev) | | `npm run worker:pm2:start` | Démarre le worker sous pm2 (`ecosystem.config.cjs`), avec auto-restart | | `npm run worker:pm2:stop` | Arrête le worker géré par pm2 | | `npm run worker:pm2:restart` | Redémarre le worker géré par pm2 | | `npm run worker:pm2:status` | Affiche l'état du process `ombrora-worker` | | `npm run worker:pm2:logs` | Affiche les logs du worker géré par pm2 | | `npm run worker:cleanup` | Expire et supprime les fichiers anciens (usage cron) | | `npm run db:migrate` | Crée et applique les migrations Prisma (dev, interactif) | | `npm run db:migrate:deploy` | Applique les migrations en attente (production, non interactif) | | `npm run db:generate` | Régénère le client Prisma | | `npm run deploy` | Déploiement complet sur o2switch (voir section ci-dessous) | ## Configuration Les paramètres applicatifs sont centralisés dans `config/app.config.ts` : ```typescript DOWNLOAD_LINK_TTL_HOURS: 24 // Durée de validité du token de téléchargement WORKER_CONCURRENCY: 3 // Téléchargements parallèles maximum WORKER_POLL_INTERVAL_MS: 10000 // Intervalle de polling du worker (ms) RATE_LIMIT_MAX: 5 // Soumissions max par IP par fenêtre RATE_LIMIT_WINDOW_MS: 3600000 // Fenêtre de rate-limit (1h) ``` ## API | Méthode | Endpoint | Description | |---------|----------|-------------| | `POST` | `/api/downloads` | Soumet une URL. Corps JSON : `{ url, format?, quality?, subtitles?, extraArgs? }`. Retourne `{ uuid }`. | | `GET` | `/api/downloads/:uuid` | Statut d'un téléchargement. Retourne `{ status, fileName, fileSize, downloadToken?, tokenExpiresAt?, errorMsg? }`. | | `GET` | `/api/download/:token` | Téléchargement du fichier (token à usage unique, 24h). | ## Architecture ``` src/ ├── app/ │ ├── page.tsx # Page d'accueil (formulaire de soumission) │ ├── status/[uuid]/page.tsx # Page de suivi │ └── api/ │ ├── downloads/route.ts # POST — création │ ├── downloads/[uuid]/route.ts # GET — statut │ └── download/[token]/route.ts # GET — téléchargement ├── components/ │ ├── SubmitForm.tsx # Formulaire de soumission │ └── StatusView.tsx # Vue de suivi (polling) └── lib/ ├── prisma.ts # Client Prisma (singleton) ├── rate-limit.ts # Rate limiting par IP ├── token.ts # Génération/validation de tokens └── ytdlp.ts # Construction des arguments yt-dlp worker/ ├── index.ts # Boucle de polling principale ├── processor.ts # Exécution de yt-dlp, mise à jour DB └── cron-cleanup.ts # Nettoyage des fichiers expirés ecosystem.config.cjs # Config pm2 du process "ombrora-worker" prisma/ └── schema.prisma # Modèles : Download, DownloadToken ``` ## Déploiement (o2switch / Passenger) ### Contraintes spécifiques à l'hébergement mutualisé - **Pas de compilation sur le serveur** : `yt-dlp` et `ffmpeg` doivent être des binaires précompilés pour la plateforme cible, placés dans `BIN_DIR`. - **`node_modules` unique** : Passenger ne crée qu'un seul `node_modules` à la racine. Toute dépendance runtime importée par le frontend doit figurer dans le `dependencies` du `package.json` racine (en plus de `frontend/package.json`). - **Worker** : Passenger ne supervise que l'app Next.js. Le worker est un process à part, maintenu vivant par **pm2** (auto-restart en cas de crash), à la manière de Passenger pour l'app web. ### Étapes de déploiement 1. Uploader les sources (hors `node_modules`, `.env`, `storage/`). 2. Déposer `yt-dlp` et `ffmpeg` dans `BIN_DIR`. 3. Remplir `.env.prod` avec les valeurs de production (non versionné, à créer/mettre à jour manuellement sur le serveur). 4. Via cPanel > "Setup Node.js App" : créer l'app Node une première fois pour que Passenger et le nodevenv soient configurés (pointer sur le dépôt). 5. En SSH, dans l'environnement Node fourni par cPanel (celui activé par le lien "Enter to the virtual environment" de cPanel) : ```bash npm run deploy ``` Ce script (`scripts/deploy.sh`) enchaîne : copie de `.env.prod` vers `.env`, `npm install`, génération du client Prisma, application des migrations en attente (`prisma migrate deploy`), `npm run build`, puis démarrage/redémarrage du worker sous pm2 (`pm2 startOrRestart` + `pm2 save`, pour persister la liste des process en vue d'un `pm2 resurrect` après reboot). 6. Redémarrer l'app Next.js via le bouton "Restart" de cPanel > "Setup Node.js App" pour que Passenger recharge le nouveau build (le script ne pilote pas Passenger, qui est géré en dehors du SSH/nodevenv). 7. Configurer un cron cPanel pour `npm run worker:cleanup` une fois par jour (suppression des fichiers expirés). pm2 gère lui-même le redémarrage du worker en cas de crash ; il n'y a donc plus besoin de cron de supervision dédié. 8. Si l'hébergeur redémarre le serveur, relancer `pm2 resurrect` (ou `npm run worker:pm2:start` si la sauvegarde `pm2 save` n'a pas été faite) pour reprendre le worker. Pour les déploiements suivants, seule l'étape 5 (`npm run deploy`) et l'étape 6 (redémarrage Passenger) sont nécessaires. ## Tests ```bash npm test ``` Tests Jest (environnement Node, transpilation SWC). Les fichiers de test sont dans `**/__tests__/**/*.test.ts`. ## Licence Usage interne — non distribué.