NewTube/README.md

291 lines
10 KiB
Markdown
Raw Permalink 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.

# NewTube — Votre hub vidéo multi-plateformes 🎬🌐
Agrégez, explorez et regardez des vidéos depuis
- **YouTube** 🔴
- **Dailymotion** 🔵
- **Twitch** 🟣
- **PeerTube** 🟢 (multi-instances)
- **Odysee** 🟡
- **Rumble** 🟠
---
## ✨ Pourquoi NewTube ? (Objectifs clés)
* 🔎 **Recherche unifiée & tendances** : un seul champ de recherche, des sections par fournisseur, filtres cohérents.
* 🧭 **Navigation claire** : thèmes (Trending, Live, Gaming, News…), onglets Shorts, pages Playlists/History/Liked.
* 👥 **Multi-utilisateur** : playlists **publiques/privées**, préférences, région/qualité par défaut.
* ⚙️ **Prod-ready** : API Node/Express, SQLite intégré, rate-limit, logs, tests ciblés.
* 📦 **Ops friendly** : image Docker, script `maj.sh`, variables denv, **astuces `daemon.json`** pour registres HTTP.
---
## 🧩 Stack
* 🅰️ **Angular 20** (standalone), **RxJS**, **TailwindCSS**
* 🟩 **Node/Express** (sert `dist/` + API)
* 🐳 **Docker/Compose** (déploiement)
* 💾 **SQLite** (par défaut) simple, portable
---
## 🎥 Fournisseurs supportés
| Plateforme | Recherche | Lecture | Shorts | Live | Playlists\* |
| ----------------------------- | :-------: | :-----: | :----: | :--: | :---------: |
| YouTube 🔴 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Dailymotion 🔵 | ✅ | ✅ | ⏳ | ✅ | ⏳ |
| Twitch 🟣 | ✅ | ✅ | N/A | ✅ | ⏳ |
| PeerTube 🟢 (multi-instances) | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
| Odysee 🟡 | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
| Rumble 🟠 | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
\* Playlists = intégration locale NewTube (création/gestion); la synchro native dépend de lAPI publique de chaque fournisseur.
---
## 🖥️ Fonctionnalités (vue densemble)
* 🧭 **Accueil “Tendances & Viral”** par fournisseurs
* 🧩 **Thèmes** : Trending, Live, Gaming, Sports, News, Finance, Tech, Science, Health, Music, Podcasts, Movies/TV, Education, Travel, Food, DIY, Auto…
* 🎯 **Shorts** : affichage dédié (séparé des vidéos longues)
* ❤️ **Liked videos** avec recherche serveur
* 🕘 **History** (recherches + visionnage)
* 📚 **Playlists** publiques/privées (CRUD, compteurs, dates MAJ)
* 🔐 **Auth légère** (JWT), **rate-limit** API
* ⚙️ **Préférences** : langue, thème (système / dark / light / blue / black), région, qualité par défaut
* 🧩 **PeerTube multi-instances** : activer/désactiver, choisir linstance active
---
## 🗂️ Structure du repo
* `docker-compose/`
* `docker-compose.yml` — service `newtube` (image, ports, env, volumes, restart)
* `.env.example` — modèle denvironnement
* `maj.sh`**pull** image + **restart** stack
* `init.sh` — init des dossiers/volumes & `.env`
* `docker/`
* `Dockerfile` — build Node/Express (sert `dist/` + API)
* `scripts/env-dump.sh` — génère `assets/config.js` depuis lenv (option NGINX)
* `config/nginx.conf` — exemple (si variante NGINX)
* `server/`
* `index.mjs` — routes API, statiques `dist/`, downloads
* `db.mjs` — SQLite + migrations légères
* `tests/playlist_visibility.test.mjs` — tests playlists
* `db/``schema.sql` + `migrations/`
* `assets/``config.local.example.js`
* `src/`, `app/`, `public/` — front Angular
* `package.json` — scripts (`dev`, `build`, `api`, `api:watch`, `test:playlists`)
---
## 🧱 Prérequis
* 🐧 Linux (recommandé) / macOS / Windows (WSL2 ok)
* 🐳 Docker Engine ≥ 24, Compose v2
* 🟩 Node.js ≥ 20 (dev local)
* 🔐 Accès au registre dimages (ex. `docker-registry.dev.home:5000`)
---
## 🚀 Installation
### Option A — Docker (recommandé)
```bash
cp docker-compose/.env.example docker-compose/.env
# Éditez docker-compose/.env (hostnames, clés API, secrets…)
cd docker-compose
docker compose up -d
```
Application : [http://localhost:8080](http://localhost:8080) (mappage `8080:4000`)
### Option B — Dev local
```bash
npm install
cp assets/config.local.example.js assets/config.local.js # (optionnel)
npm run dev # front + api dev proxy
# API seule :
npm run api
npm run api:watch
# Build prod :
npm run build
```
---
## 🔁 Déploiement & mises à jour (`maj.sh`)
```bash
chmod +x docker-compose/maj.sh
./docker-compose/maj.sh
```
Ce script fait :
1. `docker image pull <registre>/newtube-angular:latest`
2. `docker compose down`
3. `docker compose up -d`
**Vérifications** : `docker compose ps`, `docker logs newtube --tail=200`, `curl -I http://localhost:8080`
---
## 🧰 Astuce Ops — `Docker /etc/docker/daemon.json` (registres HTTP/insecure)
> À configurer **sur la machine qui exécute** `docker compose` / `maj.sh`.
```bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'JSON'
{
"insecure-registries": ["docker-registry.dev.home:5000"],
"registry-mirrors": [],
"debug": false
}
JSON
sudo systemctl daemon-reload
sudo systemctl restart docker
docker info | grep -i registry
```
Ajoutez au besoin `log-driver`, `log-opts`, `default-address-pools`, etc.
---
## 🔐 Variables denvironnement (exemples)
**Service / compose**
* `NGINX_HOSTNAME`, `DIR_NEWTUBE`, `TZ`
**App / serveur**
* `PORT` (4000), `NODE_ENV`, `JWT_SECRET`
* `ACCESS_TTL_MIN`, `REFRESH_TTL_DAYS`, `REMEMBER_TTL_DAYS`
* `YT_CACHE_TTL_MS`
* **Clés API** : `GEMINI_API_KEY`, `YOUTUBE_API_KEY` ou `YOUTUBE_API_KEYS` (CSV), `VIMEO_ACCESS_TOKEN`, `TWITCH_CLIENT_ID`, `TWITCH_CLIENT_SECRET`
* `NEWTUBE_DB_FILE` (chemin SQLite alternatif)
> Voir `docker-compose/.env.example` pour un point de départ.
---
## 🩺 Troubleshooting (rapide)
* 🧾 **Certif/registre** : `x509… unknown authority` → configurez `daemon.json` (ci-dessus) puis `systemctl restart docker`
* 🔌 **Port 8080 occupé** : changez le mappage dans `docker-compose.yml`
* 🗄️ **Permissions volumes** : vérifiez que `DIR_NEWTUBE` existe et est accessible par Docker
* 🧩 **Variables manquantes** : complétez `.env` (clés API, `JWT_SECRET`, etc.)
* 🌐 **CORS en dev** : utilisez le `proxy.conf.json` et `npm run dev`
---
## 🗺️ Roadmap
* ✅ Dist statique + API Node/Express
* ✅ Playlists **publiques/privées** (tests de visibilité)
* ✅ Barre de recherche **Liked videos** (filtrage serveur)
* ✅ PeerTube **multi-instances** (activer/désactiver, set active)
* ✅ Thème (système / dark / light / blue / black)
* ✅ Préférences (langue, thème, région, qualité par défaut)
* ✅ Auth légère (JWT), rate-limit API
* ✅ Navigation par thèmes (Trending, Live, Gaming, News, Finance, Tech, Science, Health, Music, Podcasts, Movies/TV, Education, Travel, Food, DIY, Auto…)
***Abonnements** (routes + DB)
***Tags** & recherche par tags
***Page “Shorts”** unifiée (tous fournisseurs) + badges de durée
***Téléchargements** intégrés (file queue, répertoires, quotas, reprise)
***Import/Export** playlists (JSON / OPML-like)
***Sous-titres & transcripts** (si dispo API; fallback parsing)
***PWA** (installable, offline cache des métadonnées)
***Chromecast / AirPlay**
***Raccourcis clavier** & mode “TV”
***Observabilité** : healthcheck `/healthz`, métriques, page **Admin** (clés OK/KO, logs, versions)
***OAuth** (Google/Twitch) pour import favoris/abonnements
***Cache serveur** configurable (TTL par provider)
***Qualité vidéo** : sélecteur et “auto” intelligent
***Traduction UI** (i18n) élargie
***Theming avancé** (polices, densité, accents)
---
## 🔒 Notes de sécurité
* ❌ Ne **jamais** versionner de secrets réels
* 🔑 Utiliser `.env` hors VCS + restrictions par referer côté fournisseurs
* 🚧 Limiter lexposition publique de lAPI, activer **rate-limit** (déjà en place)
* 🧪 Ajouter des tests e2e/units pour les zones critiques (auth, playlists, downloads)
---
## 🤝 Contribuer
Issues & PR bienvenues ! Proposez des connecteurs, des règles de parsing plus robustes ou des idées dUX.
Astuce : ouvrez une PR “Draft” tôt pour discussion/feedback.
---
## 📜 Licence
MIT (voir `LICENSE`)
---
> 💡 **Tip produit** : gardez lUX simple — **Thèmes fixes sous le header**, **Shorts séparés**, **CTA clairs** (“View All”, “Add to playlist”), et utilisez les **états vides** (empty states) sur History/Liked/Playlists pour guider lutilisateur.
---
## 🧩 Ajouter un provider en 5 minutes
1) Front — Registry
- Éditez `src/app/core/providers/provider-registry.ts` et ajoutez une entrée `ProviderSpec` avec:
- `id` (ex. `"yt"`), `displayName`, `shortLabel`, `icon`, `colorClass`
- `supports` (search/shorts/live/playlists)
- `buildSearchUrl(q)` (facultatif côté front)
2) Back — Handler
- Créez un fichier `server/providers/<provider>.mjs` qui exporte `default` avec:
- `id`, `label`
- `async search(q, { limit, page })``Promise<Suggestion[]>`
- Enregistrez-le dans `server/providers/registry.mjs` pour être éligible au fanout `/api/search`.
3) API — Recherche multiproviders
- Lendpoint `GET /api/search?q=...&providers=yt,dm,ru&limit=...` valide les providers et déclenche les recherches en parallèle (timeouts), puis retourne:
```json
{
"q": "documentary",
"providers": ["yt","dm","ru"],
"groups": {
"yt": [{ "title": "...", "id": "...", "duration": 192, "isShort": false }],
"dm": [],
"ru": [{ "title": "...", "id": "...", "isShort": true }]
}
}
```
4) UI — Sélecteur & Chips
- Le `SearchBoxComponent` (standalone) rend les chips `All / YT / DM / TW / PT / OD / RU` + menu rapide `@` (ProviderPicker).
- Le composant émet `(submitted)` avec `{ q, providers }` et met à jour `SearchService` (RxJS state) pour lappel API.
5) Deeplink
- Les URLs du type `?q=…&providers=yt,ru` relancent la même recherche. Assurez-vous de propager le paramètre `providers` lors des navigations.
6) Tests (à compléter)
- Unit: parsing `@yt` dans linput, toggle ProviderPicker, composition de `SearchService`.
- e2e: `@yt + query` → résultats uniquement YouTube; chips `YT+DM` → sections YT/DM visibles; deeplink restauré.
Astuce: lajout dun provider ne nécessite pas de modifier les composants — il suffit dajouter une entrée dans le registry front + un handler API.