mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-11 17:30:00 +02:00
Builds reproductibles, CI durcie, docs remises à jour
Lockfiles : - pubspec.lock et bin/pubspec.lock versionnés (le .gitignore les excluait via *.lock ; le Dockerfile résolvait des versions fraîches à chaque build, comme son commentaire l'assumait) ; le Dockerfile les COPY désormais, .dockerignore ajusté CI (ci.yml) : - flutter-version 3.38.4 et Dart 3.13.2 épinglés (channel: stable seul fait dériver le SDK et peut casser la CI sans changement du dépôt) - cache pub activé, concurrency: cancel-in-progress Publication (docker-publish.yml) : - Chaîné sur la CI via workflow_run : l'image :latest n'est publiée qu'après analyze/test/build verts sur main (l'ancien push: [main] tournait en parallèle et pouvait publier une image cassée) ; build du head_sha validé par la CI docker-compose : - Défaut RECORDINGS_PATH: ./data/recordings au lieu du chemin unRAID spécifique à une machine (/mnt/user/Data/Sport) - Variable TZ (défaut Europe/Paris) Docs : - README réécrit : il décrivait une architecture disparue (Hive/ IndexedDB, hachage SHA-256, dhttpd port 8080, --web-renderer html) au lieu de l'état réel (SQLite serveur, bcrypt, binaire natif port 8089, enregistrements, transcodage, CI) - DEPLOYMENT_CHECKLIST.md archivé (6 fichiers cités inexistants, versions de dépendances fausses) - docs/archive/README.md : avertissement que ces documents sont historiques (plusieurs se déclarent « COMPLETE » à tort) Non traité ici : l'épinglage de la release FFmpeg du Dockerfile (l'accès aux releases BtbN est bloqué depuis cet environnement, impossible de vérifier un tag valide) et la suppression du code mort (reportée après le merge des PRs #7/#8/#9 pour éviter les conflits). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015oEu9QayWsw7hCKhenxgVa
This commit is contained in:
12 files changed
+1876
-263
No files matched your search
@@ -8,7 +8,6 @@
|
|||||||
build/
|
build/
|
||||||
bin/.dart_tool
|
bin/.dart_tool
|
||||||
bin/.packages
|
bin/.packages
|
||||||
bin/pubspec.lock
|
|
||||||
ios/
|
ios/
|
||||||
android/
|
android/
|
||||||
windows/
|
windows/
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
|
# Un push qui en suit un autre annule le run précédent : inutile de
|
||||||
|
# consommer un runner pour un commit déjà obsolète.
|
||||||
|
concurrency:
|
||||||
|
group: ci-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
frontend:
|
frontend:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -13,7 +19,13 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
|
# Version épinglée : `channel: stable` seul fait dériver le SDK au
|
||||||
|
# fil du temps (une release Flutter peut casser la CI sans aucun
|
||||||
|
# changement dans le dépôt). Le cache évite de retélécharger SDK et
|
||||||
|
# dépendances pub à chaque run.
|
||||||
|
flutter-version: 3.38.4
|
||||||
channel: stable
|
channel: stable
|
||||||
|
cache: true
|
||||||
- run: flutter pub get
|
- run: flutter pub get
|
||||||
# Infos (pre-existing withOpacity/dart:html deprecations) are not
|
# Infos (pre-existing withOpacity/dart:html deprecations) are not
|
||||||
# fatal; errors and warnings still fail the build.
|
# fatal; errors and warnings still fail the build.
|
||||||
@@ -30,7 +42,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: dart-lang/setup-dart@v1
|
- uses: dart-lang/setup-dart@v1
|
||||||
with:
|
with:
|
||||||
sdk: stable
|
sdk: 3.13.2
|
||||||
- run: dart pub get
|
- run: dart pub get
|
||||||
- run: dart analyze
|
- run: dart analyze
|
||||||
- run: dart test
|
- run: dart test
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
name: Docker Publish
|
name: Docker Publish
|
||||||
|
|
||||||
|
# Chaîné sur la CI : l'image :latest n'est publiée que si analyze/test/build
|
||||||
|
# sont verts sur main. L'ancien déclencheur `push: [main]` tournait en
|
||||||
|
# parallèle de la CI et pouvait publier une image cassée.
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_run:
|
||||||
|
workflows: [CI]
|
||||||
|
types: [completed]
|
||||||
branches: [main]
|
branches: [main]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -11,11 +16,18 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build-and-push:
|
build-and-push:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: >-
|
||||||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
github.event.workflow_run.conclusion == 'success'
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
# Sur workflow_run, github.sha pointe sur le commit du workflow
|
||||||
|
# par défaut : construire exactement le commit validé par la CI.
|
||||||
|
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||||
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
@@ -34,6 +46,6 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
${{ env.IMAGE_NAME }}:latest
|
${{ env.IMAGE_NAME }}:latest
|
||||||
${{ env.IMAGE_NAME }}:${{ github.sha }}
|
${{ env.IMAGE_NAME }}:${{ github.event.workflow_run.head_sha || github.sha }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
@@ -49,4 +49,7 @@ app.*.map.json
|
|||||||
# Hive data (local development)
|
# Hive data (local development)
|
||||||
*.hive
|
*.hive
|
||||||
*.lock
|
*.lock
|
||||||
|
# Les lockfiles pub sont versionnés : sans eux, chaque build Docker/CI
|
||||||
|
# résout des versions différentes (builds non reproductibles).
|
||||||
|
!pubspec.lock
|
||||||
.claude/settings.local.json
|
.claude/settings.local.json
|
||||||
@@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
## Non publié
|
## Non publié
|
||||||
|
|
||||||
|
### 🧰 Qualité / Infra
|
||||||
|
- **Builds reproductibles** : `pubspec.lock` (frontend et backend) désormais versionnés et utilisés par le Dockerfile — chaque build résolvait jusqu'ici des versions fraîches
|
||||||
|
- **CI durcie** : versions Flutter/Dart épinglées, cache pub, annulation des runs obsolètes (`concurrency`) ; `docker-publish` ne publie plus `:latest` qu'après une CI verte sur main (il tournait en parallèle et pouvait publier une image cassée)
|
||||||
|
- **docker-compose** : défaut `RECORDINGS_PATH` porté à `./data/recordings` (l'ancien défaut était un chemin unRAID spécifique à une machine), variable `TZ` ajoutée
|
||||||
|
- **README réécrit** : il décrivait une architecture disparue (Hive/IndexedDB, SHA-256, dhttpd port 8080) — remplacé par l'état réel (SQLite serveur, bcrypt, binaire natif port 8089, enregistrements, CI)
|
||||||
|
- `DEPLOYMENT_CHECKLIST.md` archivé et avertissement ajouté sur `docs/archive/` (plusieurs documents s'y déclarent « COMPLETE » à tort)
|
||||||
|
|
||||||
### 📺 Enregistrements
|
### 📺 Enregistrements
|
||||||
- La liste des enregistrements se met à jour automatiquement : rafraîchissement immédiat dès qu'un enregistrement est créé/arrêté n'importe où dans l'app (guide EPG, modal, widget rapide), et polling en arrière-plan (5 s quand un enregistrement est en cours ou planifié, 20 s sinon) pour suivre les statuts sans clic manuel
|
- La liste des enregistrements se met à jour automatiquement : rafraîchissement immédiat dès qu'un enregistrement est créé/arrêté n'importe où dans l'app (guide EPG, modal, widget rapide), et polling en arrière-plan (5 s quand un enregistrement est en cours ou planifié, 20 s sinon) pour suivre les statuts sans clic manuel
|
||||||
- Indicateur « Suivi auto » avec heure de dernière actualisation dans l'onglet Enregistrements
|
- Indicateur « Suivi auto » avec heure de dernière actualisation dans l'onglet Enregistrements
|
||||||
|
|||||||
+4
-3
@@ -12,9 +12,10 @@ ENV FLUTTER_NO_ANALYTICS=1
|
|||||||
RUN flutter config --enable-web && flutter precache --web
|
RUN flutter config --enable-web && flutter precache --web
|
||||||
|
|
||||||
# 2. Dependency Resolution (ONLY UPDATES IF PUBSPEC CHANGES)
|
# 2. Dependency Resolution (ONLY UPDATES IF PUBSPEC CHANGES)
|
||||||
COPY pubspec.yaml ./
|
# Les lockfiles sont versionnés : le build résout exactement les versions
|
||||||
COPY bin/pubspec.yaml ./bin/
|
# committées au lieu d'en chercher de nouvelles à chaque build.
|
||||||
# Note: No .lock files found locally, so we fetch fresh ones here
|
COPY pubspec.yaml pubspec.lock ./
|
||||||
|
COPY bin/pubspec.yaml bin/pubspec.lock ./bin/
|
||||||
RUN flutter pub get && cd bin && dart pub get
|
RUN flutter pub get && cd bin && dart pub get
|
||||||
|
|
||||||
# 3. Source Code Copy (CHANGES OFTEN)
|
# 3. Source Code Copy (CHANGES OFTEN)
|
||||||
|
|||||||
@@ -1,282 +1,103 @@
|
|||||||
# XtremFlow - IPTV Web Application
|
# XtremFlow — Application Web IPTV
|
||||||
|
|
||||||
High-performance, containerized IPTV Web Application using Flutter Web and Xtream Codes API.
|
Application IPTV auto-hébergée : frontend Flutter Web + serveur Dart natif, empaquetés dans une seule image Docker. Se connecte à un abonnement Xtream Codes et ajoute le magnétoscope (enregistrements planifiés, season passes), l'EPG avec repli XMLTV, et le transcodage FFmpeg à la demande.
|
||||||
|
|
||||||
## Features
|
## Fonctionnalités
|
||||||
|
|
||||||
✅ **Local Authentication System**
|
- **Live TV, Films, Séries** : catalogues Xtream avec catégories, recherche, favoris, reprise de lecture
|
||||||
- Default admin user (`admin`/`admin`)
|
- **Guide TV (EPG)** : panneau de l'abonné en priorité, repli automatique sur un dump XMLTV quand le panneau est figé
|
||||||
- Secure salt-based password hashing (SHA-256)
|
- **Enregistrements TV** : planification depuis le guide, capture FFmpeg (`-c copy`), reprise après coupure amont ou redémarrage du serveur, fusion automatique des parties
|
||||||
- No public signup - private app only
|
- **Season Passes** : enregistrement automatique de toutes les diffusions d'une émission (scan EPG toutes les 4 h)
|
||||||
|
- **Transcodage à la demande** : `source | high | medium | low` (live et VOD), `source` = zéro transcodage ; NVENC optionnel
|
||||||
|
- **Multi-utilisateurs** : comptes locaux (bcrypt), playlists par utilisateur, panneau d'administration
|
||||||
|
|
||||||
✅ **Multi-Playlist Management**
|
## Stack
|
||||||
- Centralized Xtream credentials management
|
|
||||||
- Playlist assignment to users
|
|
||||||
- Easy switching between playlists
|
|
||||||
|
|
||||||
✅ **High-Performance Dashboard (60fps)**
|
| Couche | Techno |
|
||||||
- Category-based pagination (100 items/page for Live TV, 50 for Movies)
|
|---|---|
|
||||||
- Lazy loading with `ListView.builder` / `GridView.builder`
|
| Frontend | Flutter Web (Riverpod, GoRouter), players HTML (hls.js / mpegts.js vendorisés) |
|
||||||
- Image caching with `cached_network_image`
|
| Backend | Dart compilé en natif (`dart compile exe`), shelf |
|
||||||
|
| Base | SQLite côté serveur (`/app/data/xtremflow.db`) |
|
||||||
|
| Capture/Transcodage | FFmpeg (build BtbN, NVENC inclus) |
|
||||||
|
| Conteneur | Debian slim multi-stage, port **8089** |
|
||||||
|
|
||||||
✅ **Live TV with EPG**
|
## Démarrage rapide (Docker)
|
||||||
- Electronic Program Guide (EPG) overlay
|
|
||||||
- "Now & Next" program display
|
|
||||||
- Real-time progress bar
|
|
||||||
|
|
||||||
✅ **VOD & Series**
|
|
||||||
- Movies and Series organized by categories
|
|
||||||
- Grid layout with posters
|
|
||||||
- Optimized ratings display (1 decimal place)
|
|
||||||
|
|
||||||
✅ **Docker Deployment**
|
|
||||||
- Multi-stage build with Flutter and Dart
|
|
||||||
- Custom Dart Server (`bin/server.dart`)
|
|
||||||
- **FFmpeg Transcoding** for mobile compatibility
|
|
||||||
- **Cache Management** system for temporary files
|
|
||||||
- External network support (`nginx_default`)
|
|
||||||
|
|
||||||
## Tech Stack
|
|
||||||
|
|
||||||
- **Framework**: Flutter Web
|
|
||||||
- **State Management**: Riverpod
|
|
||||||
- **Local Database**: Hive (Web IndexedDB) with AES encryption
|
|
||||||
- **Networking**: Dio with cache interceptors
|
|
||||||
- **Routing**: GoRouter with auth guards
|
|
||||||
- **Video Player**: `video_player` + `chewie`
|
|
||||||
- **UI**: Google Fonts, Material Design 3
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- Docker & Docker Compose
|
|
||||||
- Existing `nginx_default` network (for reverse proxy routing)
|
|
||||||
- Flutter SDK (for local development only)
|
|
||||||
|
|
||||||
## Quick Start (Docker)
|
|
||||||
|
|
||||||
### 1. Build the Docker image
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose build
|
docker-compose up -d --build
|
||||||
|
# Application sur http://localhost:8089
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Start the container
|
Au premier démarrage, un compte `admin` est créé avec un **mot de passe aléatoire affiché une seule fois dans les logs** (`docker logs xtremflow`), sauf si `ADMIN_INITIAL_PASSWORD` est défini. Changez-le après la première connexion.
|
||||||
|
|
||||||
```bash
|
### Variables d'environnement (docker-compose.yml)
|
||||||
docker-compose up -d
|
|
||||||
```
|
| Variable | Défaut | Rôle |
|
||||||
|
|---|---|---|
|
||||||
### 3. Access via reverse proxy
|
| `RECORDINGS_PATH` | `./data/recordings` | Dossier hôte des enregistrements |
|
||||||
|
| `TZ` | `Europe/Paris` | Fuseau du conteneur (les enregistrements sont stockés en UTC) |
|
||||||
Configure your reverse proxy (Nginx/Traefik) to route traffic to:
|
| `MAX_CONCURRENT_RECORDINGS` | `2` | Enregistrements simultanés |
|
||||||
- **Container**: `xtremflow`
|
| `EPG_XMLTV_URLS` | dump FR | Sources XMLTV de repli (vide = aucun appel sortant) |
|
||||||
- **Internal Port**: `8080`
|
| `NVIDIA_GPU` | `false` | Transcodage NVENC |
|
||||||
- **Network**: `nginx_default`
|
| `ADMIN_INITIAL_PASSWORD` | *(généré)* | Mot de passe initial du compte admin |
|
||||||
|
| `MIN_FREE_DISK_MB` | `500` | Espace libre minimal pour démarrer une capture |
|
||||||
Example Nginx configuration:
|
| `RECORDINGS_QUOTA_GB` | `0` (off) | Quota du dossier d'enregistrements (rotation des plus anciens terminés) |
|
||||||
|
| `TRUSTED_PROXIES` | loopback + RFC1918 | IPs de reverse proxy dont `X-Forwarded-For` est honoré |
|
||||||
```nginx
|
|
||||||
location /iptv {
|
## Développement local
|
||||||
proxy_pass http://xtremflow:8080;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Login
|
|
||||||
|
|
||||||
- **URL**: `http://your-domain/iptv`
|
|
||||||
- **Default Credentials**:
|
|
||||||
- Username: `admin`
|
|
||||||
- Password: `admin`
|
|
||||||
|
|
||||||
⚠️ **Change the admin password immediately after first login!**
|
|
||||||
|
|
||||||
## Local Development
|
|
||||||
|
|
||||||
### Install dependencies
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Frontend
|
||||||
flutter pub get
|
flutter pub get
|
||||||
|
flutter analyze && flutter test
|
||||||
|
flutter run -d chrome # nécessite le backend lancé pour les routes /api
|
||||||
|
|
||||||
|
# Backend
|
||||||
|
cd bin
|
||||||
|
dart pub get
|
||||||
|
dart analyze && dart test
|
||||||
|
dart run server.dart --port 8089 --path ../build/web
|
||||||
```
|
```
|
||||||
|
|
||||||
### Generate Hive adapters (if modified)
|
Le build Windows natif est documenté dans `BUILD.md`.
|
||||||
|
|
||||||
```bash
|
## Structure du projet
|
||||||
flutter pub run build_runner build --delete-conflicting-outputs
|
|
||||||
```
|
|
||||||
|
|
||||||
### Run web app
|
|
||||||
|
|
||||||
```bash
|
|
||||||
flutter run -d chrome
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
lib/
|
bin/ Serveur Dart
|
||||||
├── core/
|
├── server.dart Point d'entrée, routage, arrêt gracieux
|
||||||
│ ├── database/
|
├── api/ Handlers HTTP (auth, playlists, recordings, EPG, proxy…)
|
||||||
│ │ └── hive_service.dart # Hive initialization & encryption
|
├── services/ Scheduler d'enregistrement, sessions FFmpeg, XMLTV
|
||||||
│ ├── models/
|
├── database/ SQLite (schéma, migrations)
|
||||||
│ │ ├── app_user.dart # User model (Hive)
|
├── middleware/ Auth (session), sécurité (rate limit, honeypot, logs redactés)
|
||||||
│ │ ├── playlist_config.dart # Playlist credentials (Hive)
|
└── test/ Tests backend (dart test)
|
||||||
│ │ └── iptv_models.dart # Channel, VOD, Series, EPG models
|
|
||||||
│ ├── router/
|
lib/ Frontend Flutter
|
||||||
│ │ └── app_router.dart # GoRouter configuration
|
├── core/ Modèles, thème, router, clients API
|
||||||
│ └── utils/
|
├── features/ auth / admin / iptv (desktop)
|
||||||
│ └── crypto_utils.dart # Password hashing utilities
|
└── mobile/ Variantes d'écrans mobiles
|
||||||
├── features/
|
|
||||||
│ ├── auth/
|
web/ Players HTML + libs vendorisées (hls.js, mpegts.js)
|
||||||
│ │ ├── providers/
|
|
||||||
│ │ │ └── auth_provider.dart # Authentication state
|
|
||||||
│ │ └── screens/
|
|
||||||
│ │ └── login_screen.dart
|
|
||||||
│ ├── admin/
|
|
||||||
│ │ └── screens/
|
|
||||||
│ │ └── admin_panel.dart # User & Playlist CRUD
|
|
||||||
│ └── iptv/
|
|
||||||
│ ├── services/
|
|
||||||
│ │ └── xtream_service.dart # Xtream API client
|
|
||||||
│ ├── providers/
|
|
||||||
│ │ └── xtream_provider.dart # Riverpod providers
|
|
||||||
│ ├── screens/
|
|
||||||
│ │ └── player_screen.dart # Video player
|
|
||||||
│ └── widgets/
|
|
||||||
│ ├── live_tv_tab.dart # Live TV with pagination
|
|
||||||
│ ├── movies_tab.dart # Movies grid
|
|
||||||
│ ├── series_tab.dart # Series grid
|
|
||||||
│ └── epg_overlay.dart # EPG display
|
|
||||||
└── main.dart
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Security Features
|
## Sécurité
|
||||||
|
|
||||||
### Password Storage
|
- Mots de passe **bcrypt** (migration lazy depuis les anciens hashes au login)
|
||||||
- **Algorithm**: SHA-256 with random UUID-based salt
|
- Les credentials Xtream ne quittent jamais le serveur : passerelle `/api/xtream-api` et proxy `/api/xtream` (authentifié par session) avec injection côté serveur
|
||||||
- **Format**: `salt:hash` (stored in Hive)
|
- Redaction des credentials dans tous les logs ; anti-SSRF avec revalidation des redirections
|
||||||
- **Legacy Support**: Fallback to unsalted comparison for migration
|
- Cookie de session HttpOnly ; rate limiting global + limite de tentatives de login par IP
|
||||||
|
|
||||||
### Database Encryption
|
## CI / Publication
|
||||||
- **Hive AES Cipher** (256-bit key)
|
|
||||||
- Key stored in `FlutterSecureStorage`
|
|
||||||
- Automatic key generation on first run
|
|
||||||
|
|
||||||
### Authentication Flow
|
`ci.yml` (analyze + tests + build web/backend) tourne sur chaque PR et push main ; `docker-publish.yml` publie `ghcr.io/r0m1k3/xtremflow:latest` **uniquement après une CI verte** sur main.
|
||||||
1. User enters credentials
|
|
||||||
2. System retrieves stored hash
|
|
||||||
3. Input password is hashed with same salt
|
|
||||||
4. Constant-time comparison prevents timing attacks
|
|
||||||
|
|
||||||
## Performance Optimizations
|
## Dépannage
|
||||||
|
|
||||||
### Memory Management (20k+ channels)
|
- **Logs** : `docker logs xtremflow` (les URLs y sont redactées)
|
||||||
- **Grouping**: Channels organized by category
|
- **Mot de passe admin perdu** : supprimer le volume `xtremflow-data` recrée la base et affiche un nouveau mot de passe (⚠ efface utilisateurs et historique d'enregistrements)
|
||||||
- **Pagination**: 100 items per page (Live TV), 50 per page (Movies)
|
- **EPG vide** : vérifier `EPG_XMLTV_URLS` et que la chaîne a un `epg_channel_id` ; l'en-tête `X-Epg-Source` des réponses `/api/epg/<id>` indique la source utilisée
|
||||||
- **Lazy Loading**: Only render visible items
|
- **Enregistrement échoué** : bouton « Logs » sur la ligne de l'enregistrement ; la raison (`error_reason`) est affichée sous le titre
|
||||||
- **Image Caching**: Disk/memory cache with `cached_network_image`
|
|
||||||
|
|
||||||
### Network Optimization
|
## Licence
|
||||||
- **Dio Cache Interceptor**: 1-hour cache for API responses
|
|
||||||
- **EPG Cache**: 5-minute refresh for program data
|
|
||||||
- **Hive Disk Store**: Persistent cache across sessions
|
|
||||||
|
|
||||||
### Rendering (60fps Target)
|
Propriétaire — usage privé uniquement.
|
||||||
- `ListView.builder` with fixed `itemExtent`
|
|
||||||
- `AutomaticKeepAliveClientMixin` for tab state
|
|
||||||
- Expansion panels for category navigation
|
|
||||||
- Grid with fixed `crossAxisCount` and `childAspectRatio`
|
|
||||||
|
|
||||||
## Xtream API Integration
|
|
||||||
|
|
||||||
### Supported Endpoints
|
|
||||||
|
|
||||||
| Endpoint | Purpose | Caching |
|
|
||||||
|----------|---------|---------|
|
|
||||||
| `player_api.php` | Authentication | 1 hour |
|
|
||||||
| `get_live_streams` | Live TV channels | 1 hour |
|
|
||||||
| `get_vod_streams` | Movies | 1 hour |
|
|
||||||
| `get_series` | Series | 1 hour |
|
|
||||||
| `get_short_epg` | EPG data | 5 minutes |
|
|
||||||
|
|
||||||
### Stream URL Formats
|
|
||||||
|
|
||||||
```dart
|
|
||||||
// Live TV
|
|
||||||
http://[dns]/live/[username]/[password]/[stream_id].m3u8
|
|
||||||
|
|
||||||
// Movies
|
|
||||||
http://[dns]/movie/[username]/[password]/[stream_id].[container_extension]
|
|
||||||
|
|
||||||
// Series
|
|
||||||
http://[dns]/series/[username]/[password]/[stream_id].[container_extension]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Docker Configuration
|
|
||||||
|
|
||||||
### Dockerfile (Multi-Stage)
|
|
||||||
|
|
||||||
**Stage 1: Builder**
|
|
||||||
- Base: `cirrusci/flutter:stable`
|
|
||||||
- Build: `flutter build web --release --web-renderer html`
|
|
||||||
|
|
||||||
**Stage 2: Runtime**
|
|
||||||
- Base: `dart:stable`
|
|
||||||
- Server: `dhttpd --host 0.0.0.0 --port 8080`
|
|
||||||
- Size: ~150MB (compressed)
|
|
||||||
|
|
||||||
### docker-compose.yml
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
iptv-web:
|
|
||||||
build: .
|
|
||||||
container_name: xtremflow
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- nginx_default
|
|
||||||
|
|
||||||
networks:
|
|
||||||
nginx_default:
|
|
||||||
external: true
|
|
||||||
```
|
|
||||||
|
|
||||||
**No port mapping** - Access via reverse proxy only.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Container won't start
|
|
||||||
```bash
|
|
||||||
# Check logs
|
|
||||||
docker logs xtremflow
|
|
||||||
|
|
||||||
# Verify network exists
|
|
||||||
docker network ls | grep nginx_default
|
|
||||||
|
|
||||||
# Create network if missing
|
|
||||||
docker network create nginx_default
|
|
||||||
```
|
|
||||||
|
|
||||||
### Login fails with admin/admin
|
|
||||||
- Check Hive database initialization in logs
|
|
||||||
- Verify `HiveService.init()` completed successfully
|
|
||||||
- Default admin is seeded only if `users` box is empty
|
|
||||||
|
|
||||||
### EPG not displaying
|
|
||||||
- EPG is optional and gracefully degrades
|
|
||||||
- Check if Xtream server supports `get_short_epg`
|
|
||||||
- Verify stream has `epg_channel_id`
|
|
||||||
|
|
||||||
### Performance issues (FPS drops)
|
|
||||||
- Reduce `_itemsPerPage` constant (currently 100 for Live TV)
|
|
||||||
- Disable image caching temporarily
|
|
||||||
- Check browser DevTools Performance tab
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Proprietary - Private Use Only
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
For Xtream API documentation, consult your IPTV provider.
|
|
||||||
@@ -0,0 +1,477 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
_fe_analyzer_shared:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: _fe_analyzer_shared
|
||||||
|
sha256: "9a3386eea899815698dd55995277cf7cb8572ee52b399a6edfb7ae2b50e5fc19"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "105.0.0"
|
||||||
|
analyzer:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analyzer
|
||||||
|
sha256: "62993bed6eadbe9596c5c20d5c167e7bc563c5fe266657a04ddeb93bdb84f4c9"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "14.1.0"
|
||||||
|
args:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.0"
|
||||||
|
async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.1"
|
||||||
|
bcrypt:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: bcrypt
|
||||||
|
sha256: "6073a700cbbc59f1d4ab27cd532755e3de5e676c4941f535f351374df849270b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
cli_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_config
|
||||||
|
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.1"
|
||||||
|
convert:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: convert
|
||||||
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
|
coverage:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: coverage
|
||||||
|
sha256: "956a3de0725ca232ad353565a8290d3357592bf4250f6f298a185e2d949c5d3d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.15.1"
|
||||||
|
crypto:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
|
equatable:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: equatable
|
||||||
|
sha256: "3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ffi
|
||||||
|
sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
frontend_server_client:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: frontend_server_client
|
||||||
|
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.0"
|
||||||
|
glob:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: glob
|
||||||
|
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.3"
|
||||||
|
hive:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: hive
|
||||||
|
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.3"
|
||||||
|
http:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.6.0"
|
||||||
|
http_methods:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_methods
|
||||||
|
sha256: "6bccce8f1ec7b5d701e7921dca35e202d425b57e317ba1a37f2638590e29e566"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
http_multi_server:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_multi_server
|
||||||
|
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.2"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: io
|
||||||
|
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.5"
|
||||||
|
logging:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: logging
|
||||||
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.20"
|
||||||
|
meta:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.0"
|
||||||
|
mime:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mime
|
||||||
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
|
node_preamble:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_preamble
|
||||||
|
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
|
package_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_config
|
||||||
|
sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
|
path:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.1"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.2"
|
||||||
|
pool:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pool
|
||||||
|
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.2"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
shelf:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shelf
|
||||||
|
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.2"
|
||||||
|
shelf_packages_handler:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_packages_handler
|
||||||
|
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
shelf_router:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shelf_router
|
||||||
|
sha256: f5e5d492440a7fb165fe1e2e1a623f31f734d3370900070b2b1e0d0428d59864
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.4"
|
||||||
|
shelf_static:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shelf_static
|
||||||
|
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.3"
|
||||||
|
shelf_web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_web_socket
|
||||||
|
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
|
source_map_stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_map_stack_trace
|
||||||
|
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
source_maps:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_maps
|
||||||
|
sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.14"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.10.2"
|
||||||
|
sqlite3:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: sqlite3
|
||||||
|
sha256: "3145bd74dcdb4fd6f5c6dda4d4e4490a8087d7f286a14dee5d37087290f0f8a2"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.9.4"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.12.1"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: test
|
||||||
|
sha256: "0d5ba5602ec3baa28c8ce365e1efc5575969c765f45c554a3e167dc7945b9c30"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.31.2"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
sha256: "475610b2aa23c19687cce2961e44b0cc57cafe220f67c2b80201231b2a07fbe7"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.13"
|
||||||
|
test_core:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_core
|
||||||
|
sha256: a39c204a4fc7a7ccb04a2b985e359fda3cc37e45e0b8ac61c3fb1a05aa832132
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.19"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
uuid:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: "9b129329f58692f6e6578329498a8fe9fbe98f090beb764ffbb8ee2eadd01dcd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.6.0"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "15.3.0"
|
||||||
|
watcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: watcher
|
||||||
|
sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
web_socket_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket_channel
|
||||||
|
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.3"
|
||||||
|
webkit_inspection_protocol:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webkit_inspection_protocol
|
||||||
|
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
xml:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.6.1"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
|
sdks:
|
||||||
|
dart: ">=3.11.0 <4.0.0"
|
||||||
+4
-1
@@ -13,8 +13,11 @@ services:
|
|||||||
# Pour changer: modifiez le chemin avant les deux points ":"
|
# Pour changer: modifiez le chemin avant les deux points ":"
|
||||||
# Exemple Windows : - D:\MesVideos\TV:/app/recordings
|
# Exemple Windows : - D:\MesVideos\TV:/app/recordings
|
||||||
# Exemple Linux : - /mnt/nas/videos:/app/recordings
|
# Exemple Linux : - /mnt/nas/videos:/app/recordings
|
||||||
- ${RECORDINGS_PATH:-/mnt/user/Data/Sport}:/app/recordings
|
- ${RECORDINGS_PATH:-./data/recordings}:/app/recordings
|
||||||
environment:
|
environment:
|
||||||
|
# Fuseau horaire du conteneur (affichage des logs ; les enregistrements
|
||||||
|
# sont stockés en UTC quoi qu'il arrive)
|
||||||
|
- TZ=${TZ:-Europe/Paris}
|
||||||
# Origine externe autorisée pour CORS (optionnel — l'app est servie
|
# Origine externe autorisée pour CORS (optionnel — l'app est servie
|
||||||
# same-origin, ne définir que si un autre domaine doit appeler l'API)
|
# same-origin, ne définir que si un autre domaine doit appeler l'API)
|
||||||
- ALLOWED_ORIGIN=${ALLOWED_ORIGIN:-}
|
- ALLOWED_ORIGIN=${ALLOWED_ORIGIN:-}
|
||||||
|
|||||||
File renamed without changes.
@@ -0,0 +1,12 @@
|
|||||||
|
# Archives — documents historiques
|
||||||
|
|
||||||
|
⚠️ **Les documents de ce dossier sont historiques et ne décrivent pas l'état actuel du code.**
|
||||||
|
|
||||||
|
Ils datent de phases de conception ou de refontes antérieures. Plusieurs se déclarent « COMPLETE » ou « production-ready » alors que le travail décrit n'a jamais été intégré (ou a été remplacé depuis) :
|
||||||
|
|
||||||
|
- `RECORDING_SYSTEM_UPGRADE.txt` — décrit un remplacement du scheduler par `SimpleRecorder` qui n'a jamais été branché ; le système réel est `bin/services/recording_scheduler.dart`.
|
||||||
|
- `THEME_REDESIGN_SUMMARY.md` — la « Phase 4: Integration » n'a pas eu lieu ; les widgets qu'il liste n'existent plus.
|
||||||
|
- `ANALYSIS_AND_IMPROVEMENTS.md` — plan d'améliorations dont une partie seulement a été réalisée.
|
||||||
|
- `DEPLOYMENT_CHECKLIST.md` — référence des fichiers et versions de dépendances qui n'ont jamais existé dans le dépôt.
|
||||||
|
|
||||||
|
Pour l'état actuel du projet, se référer au `README.md` racine et au `CHANGELOG.md`.
|
||||||
+1266
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user