msansm1/rss-podcast-dlpublic Fork
⑂ f89a2b8
Commits
⬇ Clone ▾
git clone https://git.rickub.com/msansm1/rss-podcast-dl.git
git clone ssh://git@rickub.com/msansm1/rss-podcast-dl.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

init specs

msansm1 committed 2026-07-03T21:34:53+02:00 Browse files
f89a2b8
added spec/init-plan.md +348 -0
new file mode 100644
@@ -0,0 +1,348 @@
1+# RSS Podcast Downloader - Plan de Développement
2+
3+## 1. Vue d'ensemble du Projet
4+
5+### 1.1 Description
6+Application de bureau en Rust utilisant le framework **egui** pour télécharger automatiquement des épisodes de podcasts à partir de flux RSS. L'application permet à l'utilisateur de gérer plusieurs flux, de synchroniser les nouveaux épisodes et de les télécharger dans des dossiers dédiés.
7+
8+### 1.2 Fonctionnalités Principales
9+- Ajout/suppression/édition de flux RSS
10+- Synchronisation manuelle des flux
11+- Téléchargement des nouveaux épisodes
12+- Stockage local de la configuration
13+- Interface graphique intuitive avec egui
14+
15+---
16+
17+## 2. Stack Technique
18+
19+| Composant | Technologie | Rôle |
20+|-----------|-------------|------|
21+| Langage | Rust (edition 2021) | Langage principal |
22+| UI | egui 0.24+ | Framework d'interface graphique |
23+| Parsing RSS | rss (crate) | Lecture des flux RSS/Atom |
24+| HTTP | reqwest | Requêtes HTTP pour téléchargements |
25+| Async | tokio | Gestion asynchrone |
26+| Sérialisation | serde + serde_json | Sauvegarde/restauration des flux |
27+| Date/Heure | chrono | Gestion des timestamps |
28+| Fichiers | std::fs + std::path | Gestion du système de fichiers |
29+| Logging | log + env_logger | Journalisation |
30+
31+---
32+
33+## 3. Architecture du Projet
34+
35+### 3.1 Structure des Fichiers
36+
37+```
38+rss-podcast-dl-egui/
39+├── Cargo.toml # Dépendances et métadonnées
40+├── src/
41+│ ├── main.rs # Point d'entrée de l'application
42+│ ├── app.rs # Structure principale de l'application egui
43+│ ├── config/
44+│ │ ├── mod.rs # Module de configuration
45+│ │ ├── feed.rs # Modèle Feed (flux RSS)
46+│ │ └── storage.rs # Sauvegarde/chargement des flux
47+│ ├── rss/
48+│ │ ├── mod.rs # Module de gestion des flux RSS
49+│ │ ├── parser.rs # Parsing des flux
50+│ │ └── downloader.rs # Téléchargement des épisodes
51+│ └── ui/
52+│ ├── mod.rs # Module UI
53+│ ├── home.rs # Écran d'accueil
54+│ ├── feed_list.rs # Liste des flux
55+│ └── add_feed.rs # Dialogue d'ajout de flux
56+├── spec/
57+│ └── init-plan.md # Ce document
58+└── assets/
59+ └── icon.png # Icône de l'application (optionnel)
60+```
61+
62+### 3.2 Modèles de Données
63+
64+#### 3.2.1 Feed (Flux RSS)
65+```rust
66+#[derive(Debug, Clone, Serialize, Deserialize)]
67+pub struct Feed {
68+ pub id: String, // UUID unique
69+ pub url: String, // URL du flux RSS
70+ pub name: String, // Nom du podcast (extraite du RSS ou personnalisé)
71+ pub download_path: PathBuf, // Chemin de téléchargement
72+ pub last_checked: Option<DateTime<Utc>>, // Dernière vérification
73+ pub last_episode_date: Option<DateTime<Utc>>, // Date du dernier épisode
74+ pub enabled: bool, // Actif/désactivé
75+}
76+```
77+
78+#### 3.2.2 Episode
79+```rust
80+#[derive(Debug, Clone)]
81+pub struct Episode {
82+ pub id: String, // UUID ou guid
83+ pub title: String,
84+ pub description: Option<String>,
85+ pub pub_date: DateTime<Utc>,
86+ pub audio_url: String,
87+ pub audio_filename: String,
88+ pub downloaded: bool,
89+ pub file_size: Option<u64>,
90+}
91+```
92+
93+#### 3.2.3 AppState
94+```rust
95+pub struct AppState {
96+ pub feeds: Vec<Feed>,
97+ pub current_feed: Option<usize>, // Index du feed sélectionné
98+ pub show_add_feed_dialog: bool,
99+ pub sync_in_progress: bool,
100+ pub download_progress: HashMap<String, f32>, // feed_id -> progression 0.0-1.0
101+ pub error_message: Option<String>,
102+ pub info_message: Option<String>,
103+}
104+```
105+
106+---
107+
108+## 4. Phases de Développement
109+
110+### 4.1 Phase 1 : Initialisation du Projet (Durée : 1 jour)
111+
112+**Objectif** : Créer la structure de base du projet Rust avec egui.
113+
114+| Tâche | Priorité | Description | Livrable |
115+|-------|----------|-------------|----------|
116+| 1.1 | High | Créer le projet Rust avec Cargo | `Cargo.toml` |
117+| 1.2 | High | Ajouter les dépendances de base | `Cargo.toml` configuré |
118+| 1.3 | High | Créer la structure de dossiers | Arboorescence complète |
119+| 1.4 | Medium | Configurer le logging | Logging fonctionnel |
120+| 1.5 | Medium | Vérifier la compilation de base | Projet compilable |
121+
122+**Dépendances Cargo.toml** :
123+```toml
124+[package]
125+name = "rss-podcast-dl-egui"
126+version = "0.1.0"
127+edition = "2021"
128+
129+[dependencies]
130+egui = "0.24"
131+eframe = "0.24"
132+serde = { version = "1.0", features = ["derive"] }
133+serde_json = "1.0"
134+reqwest = { version = "0.11", features = ["json"] }
135+tokio = { version = "1.0", features = ["full"] }
136+rss = "2.0"
137+chrono = { version = "0.4", features = ["serde"] }
138+log = "0.4"
139+env_logger = "0.10"
140+uuid = { version = "1.0", features = ["v4", "serde"] }
141+```
142+
143+---
144+
145+### 4.2 Phase 2 : Modèles et Stockage (Durée : 2 jours)
146+
147+**Objectif** : Implémenter les modèles de données et la persistance.
148+
149+| Tâche | Priorité | Description | Livrable |
150+|-------|----------|-------------|----------|
151+| 2.1 | High | Créer le module `config/feed.rs` | Modèle `Feed` |
152+| 2.2 | High | Créer le module `config/storage.rs` | Fonctions de sauvegarde/chargement |
153+| 2.3 | High | Implémenter la sérialisation/désérialisation | JSON compatible |
154+| 2.4 | Medium | Ajouter la validation des URLs | Vérification format URL |
155+| 2.5 | Medium | Créer le fichier de configuration par défaut | `~/.config/rss-podcast-dl/config.json` |
156+
157+**Fonctions clés à implémenter** :
158+```rust
159+// storage.rs
160+pub fn save_feeds(feeds: &[Feed], config_path: &Path) -> Result<(), StorageError>
161+pub fn load_feeds(config_path: &Path) -> Result<Vec<Feed>, StorageError>
162+pub fn get_config_path() -> PathBuf
163+```
164+
165+---
166+
167+### 4.3 Phase 3 : Parsing RSS et Téléchargement (Durée : 3 jours)
168+
169+**Objectif** : Implémenter la récupération et le parsing des flux, ainsi que le téléchargement.
170+
171+| Tâche | Priorité | Description | Livrable |
172+|-------|----------|-------------|----------|
173+| 3.1 | High | Créer `rss/parser.rs` | Parsing des flux RSS/Atom |
174+| 3.2 | High | Extraire les épisodes d'un flux | Liste d'épisodes |
175+| 3.3 | High | Créer `rss/downloader.rs` | Téléchargement des fichiers audio |
176+| 3.4 | High | Implémenter la détection des nouveaux épisodes | Comparaison par date |
177+| 3.5 | Medium | Gérer les erreurs de réseau | Retry et timeout |
178+| 3.6 | Medium | Afficher la progression du téléchargement | Callback de progression |
179+
180+**Fonctions clés** :
181+```rust
182+// parser.rs
183+pub async fn fetch_feed(url: &str) -> Result<RssFeed, ParserError>
184+pub fn extract_episodes(feed: &RssFeed) -> Vec<Episode>
185+
186+// downloader.rs
187+pub async fn download_episode(
188+ episode: &Episode,
189+ download_path: &Path,
190+ progress_callback: Box<dyn Fn(f32) + Send + Sync>,
191+) -> Result<PathBuf, DownloadError>
192+```
193+
194+---
195+
196+### 4.4 Phase 4 : Interface Utilisateur (Durée : 4 jours)
197+
198+**Objectif** : Créer l'interface graphique complète avec egui.
199+
200+| Tâche | Priorité | Description | Livrable |
201+|-------|----------|-------------|----------|
202+| 4.1 | High | Créer la structure de base de l'app egui | `app.rs` + `main.rs` |
203+| 4.2 | High | Implémenter l'écran d'accueil | `ui/home.rs` |
204+| 4.3 | High | Créer la liste des flux avec actions | `ui/feed_list.rs` |
205+| 4.4 | High | Implémenter le dialogue d'ajout de flux | `ui/add_feed.rs` |
206+| 4.5 | Medium | Ajouter les boutons d'action (Ajouter, Synchroniser) | Boutons fonctionnels |
207+| 4.6 | Medium | Afficher les messages d'erreur/info | Notifications UI |
208+| 4.7 | Medium | Ajouter une barre de progression | Visual feedback |
209+| 4.8 | Low | Personnaliser le thème egui | Thème cohérent |
210+
211+**Structure UI** :
212+```
213++------------------------------------------+
214+| RSS Podcast Downloader [⚙️] |
215++------------------------------------------+
216+| |
217+| +----------------------+ |
218+| | [+ Ajouter un flux] | |
219+| +----------------------+ |
220+| |
221+| +----------------------+ |
222+| | [🔄 Synchroniser] | |
223+| +----------------------+ |
224+| |
225+| Liste des flux configurés : |
226+| +------------------------------------+ |
227+| | 🎙️ Le Podcast #1 | |
228+| | URL: https://... | |
229+| | Dossier: ~/podcasts/lepodcast | |
230+| | [✏️] [🗑️] [🔄] | |
231+| +------------------------------------+ |
232+| | 🎙️ Tech News | |
233+| | URL: https://... | |
234+| | Dossier: ~/podcasts/tech | |
235+| | [✏️] [🗑️] [🔄] | |
236+| +------------------------------------+ |
237+| |
238+| Statut: Prêt | |
239++------------------------------------------+
240+```
241+
242+---
243+
244+### 4.5 Phase 5 : Synchronisation (Durée : 2 jours)
245+
246+**Objectif** : Implémenter la logique de synchronisation complète.
247+
248+| Tâche | Priorité | Description | Livrable |
249+|-------|----------|-------------|----------|
250+| 5.1 | High | Implémenter la synchronisation d'un flux | Vérification des nouveaux épisodes |
251+| 5.2 | High | Synchroniser tous les flux | Boucle sur tous les flux |
252+| 5.3 | High | Mettre à jour le `last_checked` | Persistance de l'état |
253+| 5.4 | Medium | Gérer les conflits de noms de fichiers | Nom unique |
254+| 5.5 | Medium | Ajouter un bouton "Tout synchroniser" | Action globale |
255+| 5.6 | Low | Synchronisation automatique (optionnelle) | Minuterie |
256+
257+**Logique de synchronisation** :
258+```
259+1. Pour chaque flux activé :
260+ a. Récupérer le flux RSS
261+ b. Extraire les épisodes
262+ c. Comparer avec last_episode_date
263+ d. Télécharger les nouveaux épisodes
264+ e. Mettre à jour last_checked et last_episode_date
265+```
266+
267+---
268+
269+### 4.6 Phase 6 : Intégration et Tests (Durée : 2 jours)
270+
271+**Objectif** : Intégrer tous les composants et tester l'application.
272+
273+| Tâche | Priorité | Description | Livrable |
274+|-------|----------|-------------|----------|
275+| 6.1 | High | Connecter UI ↔ Logique métier | Événements gérés |
276+| 6.2 | High | Tester l'ajout de flux | Flux persisté |
277+| 6.3 | High | Tester la synchronisation | Épisodes téléchargés |
278+| 6.4 | High | Tester la suppression de flux | Flux supprimé |
279+| 6.5 | Medium | Gérer les erreurs gracefully | Pas de crash |
280+| 6.6 | Medium | Optimiser les performances | Réactivité UI |
281+| 6.7 | Low | Ajouter des logs détaillés | Debug facilitée |
282+
283+---
284+
285+### 4.7 Phase 7 : Finalisation (Durée : 1 jour)
286+
287+**Objectif** : Préparer l'application pour la distribution.
288+
289+| Tâche | Priorité | Description | Livrable |
290+|-------|----------|-------------|----------|
291+| 7.1 | Medium | Ajouter une icône | `assets/icon.png` |
292+| 7.2 | Medium | Configurer le nom et version | `Cargo.toml` |
293+| 7.3 | Medium | Créer un README | Documentation |
294+| 7.4 | Low | Builder pour Windows/Linux | Binaires |
295+| 7.5 | Low | Nettoyer le code | Code propre |
296+
297+---
298+
299+## 5. Calendrier Global
300+
301+| Phase | Durée | Dates Estimées | Statut |
302+|-------|-------|----------------|--------|
303+| Phase 1 | 1 jour | J1 | ⬜ |
304+| Phase 2 | 2 jours | J2-J3 | ⬜ |
305+| Phase 3 | 3 jours | J4-J6 | ⬜ |
306+| Phase 4 | 4 jours | J7-J10 | ⬜ |
307+| Phase 5 | 2 jours | J11-J12 | ⬜ |
308+| Phase 6 | 2 jours | J13-J14 | ⬜ |
309+| Phase 7 | 1 jour | J15 | ⬜ |
310+| **Total** | **15 jours** | | |
311+
312+---
313+
314+## 6. Points d'Attention
315+
316+### 6.1 Risques Identifiés
317+
318+| Risque | Probabilité | Impact | Mitigation |
319+|--------|-------------|--------|------------|
320+| Problème de compatibilité avec egui 0.24 | Moyenne | Élevé | Vérifier la documentation et exemples |
321+| Parsing de flux RSS non-standards | Élevée | Moyen | Utiliser la crate `rss` robuste |
322+| Gestion des chemins Windows/Linux | Moyenne | Moyen | Utiliser `PathBuf` et `std::path` |
323+| Performance avec beaucoup de flux | Faible | Moyen | Async/await + tokio |
324+
325+### 6.2 Contraintes Techniques
326+- L'application doit fonctionner sans serveur (standalone)
327+- Les flux doivent être stockés localement dans un fichier unique
328+- L'interface doit rester réactive pendant les téléchargements
329+- Les téléchargements doivent être asynchrones
330+
331+### 6.3 Hypothèses
332+- Les flux RSS suivent les standards RSS 2.0 ou Atom
333+- Les URLs des épisodes pointent vers des fichiers audio (MP3, M4A, etc.)
334+- L'utilisateur a les permissions d'écriture dans les dossiers de téléchargement
335+- L'application sera utilisée sur Windows et Linux
336+
337+---
338+
339+## 7. Prochaines Étapes
340+
341+1. **Valider ce plan** avec les parties prenantes
342+2. **Créer le projet Rust** avec la structure initiale
343+3. **Commencer par la Phase 1** : Initialisation du projet
344+4. **Configurer l'environnement** de développement
345+
346+---
347+
348+*Document généré le 03/07/2026 - Version 1.0*
new file mode 100644
@@ -0,0 +1,348 @@
1+# RSS Podcast Downloader - Plan de Développement
2+
3+## 1. Vue d'ensemble du Projet
4+
5+### 1.1 Description
6+Application de bureau en Rust utilisant le framework **egui** pour télécharger automatiquement des épisodes de podcasts à partir de flux RSS. L'application permet à l'utilisateur de gérer plusieurs flux, de synchroniser les nouveaux épisodes et de les télécharger dans des dossiers dédiés.
7+
8+### 1.2 Fonctionnalités Principales
9+- Ajout/suppression/édition de flux RSS
10+- Synchronisation manuelle des flux
11+- Téléchargement des nouveaux épisodes
12+- Stockage local de la configuration
13+- Interface graphique intuitive avec egui
14+
15+---
16+
17+## 2. Stack Technique
18+
19+| Composant | Technologie | Rôle |
20+|-----------|-------------|------|
21+| Langage | Rust (edition 2021) | Langage principal |
22+| UI | egui 0.24+ | Framework d'interface graphique |
23+| Parsing RSS | rss (crate) | Lecture des flux RSS/Atom |
24+| HTTP | reqwest | Requêtes HTTP pour téléchargements |
25+| Async | tokio | Gestion asynchrone |
26+| Sérialisation | serde + serde_json | Sauvegarde/restauration des flux |
27+| Date/Heure | chrono | Gestion des timestamps |
28+| Fichiers | std::fs + std::path | Gestion du système de fichiers |
29+| Logging | log + env_logger | Journalisation |
30+
31+---
32+
33+## 3. Architecture du Projet
34+
35+### 3.1 Structure des Fichiers
36+
37+```
38+rss-podcast-dl-egui/
39+├── Cargo.toml # Dépendances et métadonnées
40+├── src/
41+│ ├── main.rs # Point d'entrée de l'application
42+│ ├── app.rs # Structure principale de l'application egui
43+│ ├── config/
44+│ │ ├── mod.rs # Module de configuration
45+│ │ ├── feed.rs # Modèle Feed (flux RSS)
46+│ │ └── storage.rs # Sauvegarde/chargement des flux
47+│ ├── rss/
48+│ │ ├── mod.rs # Module de gestion des flux RSS
49+│ │ ├── parser.rs # Parsing des flux
50+│ │ └── downloader.rs # Téléchargement des épisodes
51+│ └── ui/
52+│ ├── mod.rs # Module UI
53+│ ├── home.rs # Écran d'accueil
54+│ ├── feed_list.rs # Liste des flux
55+│ └── add_feed.rs # Dialogue d'ajout de flux
56+├── spec/
57+│ └── init-plan.md # Ce document
58+└── assets/
59+ └── icon.png # Icône de l'application (optionnel)
60+```
61+
62+### 3.2 Modèles de Données
63+
64+#### 3.2.1 Feed (Flux RSS)
65+```rust
66+#[derive(Debug, Clone, Serialize, Deserialize)]
67+pub struct Feed {
68+ pub id: String, // UUID unique
69+ pub url: String, // URL du flux RSS
70+ pub name: String, // Nom du podcast (extraite du RSS ou personnalisé)
71+ pub download_path: PathBuf, // Chemin de téléchargement
72+ pub last_checked: Option<DateTime<Utc>>, // Dernière vérification
73+ pub last_episode_date: Option<DateTime<Utc>>, // Date du dernier épisode
74+ pub enabled: bool, // Actif/désactivé
75+}
76+```
77+
78+#### 3.2.2 Episode
79+```rust
80+#[derive(Debug, Clone)]
81+pub struct Episode {
82+ pub id: String, // UUID ou guid
83+ pub title: String,
84+ pub description: Option<String>,
85+ pub pub_date: DateTime<Utc>,
86+ pub audio_url: String,
87+ pub audio_filename: String,
88+ pub downloaded: bool,
89+ pub file_size: Option<u64>,
90+}
91+```
92+
93+#### 3.2.3 AppState
94+```rust
95+pub struct AppState {
96+ pub feeds: Vec<Feed>,
97+ pub current_feed: Option<usize>, // Index du feed sélectionné
98+ pub show_add_feed_dialog: bool,
99+ pub sync_in_progress: bool,
100+ pub download_progress: HashMap<String, f32>, // feed_id -> progression 0.0-1.0
101+ pub error_message: Option<String>,
102+ pub info_message: Option<String>,
103+}
104+```
105+
106+---
107+
108+## 4. Phases de Développement
109+
110+### 4.1 Phase 1 : Initialisation du Projet (Durée : 1 jour)
111+
112+**Objectif** : Créer la structure de base du projet Rust avec egui.
113+
114+| Tâche | Priorité | Description | Livrable |
115+|-------|----------|-------------|----------|
116+| 1.1 | High | Créer le projet Rust avec Cargo | `Cargo.toml` |
117+| 1.2 | High | Ajouter les dépendances de base | `Cargo.toml` configuré |
118+| 1.3 | High | Créer la structure de dossiers | Arboorescence complète |
119+| 1.4 | Medium | Configurer le logging | Logging fonctionnel |
120+| 1.5 | Medium | Vérifier la compilation de base | Projet compilable |
121+
122+**Dépendances Cargo.toml** :
123+```toml
124+[package]
125+name = "rss-podcast-dl-egui"
126+version = "0.1.0"
127+edition = "2021"
128+
129+[dependencies]
130+egui = "0.24"
131+eframe = "0.24"
132+serde = { version = "1.0", features = ["derive"] }
133+serde_json = "1.0"
134+reqwest = { version = "0.11", features = ["json"] }
135+tokio = { version = "1.0", features = ["full"] }
136+rss = "2.0"
137+chrono = { version = "0.4", features = ["serde"] }
138+log = "0.4"
139+env_logger = "0.10"
140+uuid = { version = "1.0", features = ["v4", "serde"] }
141+```
142+
143+---
144+
145+### 4.2 Phase 2 : Modèles et Stockage (Durée : 2 jours)
146+
147+**Objectif** : Implémenter les modèles de données et la persistance.
148+
149+| Tâche | Priorité | Description | Livrable |
150+|-------|----------|-------------|----------|
151+| 2.1 | High | Créer le module `config/feed.rs` | Modèle `Feed` |
152+| 2.2 | High | Créer le module `config/storage.rs` | Fonctions de sauvegarde/chargement |
153+| 2.3 | High | Implémenter la sérialisation/désérialisation | JSON compatible |
154+| 2.4 | Medium | Ajouter la validation des URLs | Vérification format URL |
155+| 2.5 | Medium | Créer le fichier de configuration par défaut | `~/.config/rss-podcast-dl/config.json` |
156+
157+**Fonctions clés à implémenter** :
158+```rust
159+// storage.rs
160+pub fn save_feeds(feeds: &[Feed], config_path: &Path) -> Result<(), StorageError>
161+pub fn load_feeds(config_path: &Path) -> Result<Vec<Feed>, StorageError>
162+pub fn get_config_path() -> PathBuf
163+```
164+
165+---
166+
167+### 4.3 Phase 3 : Parsing RSS et Téléchargement (Durée : 3 jours)
168+
169+**Objectif** : Implémenter la récupération et le parsing des flux, ainsi que le téléchargement.
170+
171+| Tâche | Priorité | Description | Livrable |
172+|-------|----------|-------------|----------|
173+| 3.1 | High | Créer `rss/parser.rs` | Parsing des flux RSS/Atom |
174+| 3.2 | High | Extraire les épisodes d'un flux | Liste d'épisodes |
175+| 3.3 | High | Créer `rss/downloader.rs` | Téléchargement des fichiers audio |
176+| 3.4 | High | Implémenter la détection des nouveaux épisodes | Comparaison par date |
177+| 3.5 | Medium | Gérer les erreurs de réseau | Retry et timeout |
178+| 3.6 | Medium | Afficher la progression du téléchargement | Callback de progression |
179+
180+**Fonctions clés** :
181+```rust
182+// parser.rs
183+pub async fn fetch_feed(url: &str) -> Result<RssFeed, ParserError>
184+pub fn extract_episodes(feed: &RssFeed) -> Vec<Episode>
185+
186+// downloader.rs
187+pub async fn download_episode(
188+ episode: &Episode,
189+ download_path: &Path,
190+ progress_callback: Box<dyn Fn(f32) + Send + Sync>,
191+) -> Result<PathBuf, DownloadError>
192+```
193+
194+---
195+
196+### 4.4 Phase 4 : Interface Utilisateur (Durée : 4 jours)
197+
198+**Objectif** : Créer l'interface graphique complète avec egui.
199+
200+| Tâche | Priorité | Description | Livrable |
201+|-------|----------|-------------|----------|
202+| 4.1 | High | Créer la structure de base de l'app egui | `app.rs` + `main.rs` |
203+| 4.2 | High | Implémenter l'écran d'accueil | `ui/home.rs` |
204+| 4.3 | High | Créer la liste des flux avec actions | `ui/feed_list.rs` |
205+| 4.4 | High | Implémenter le dialogue d'ajout de flux | `ui/add_feed.rs` |
206+| 4.5 | Medium | Ajouter les boutons d'action (Ajouter, Synchroniser) | Boutons fonctionnels |
207+| 4.6 | Medium | Afficher les messages d'erreur/info | Notifications UI |
208+| 4.7 | Medium | Ajouter une barre de progression | Visual feedback |
209+| 4.8 | Low | Personnaliser le thème egui | Thème cohérent |
210+
211+**Structure UI** :
212+```
213++------------------------------------------+
214+| RSS Podcast Downloader [⚙️] |
215++------------------------------------------+
216+| |
217+| +----------------------+ |
218+| | [+ Ajouter un flux] | |
219+| +----------------------+ |
220+| |
221+| +----------------------+ |
222+| | [🔄 Synchroniser] | |
223+| +----------------------+ |
224+| |
225+| Liste des flux configurés : |
226+| +------------------------------------+ |
227+| | 🎙️ Le Podcast #1 | |
228+| | URL: https://... | |
229+| | Dossier: ~/podcasts/lepodcast | |
230+| | [✏️] [🗑️] [🔄] | |
231+| +------------------------------------+ |
232+| | 🎙️ Tech News | |
233+| | URL: https://... | |
234+| | Dossier: ~/podcasts/tech | |
235+| | [✏️] [🗑️] [🔄] | |
236+| +------------------------------------+ |
237+| |
238+| Statut: Prêt | |
239++------------------------------------------+
240+```
241+
242+---
243+
244+### 4.5 Phase 5 : Synchronisation (Durée : 2 jours)
245+
246+**Objectif** : Implémenter la logique de synchronisation complète.
247+
248+| Tâche | Priorité | Description | Livrable |
249+|-------|----------|-------------|----------|
250+| 5.1 | High | Implémenter la synchronisation d'un flux | Vérification des nouveaux épisodes |
251+| 5.2 | High | Synchroniser tous les flux | Boucle sur tous les flux |
252+| 5.3 | High | Mettre à jour le `last_checked` | Persistance de l'état |
253+| 5.4 | Medium | Gérer les conflits de noms de fichiers | Nom unique |
254+| 5.5 | Medium | Ajouter un bouton "Tout synchroniser" | Action globale |
255+| 5.6 | Low | Synchronisation automatique (optionnelle) | Minuterie |
256+
257+**Logique de synchronisation** :
258+```
259+1. Pour chaque flux activé :
260+ a. Récupérer le flux RSS
261+ b. Extraire les épisodes
262+ c. Comparer avec last_episode_date
263+ d. Télécharger les nouveaux épisodes
264+ e. Mettre à jour last_checked et last_episode_date
265+```
266+
267+---
268+
269+### 4.6 Phase 6 : Intégration et Tests (Durée : 2 jours)
270+
271+**Objectif** : Intégrer tous les composants et tester l'application.
272+
273+| Tâche | Priorité | Description | Livrable |
274+|-------|----------|-------------|----------|
275+| 6.1 | High | Connecter UI ↔ Logique métier | Événements gérés |
276+| 6.2 | High | Tester l'ajout de flux | Flux persisté |
277+| 6.3 | High | Tester la synchronisation | Épisodes téléchargés |
278+| 6.4 | High | Tester la suppression de flux | Flux supprimé |
279+| 6.5 | Medium | Gérer les erreurs gracefully | Pas de crash |
280+| 6.6 | Medium | Optimiser les performances | Réactivité UI |
281+| 6.7 | Low | Ajouter des logs détaillés | Debug facilitée |
282+
283+---
284+
285+### 4.7 Phase 7 : Finalisation (Durée : 1 jour)
286+
287+**Objectif** : Préparer l'application pour la distribution.
288+
289+| Tâche | Priorité | Description | Livrable |
290+|-------|----------|-------------|----------|
291+| 7.1 | Medium | Ajouter une icône | `assets/icon.png` |
292+| 7.2 | Medium | Configurer le nom et version | `Cargo.toml` |
293+| 7.3 | Medium | Créer un README | Documentation |
294+| 7.4 | Low | Builder pour Windows/Linux | Binaires |
295+| 7.5 | Low | Nettoyer le code | Code propre |
296+
297+---
298+
299+## 5. Calendrier Global
300+
301+| Phase | Durée | Dates Estimées | Statut |
302+|-------|-------|----------------|--------|
303+| Phase 1 | 1 jour | J1 | ⬜ |
304+| Phase 2 | 2 jours | J2-J3 | ⬜ |
305+| Phase 3 | 3 jours | J4-J6 | ⬜ |
306+| Phase 4 | 4 jours | J7-J10 | ⬜ |
307+| Phase 5 | 2 jours | J11-J12 | ⬜ |
308+| Phase 6 | 2 jours | J13-J14 | ⬜ |
309+| Phase 7 | 1 jour | J15 | ⬜ |
310+| **Total** | **15 jours** | | |
311+
312+---
313+
314+## 6. Points d'Attention
315+
316+### 6.1 Risques Identifiés
317+
318+| Risque | Probabilité | Impact | Mitigation |
319+|--------|-------------|--------|------------|
320+| Problème de compatibilité avec egui 0.24 | Moyenne | Élevé | Vérifier la documentation et exemples |
321+| Parsing de flux RSS non-standards | Élevée | Moyen | Utiliser la crate `rss` robuste |
322+| Gestion des chemins Windows/Linux | Moyenne | Moyen | Utiliser `PathBuf` et `std::path` |
323+| Performance avec beaucoup de flux | Faible | Moyen | Async/await + tokio |
324+
325+### 6.2 Contraintes Techniques
326+- L'application doit fonctionner sans serveur (standalone)
327+- Les flux doivent être stockés localement dans un fichier unique
328+- L'interface doit rester réactive pendant les téléchargements
329+- Les téléchargements doivent être asynchrones
330+
331+### 6.3 Hypothèses
332+- Les flux RSS suivent les standards RSS 2.0 ou Atom
333+- Les URLs des épisodes pointent vers des fichiers audio (MP3, M4A, etc.)
334+- L'utilisateur a les permissions d'écriture dans les dossiers de téléchargement
335+- L'application sera utilisée sur Windows et Linux
336+
337+---
338+
339+## 7. Prochaines Étapes
340+
341+1. **Valider ce plan** avec les parties prenantes
342+2. **Créer le projet Rust** avec la structure initiale
343+3. **Commencer par la Phase 1** : Initialisation du projet
344+4. **Configurer l'environnement** de développement
345+
346+---
347+
348+*Document généré le 03/07/2026 - Version 1.0*
added spec/init-tasks.md +263 -0
new file mode 100644
@@ -0,0 +1,263 @@
1+# RSS Podcast Downloader - Liste Détaillée des Tâches
2+
3+*Version 1.0 - 03/07/2026*
4+*Dérivé de spec/init-plan.md*
5+
6+---
7+
8+## Légende
9+
10+- **ID** : Identifiant unique de la tâche (ex: T1.1)
11+- **Phase** : Phase du plan global (1-7)
12+- **Priorité** : High (H) | Medium (M) | Low (L)
13+- **Durée** : Temps estimé en heures
14+- **Statut** : ⬜ À faire | 🟡 En cours | ✅ Terminé | ❌ Annulé
15+- **Fichiers** : Fichiers concernés par la tâche
16+- **Dépendances** : IDs des tâches requises avant celle-ci
17+
18+---
19+
20+## Phase 1 : Initialisation du Projet
21+
22+### Objectif : Créer la structure de base du projet Rust avec egui
23+
24+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
25+|----|-------|----------|-------|---------|-------------|--------|
26+| T1.1 | Créer le projet Rust avec `cargo init --name rss-podcast-dl-egui` | H | 0.5h | `Cargo.toml`, `src/main.rs` | Aucune | ⬜ |
27+| T1.2 | Configurer `Cargo.toml` avec toutes les dépendances nécessaires | H | 1h | `Cargo.toml` | T1.1 | ⬜ |
28+| T1.3 | Créer la structure de dossiers (`src/config/`, `src/rss/`, `src/ui/`, `spec/`, `assets/`) | H | 0.5h | Structure de dossiers | T1.1 | ⬜ |
29+| T1.4 | Créer les fichiers vides pour chaque module (`mod.rs` dans chaque dossier) | H | 0.5h | `src/config/mod.rs`, `src/rss/mod.rs`, `src/ui/mod.rs` | T1.3 | ⬜ |
30+| T1.5 | Configurer `main.rs` avec le squelette de base eframe | H | 1h | `src/main.rs` | T1.2 | ⬜ |
31+| T1.6 | Initialiser le logging avec `env_logger` dans `main.rs` | M | 0.5h | `src/main.rs` | T1.5 | ⬜ |
32+| T1.7 | Tester la compilation de base avec `cargo check` | M | 0.5h | - | T1.6 | ⬜ |
33+| T1.8 | Vérifier l'exécution avec `cargo run` (fenêtre egui vide) | M | 0.5h | - | T1.7 | ⬜ |
34+
35+**Total Phase 1** : 5 heures
36+
37+---
38+
39+## Phase 2 : Modèles et Stockage
40+
41+### Objectif : Implémenter les modèles de données et la persistance
42+
43+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
44+|----|-------|----------|-------|---------|-------------|--------|
45+| T2.1 | Créer `config/feed.rs` avec la structure `Feed` | H | 1h | `src/config/feed.rs` | T1.3 | ⬜ |
46+| T2.2 | Implémenter `Default`, `Debug`, `Clone`, `Serialize`, `Deserialize` pour `Feed` | H | 1h | `src/config/feed.rs` | T2.1 | ⬜ |
47+| T2.3 | Créer `config/episode.rs` avec la structure `Episode` | H | 1h | `src/config/episode.rs` | T1.3 | ⬜ |
48+| T2.4 | Créer `config/app_state.rs` avec la structure `AppState` | H | 1h | `src/config/app_state.rs` | T1.3 | ⬜ |
49+| T2.5 | Mettre à jour `config/mod.rs` pour exporter les modules | H | 0.5h | `src/config/mod.rs` | T2.1, T2.3, T2.4 | ⬜ |
50+| T2.6 | Créer `config/storage.rs` avec les types d'erreur (`StorageError`) | H | 1h | `src/config/storage.rs` | T2.1 | ⬜ |
51+| T2.7 | Implémenter `get_config_path()` pour déterminer le chemin du fichier de config | H | 1h | `src/config/storage.rs` | T2.6 | ⬜ |
52+| T2.8 | Implémenter `save_feeds(feeds: &[Feed], path: &Path)` | H | 2h | `src/config/storage.rs` | T2.6 | ⬜ |
53+| T2.9 | Implémenter `load_feeds(path: &Path) -> Result<Vec<Feed>, StorageError>` | H | 2h | `src/config/storage.rs` | T2.6 | ⬜ |
54+| T2.10 | Ajouter la validation de l'URL dans `Feed` (méthode `validate_url()`) | M | 1h | `src/config/feed.rs` | T2.1 | ⬜ |
55+| T2.11 | Ajouter la validation du chemin dans `Feed` (méthode `validate_path()`) | M | 1h | `src/config/feed.rs` | T2.1 | ⬜ |
56+| T2.12 | Créer un test unitaire pour `save_feeds` et `load_feeds` | M | 1h | `src/config/storage.rs` | T2.8, T2.9 | ⬜ |
57+
58+**Total Phase 2** : 14 heures (2 jours)
59+
60+---
61+
62+## Phase 3 : Parsing RSS et Téléchargement
63+
64+### Objectif : Implémenter la récupération, le parsing des flux et le téléchargement
65+
66+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
67+|----|-------|----------|-------|---------|-------------|--------|
68+| T3.1 | Créer `rss/parser.rs` avec les types d'erreur (`ParserError`) | H | 1h | `src/rss/parser.rs` | T1.3 | ⬜ |
69+| T3.2 | Implémenter `fetch_feed(url: &str) -> Result<String, ParserError>` (récupération HTTP) | H | 2h | `src/rss/parser.rs` | T3.1 | ⬜ |
70+| T3.3 | Implémenter `parse_rss_content(content: &str) -> Result<RssFeed, ParserError>` | H | 2h | `src/rss/parser.rs` | T3.1 | ⬜ |
71+| T3.4 | Créer `rss/episode_extractor.rs` avec `extract_episodes(feed: &RssFeed) -> Vec<Episode>` | H | 3h | `src/rss/episode_extractor.rs` | T2.3, T3.3 | ⬜ |
72+| T3.5 | Gérer les différents formats (RSS 2.0, Atom) dans l'extraction | H | 2h | `src/rss/episode_extractor.rs` | T3.4 | ⬜ |
73+| T3.6 | Créer `rss/downloader.rs` avec les types d'erreur (`DownloadError`) | H | 1h | `src/rss/downloader.rs` | T1.3 | ⬜ |
74+| T3.7 | Implémenter `download_file(url: &str, dest: &Path) -> Result<(), DownloadError>` | H | 2h | `src/rss/downloader.rs` | T3.6 | ⬜ |
75+| T3.8 | Implémenter `download_episode(episode: &Episode, download_path: &Path, progress_callback: Box<dyn Fn(f32)>)` | H | 3h | `src/rss/downloader.rs` | T3.7 | ⬜ |
76+| T3.9 | Gérer le timeout et retry pour les requêtes HTTP | M | 2h | `src/rss/parser.rs`, `src/rss/downloader.rs` | T3.2, T3.7 | ⬜ |
77+| T3.10 | Créer un système de cache pour éviter de re-télécharger les mêmes épisodes | M | 2h | `src/rss/downloader.rs` | T3.8 | ⬜ |
78+| T3.11 | Mettre à jour `rss/mod.rs` pour exporter les modules | H | 0.5h | `src/rss/mod.rs` | T3.1, T3.4, T3.6 | ⬜ |
79+
80+**Total Phase 3** : 23 heures (3 jours)
81+
82+---
83+
84+## Phase 4 : Interface Utilisateur
85+
86+### Objectif : Créer l'interface graphique complète avec egui
87+
88+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
89+|----|-------|----------|-------|---------|-------------|--------|
90+| T4.1 | Créer `app.rs` avec la structure principale de l'application | H | 2h | `src/app.rs` | T1.5, T2.4 | ⬜ |
91+| T4.2 | Mettre à jour `main.rs` pour utiliser `app.rs` | H | 1h | `src/main.rs` | T4.1 | ⬜ |
92+| T4.3 | Créer `ui/mod.rs` pour exporter les composants UI | H | 0.5h | `src/ui/mod.rs` | T1.3 | ⬜ |
93+| T4.4 | Créer `ui/home.rs` avec le layout principal (container, scroll area) | H | 2h | `src/ui/home.rs` | T4.1 | ⬜ |
94+| T4.5 | Implémenter le bouton "Ajouter un flux" dans `home.rs` | H | 2h | `src/ui/home.rs` | T4.4 | ⬜ |
95+| T4.6 | Implémenter le bouton "Synchroniser tous" dans `home.rs` | H | 2h | `src/ui/home.rs` | T4.4 | ⬜ |
96+| T4.7 | Créer `ui/feed_list.rs` pour afficher la liste des flux | H | 3h | `src/ui/feed_list.rs` | T4.1, T2.1 | ⬜ |
97+| T4.8 | Ajouter les actions par flux (boutons éditer, supprimer, synchroniser) | H | 3h | `src/ui/feed_list.rs` | T4.7 | ⬜ |
98+| T4.9 | Créer `ui/add_feed_dialog.rs` avec le formulaire d'ajout | H | 3h | `src/ui/add_feed_dialog.rs` | T4.1, T2.1 | ⬜ |
99+| T4.10 | Implémenter la validation du formulaire dans `add_feed_dialog.rs` | H | 2h | `src/ui/add_feed_dialog.rs` | T4.9 | ⬜ |
100+| T4.11 | Intégrer le dialogue d'ajout dans `home.rs` | H | 1h | `src/ui/home.rs`, `src/ui/add_feed_dialog.rs` | T4.5, T4.9 | ⬜ |
101+| T4.12 | Créer `ui/status_bar.rs` pour afficher les messages et progressions | M | 2h | `src/ui/status_bar.rs` | T4.1 | ⬜ |
102+| T4.13 | Intégrer la barre de statut dans le layout principal | M | 1h | `src/ui/home.rs`, `src/app.rs` | T4.12 | ⬜ |
103+| T4.14 | Créer `ui/feed_edit_dialog.rs` pour éditer un flux existant | M | 2h | `src/ui/feed_edit_dialog.rs` | T4.1, T2.1 | ⬜ |
104+| T4.15 | Intégrer le dialogue d'édition dans `feed_list.rs` | M | 1h | `src/ui/feed_list.rs`, `src/ui/feed_edit_dialog.rs` | T4.8, T4.14 | ⬜ |
105+| T4.16 | Personnaliser le thème egui (couleurs, polices) | L | 2h | `src/app.rs` | T4.1 | ⬜ |
106+| T4.17 | Ajouter des icônes pour les boutons (optionnel) | L | 2h | `src/ui/*` | T4.4 | ⬜ |
107+
108+**Total Phase 4** : 32 heures (4 jours)
109+
110+---
111+
112+## Phase 5 : Synchronisation
113+
114+### Objectif : Implémenter la logique de synchronisation complète
115+
116+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
117+|----|-------|----------|-------|---------|-------------|--------|
118+| T5.1 | Créer `rss/sync.rs` avec les types d'erreur (`SyncError`) | H | 1h | `src/rss/sync.rs` | T1.3 | ⬜ |
119+| T5.2 | Implémenter `sync_feed(feed: &mut Feed) -> Result<Vec<Episode>, SyncError>` | H | 3h | `src/rss/sync.rs` | T5.1, T3.3, T3.4 | ⬜ |
120+| T5.3 | Implémenter `download_new_episodes(feed: &Feed, episodes: &[Episode]) -> Result<(), SyncError>` | H | 2h | `src/rss/sync.rs` | T5.2, T3.8 | ⬜ |
121+| T5.4 | Implémenter `sync_all_feeds(feeds: &mut [Feed]) -> Result<(), SyncError>` | H | 2h | `src/rss/sync.rs` | T5.2 | ⬜ |
122+| T5.5 | Mettre à jour `last_checked` et `last_episode_date` après synchronisation | H | 1h | `src/rss/sync.rs` | T5.2 | ⬜ |
123+| T5.6 | Gérer les conflits de noms de fichiers (ajout de suffixe) | M | 2h | `src/rss/sync.rs` | T5.3 | ⬜ |
124+| T5.7 | Connecter le bouton "Synchroniser" à `sync_feed` | H | 1h | `src/ui/feed_list.rs`, `src/rss/sync.rs` | T4.8, T5.2 | ⬜ |
125+| T5.8 | Connecter le bouton "Synchroniser tous" à `sync_all_feeds` | H | 1h | `src/ui/home.rs`, `src/rss/sync.rs` | T4.6, T5.4 | ⬜ |
126+| T5.9 | Mettre à jour `rss/mod.rs` pour exporter le module sync | H | 0.5h | `src/rss/mod.rs` | T5.1 | ⬜ |
127+| T5.10 | Implémenter la détection des épisodes déjà téléchargés | M | 2h | `src/rss/sync.rs` | T5.2 | ⬜ |
128+
129+**Total Phase 5** : 16 heures (2 jours)
130+
131+---
132+
133+## Phase 6 : Intégration et Tests
134+
135+### Objectif : Intégrer tous les composants et tester l'application
136+
137+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
138+|----|-------|----------|-------|---------|-------------|--------|
139+| T6.1 | Vérifier que tous les modules compilent ensemble | H | 1h | - | Toutes les tâches précédentes | ⬜ |
140+| T6.2 | Tester manuellement l'ajout de flux (validation, persistance) | H | 2h | - | T2.1-T2.12, T4.5, T4.9 | ⬜ |
141+| T6.3 | Tester manuellement la synchronisation d'un flux | H | 2h | - | T3.1-T3.11, T5.1-T5.10 | ⬜ |
142+| T6.4 | Tester manuellement le téléchargement d'épisodes | H | 2h | - | T3.6-T3.10, T5.3 | ⬜ |
143+| T6.5 | Tester la suppression de flux | H | 1h | - | T4.7, T4.8 | ⬜ |
144+| T6.6 | Tester l'édition de flux | H | 1h | - | T4.14, T4.15 | ⬜ |
145+| T6.7 | Vérifier la gestion des erreurs (URL invalide, réseau, permissions) | M | 2h | - | Toutes | ⬜ |
146+| T6.8 | Optimiser les performances (pas de blocage UI pendant les téléchargements) | M | 2h | `src/app.rs`, `src/rss/*` | Toutes | ⬜ |
147+| T6.9 | Ajouter des logs détaillés pour le debug | M | 1h | Tous les modules | Toutes | ⬜ |
148+| T6.10 | Créer des tests unitaires pour les fonctions critiques | M | 4h | `src/rss/parser.rs`, `src/rss/sync.rs`, `src/config/storage.rs` | Toutes | ⬜ |
149+| T6.11 | Vérifier la compatibilité Windows/Linux | M | 2h | - | Toutes | ⬜ |
150+| T6.12 | Corriger les bugs identifiés | M | 4h | Variables | T6.1-T6.11 | ⬜ |
151+
152+**Total Phase 6** : 24 heures (3 jours révisés)
153+
154+---
155+
156+## Phase 7 : Finalisation
157+
158+### Objectif : Préparer l'application pour la distribution
159+
160+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
161+|----|-------|----------|-------|---------|-------------|--------|
162+| T7.1 | Ajouter une icône pour l'application (fichier `assets/icon.png`) | M | 1h | `assets/icon.png` | T1.3 | ⬜ |
163+| T7.2 | Configurer le nom, version, description dans `Cargo.toml` | M | 0.5h | `Cargo.toml` | T1.2 | ⬜ |
164+| T7.3 | Créer un fichier `README.md` avec la documentation | M | 2h | `README.md` | Toutes | ⬜ |
165+| T7.4 | Configurer le build pour Windows (`cargo build --release`) | M | 1h | - | Toutes | ⬜ |
166+| T7.5 | Configurer le build pour Linux | M | 1h | - | Toutes | ⬜ |
167+| T7.6 | Nettoyer le code (supprimer les debug prints, commentaires inutiles) | L | 2h | Tous les fichiers source | Toutes | ⬜ |
168+| T7.7 | Vérifier les warnings de compilation | L | 1h | - | Toutes | ⬜ |
169+| T7.8 | Créer un fichier `.gitignore` approprié | L | 0.5h | `.gitignore` | T1.1 | ⬜ |
170+| T7.9 | Commiter tout le code avec des messages clairs | L | 1h | - | Toutes | ⬜ |
171+| T7.10 | Créer une release GitHub (optionnel) | L | 1h | - | T7.9 | ⬜ |
172+
173+**Total Phase 7** : 11 heures (1.5 jours révisés)
174+
175+---
176+
177+## Résumé Global
178+
179+| Phase | Nombre de Tâches | Durée Totale | Statut |
180+|-------|------------------|--------------|--------|
181+| Phase 1 | 8 tâches | 5h | ⬜ |
182+| Phase 2 | 12 tâches | 14h | ⬜ |
183+| Phase 3 | 11 tâches | 23h | ⬜ |
184+| Phase 4 | 17 tâches | 32h | ⬜ |
185+| Phase 5 | 10 tâches | 16h | ⬜ |
186+| Phase 6 | 12 tâches | 24h | ⬜ |
187+| Phase 7 | 10 tâches | 11h | ⬜ |
188+| **Total** | **80 tâches** | **125 heures** (~16 jours) | ⬜ |
189+
190+---
191+
192+## Ordre Recommandé de Réalisation
193+
194+### Semaine 1 (Initialisation + Modèles + Parsing)
195+1. T1.1 → T1.8 (Phase 1 complète)
196+2. T2.1 → T2.12 (Phase 2 complète)
197+3. T3.1 → T3.11 (Phase 3 complète)
198+
199+### Semaine 2 (UI + Synchronisation)
200+4. T4.1 → T4.17 (Phase 4 complète)
201+5. T5.1 → T5.10 (Phase 5 complète)
202+
203+### Semaine 3 (Intégration + Finalisation)
204+6. T6.1 → T6.12 (Phase 6 complète)
205+7. T7.1 → T7.10 (Phase 7 complète)
206+
207+---
208+
209+## Conseils de Développement
210+
211+### Bonnes Pratiques
212+- **Commits fréquents** : Commiter après chaque tâche terminée
213+- **Tests unitaires** : Ajouter des tests dès que possible (surtout Phase 2 et 3)
214+- **Documentation** : Documenter les fonctions publiques avec `///`
215+- **Gestion des erreurs** : Utiliser des types d'erreur custom plutôt que `String`
216+- **Logging** : Utiliser `log::info!`, `log::error!`, etc. pour le debug
217+
218+### Commandes Utiles
219+```bash
220+# Vérifier la compilation
221+cargo check
222+
223+# Exécuter l'application
224+cargo run
225+
226+# Build en mode release
227+cargo build --release
228+
229+# Exécuter les tests
230+cargo test
231+
232+# Formater le code
233+cargo fmt
234+
235+# Analyser le code (linter)
236+cargo clippy
237+```
238+
239+### Resources
240+- Documentation egui : https://docs.rs/egui/latest/egui/
241+- Documentation eframe : https://docs.rs/eframe/latest/eframe/
242+- Crate rss : https://docs.rs/rss/latest/rss/
243+- Crate reqwest : https://docs.rs/reqwest/latest/reqwest/
244+
245+---
246+
247+## Suivi des Progrès
248+
249+Crée un fichier `spec/progress.md` ou utilise un outil comme GitHub Projects pour suivre l'avancement de chaque tâche.
250+
251+*Exemple de format pour progress.md* :
252+```markdown
253+## Progrès
254+
255+- [x] T1.1 - Créer le projet Rust
256+- [x] T1.2 - Configurer Cargo.toml
257+- [ ] T1.3 - Créer la structure de dossiers
258+...
259+```
260+
261+---
262+
263+*Document généré le 03/07/2026 - Version 1.0*
new file mode 100644
@@ -0,0 +1,263 @@
1+# RSS Podcast Downloader - Liste Détaillée des Tâches
2+
3+*Version 1.0 - 03/07/2026*
4+*Dérivé de spec/init-plan.md*
5+
6+---
7+
8+## Légende
9+
10+- **ID** : Identifiant unique de la tâche (ex: T1.1)
11+- **Phase** : Phase du plan global (1-7)
12+- **Priorité** : High (H) | Medium (M) | Low (L)
13+- **Durée** : Temps estimé en heures
14+- **Statut** : ⬜ À faire | 🟡 En cours | ✅ Terminé | ❌ Annulé
15+- **Fichiers** : Fichiers concernés par la tâche
16+- **Dépendances** : IDs des tâches requises avant celle-ci
17+
18+---
19+
20+## Phase 1 : Initialisation du Projet
21+
22+### Objectif : Créer la structure de base du projet Rust avec egui
23+
24+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
25+|----|-------|----------|-------|---------|-------------|--------|
26+| T1.1 | Créer le projet Rust avec `cargo init --name rss-podcast-dl-egui` | H | 0.5h | `Cargo.toml`, `src/main.rs` | Aucune | ⬜ |
27+| T1.2 | Configurer `Cargo.toml` avec toutes les dépendances nécessaires | H | 1h | `Cargo.toml` | T1.1 | ⬜ |
28+| T1.3 | Créer la structure de dossiers (`src/config/`, `src/rss/`, `src/ui/`, `spec/`, `assets/`) | H | 0.5h | Structure de dossiers | T1.1 | ⬜ |
29+| T1.4 | Créer les fichiers vides pour chaque module (`mod.rs` dans chaque dossier) | H | 0.5h | `src/config/mod.rs`, `src/rss/mod.rs`, `src/ui/mod.rs` | T1.3 | ⬜ |
30+| T1.5 | Configurer `main.rs` avec le squelette de base eframe | H | 1h | `src/main.rs` | T1.2 | ⬜ |
31+| T1.6 | Initialiser le logging avec `env_logger` dans `main.rs` | M | 0.5h | `src/main.rs` | T1.5 | ⬜ |
32+| T1.7 | Tester la compilation de base avec `cargo check` | M | 0.5h | - | T1.6 | ⬜ |
33+| T1.8 | Vérifier l'exécution avec `cargo run` (fenêtre egui vide) | M | 0.5h | - | T1.7 | ⬜ |
34+
35+**Total Phase 1** : 5 heures
36+
37+---
38+
39+## Phase 2 : Modèles et Stockage
40+
41+### Objectif : Implémenter les modèles de données et la persistance
42+
43+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
44+|----|-------|----------|-------|---------|-------------|--------|
45+| T2.1 | Créer `config/feed.rs` avec la structure `Feed` | H | 1h | `src/config/feed.rs` | T1.3 | ⬜ |
46+| T2.2 | Implémenter `Default`, `Debug`, `Clone`, `Serialize`, `Deserialize` pour `Feed` | H | 1h | `src/config/feed.rs` | T2.1 | ⬜ |
47+| T2.3 | Créer `config/episode.rs` avec la structure `Episode` | H | 1h | `src/config/episode.rs` | T1.3 | ⬜ |
48+| T2.4 | Créer `config/app_state.rs` avec la structure `AppState` | H | 1h | `src/config/app_state.rs` | T1.3 | ⬜ |
49+| T2.5 | Mettre à jour `config/mod.rs` pour exporter les modules | H | 0.5h | `src/config/mod.rs` | T2.1, T2.3, T2.4 | ⬜ |
50+| T2.6 | Créer `config/storage.rs` avec les types d'erreur (`StorageError`) | H | 1h | `src/config/storage.rs` | T2.1 | ⬜ |
51+| T2.7 | Implémenter `get_config_path()` pour déterminer le chemin du fichier de config | H | 1h | `src/config/storage.rs` | T2.6 | ⬜ |
52+| T2.8 | Implémenter `save_feeds(feeds: &[Feed], path: &Path)` | H | 2h | `src/config/storage.rs` | T2.6 | ⬜ |
53+| T2.9 | Implémenter `load_feeds(path: &Path) -> Result<Vec<Feed>, StorageError>` | H | 2h | `src/config/storage.rs` | T2.6 | ⬜ |
54+| T2.10 | Ajouter la validation de l'URL dans `Feed` (méthode `validate_url()`) | M | 1h | `src/config/feed.rs` | T2.1 | ⬜ |
55+| T2.11 | Ajouter la validation du chemin dans `Feed` (méthode `validate_path()`) | M | 1h | `src/config/feed.rs` | T2.1 | ⬜ |
56+| T2.12 | Créer un test unitaire pour `save_feeds` et `load_feeds` | M | 1h | `src/config/storage.rs` | T2.8, T2.9 | ⬜ |
57+
58+**Total Phase 2** : 14 heures (2 jours)
59+
60+---
61+
62+## Phase 3 : Parsing RSS et Téléchargement
63+
64+### Objectif : Implémenter la récupération, le parsing des flux et le téléchargement
65+
66+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
67+|----|-------|----------|-------|---------|-------------|--------|
68+| T3.1 | Créer `rss/parser.rs` avec les types d'erreur (`ParserError`) | H | 1h | `src/rss/parser.rs` | T1.3 | ⬜ |
69+| T3.2 | Implémenter `fetch_feed(url: &str) -> Result<String, ParserError>` (récupération HTTP) | H | 2h | `src/rss/parser.rs` | T3.1 | ⬜ |
70+| T3.3 | Implémenter `parse_rss_content(content: &str) -> Result<RssFeed, ParserError>` | H | 2h | `src/rss/parser.rs` | T3.1 | ⬜ |
71+| T3.4 | Créer `rss/episode_extractor.rs` avec `extract_episodes(feed: &RssFeed) -> Vec<Episode>` | H | 3h | `src/rss/episode_extractor.rs` | T2.3, T3.3 | ⬜ |
72+| T3.5 | Gérer les différents formats (RSS 2.0, Atom) dans l'extraction | H | 2h | `src/rss/episode_extractor.rs` | T3.4 | ⬜ |
73+| T3.6 | Créer `rss/downloader.rs` avec les types d'erreur (`DownloadError`) | H | 1h | `src/rss/downloader.rs` | T1.3 | ⬜ |
74+| T3.7 | Implémenter `download_file(url: &str, dest: &Path) -> Result<(), DownloadError>` | H | 2h | `src/rss/downloader.rs` | T3.6 | ⬜ |
75+| T3.8 | Implémenter `download_episode(episode: &Episode, download_path: &Path, progress_callback: Box<dyn Fn(f32)>)` | H | 3h | `src/rss/downloader.rs` | T3.7 | ⬜ |
76+| T3.9 | Gérer le timeout et retry pour les requêtes HTTP | M | 2h | `src/rss/parser.rs`, `src/rss/downloader.rs` | T3.2, T3.7 | ⬜ |
77+| T3.10 | Créer un système de cache pour éviter de re-télécharger les mêmes épisodes | M | 2h | `src/rss/downloader.rs` | T3.8 | ⬜ |
78+| T3.11 | Mettre à jour `rss/mod.rs` pour exporter les modules | H | 0.5h | `src/rss/mod.rs` | T3.1, T3.4, T3.6 | ⬜ |
79+
80+**Total Phase 3** : 23 heures (3 jours)
81+
82+---
83+
84+## Phase 4 : Interface Utilisateur
85+
86+### Objectif : Créer l'interface graphique complète avec egui
87+
88+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
89+|----|-------|----------|-------|---------|-------------|--------|
90+| T4.1 | Créer `app.rs` avec la structure principale de l'application | H | 2h | `src/app.rs` | T1.5, T2.4 | ⬜ |
91+| T4.2 | Mettre à jour `main.rs` pour utiliser `app.rs` | H | 1h | `src/main.rs` | T4.1 | ⬜ |
92+| T4.3 | Créer `ui/mod.rs` pour exporter les composants UI | H | 0.5h | `src/ui/mod.rs` | T1.3 | ⬜ |
93+| T4.4 | Créer `ui/home.rs` avec le layout principal (container, scroll area) | H | 2h | `src/ui/home.rs` | T4.1 | ⬜ |
94+| T4.5 | Implémenter le bouton "Ajouter un flux" dans `home.rs` | H | 2h | `src/ui/home.rs` | T4.4 | ⬜ |
95+| T4.6 | Implémenter le bouton "Synchroniser tous" dans `home.rs` | H | 2h | `src/ui/home.rs` | T4.4 | ⬜ |
96+| T4.7 | Créer `ui/feed_list.rs` pour afficher la liste des flux | H | 3h | `src/ui/feed_list.rs` | T4.1, T2.1 | ⬜ |
97+| T4.8 | Ajouter les actions par flux (boutons éditer, supprimer, synchroniser) | H | 3h | `src/ui/feed_list.rs` | T4.7 | ⬜ |
98+| T4.9 | Créer `ui/add_feed_dialog.rs` avec le formulaire d'ajout | H | 3h | `src/ui/add_feed_dialog.rs` | T4.1, T2.1 | ⬜ |
99+| T4.10 | Implémenter la validation du formulaire dans `add_feed_dialog.rs` | H | 2h | `src/ui/add_feed_dialog.rs` | T4.9 | ⬜ |
100+| T4.11 | Intégrer le dialogue d'ajout dans `home.rs` | H | 1h | `src/ui/home.rs`, `src/ui/add_feed_dialog.rs` | T4.5, T4.9 | ⬜ |
101+| T4.12 | Créer `ui/status_bar.rs` pour afficher les messages et progressions | M | 2h | `src/ui/status_bar.rs` | T4.1 | ⬜ |
102+| T4.13 | Intégrer la barre de statut dans le layout principal | M | 1h | `src/ui/home.rs`, `src/app.rs` | T4.12 | ⬜ |
103+| T4.14 | Créer `ui/feed_edit_dialog.rs` pour éditer un flux existant | M | 2h | `src/ui/feed_edit_dialog.rs` | T4.1, T2.1 | ⬜ |
104+| T4.15 | Intégrer le dialogue d'édition dans `feed_list.rs` | M | 1h | `src/ui/feed_list.rs`, `src/ui/feed_edit_dialog.rs` | T4.8, T4.14 | ⬜ |
105+| T4.16 | Personnaliser le thème egui (couleurs, polices) | L | 2h | `src/app.rs` | T4.1 | ⬜ |
106+| T4.17 | Ajouter des icônes pour les boutons (optionnel) | L | 2h | `src/ui/*` | T4.4 | ⬜ |
107+
108+**Total Phase 4** : 32 heures (4 jours)
109+
110+---
111+
112+## Phase 5 : Synchronisation
113+
114+### Objectif : Implémenter la logique de synchronisation complète
115+
116+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
117+|----|-------|----------|-------|---------|-------------|--------|
118+| T5.1 | Créer `rss/sync.rs` avec les types d'erreur (`SyncError`) | H | 1h | `src/rss/sync.rs` | T1.3 | ⬜ |
119+| T5.2 | Implémenter `sync_feed(feed: &mut Feed) -> Result<Vec<Episode>, SyncError>` | H | 3h | `src/rss/sync.rs` | T5.1, T3.3, T3.4 | ⬜ |
120+| T5.3 | Implémenter `download_new_episodes(feed: &Feed, episodes: &[Episode]) -> Result<(), SyncError>` | H | 2h | `src/rss/sync.rs` | T5.2, T3.8 | ⬜ |
121+| T5.4 | Implémenter `sync_all_feeds(feeds: &mut [Feed]) -> Result<(), SyncError>` | H | 2h | `src/rss/sync.rs` | T5.2 | ⬜ |
122+| T5.5 | Mettre à jour `last_checked` et `last_episode_date` après synchronisation | H | 1h | `src/rss/sync.rs` | T5.2 | ⬜ |
123+| T5.6 | Gérer les conflits de noms de fichiers (ajout de suffixe) | M | 2h | `src/rss/sync.rs` | T5.3 | ⬜ |
124+| T5.7 | Connecter le bouton "Synchroniser" à `sync_feed` | H | 1h | `src/ui/feed_list.rs`, `src/rss/sync.rs` | T4.8, T5.2 | ⬜ |
125+| T5.8 | Connecter le bouton "Synchroniser tous" à `sync_all_feeds` | H | 1h | `src/ui/home.rs`, `src/rss/sync.rs` | T4.6, T5.4 | ⬜ |
126+| T5.9 | Mettre à jour `rss/mod.rs` pour exporter le module sync | H | 0.5h | `src/rss/mod.rs` | T5.1 | ⬜ |
127+| T5.10 | Implémenter la détection des épisodes déjà téléchargés | M | 2h | `src/rss/sync.rs` | T5.2 | ⬜ |
128+
129+**Total Phase 5** : 16 heures (2 jours)
130+
131+---
132+
133+## Phase 6 : Intégration et Tests
134+
135+### Objectif : Intégrer tous les composants et tester l'application
136+
137+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
138+|----|-------|----------|-------|---------|-------------|--------|
139+| T6.1 | Vérifier que tous les modules compilent ensemble | H | 1h | - | Toutes les tâches précédentes | ⬜ |
140+| T6.2 | Tester manuellement l'ajout de flux (validation, persistance) | H | 2h | - | T2.1-T2.12, T4.5, T4.9 | ⬜ |
141+| T6.3 | Tester manuellement la synchronisation d'un flux | H | 2h | - | T3.1-T3.11, T5.1-T5.10 | ⬜ |
142+| T6.4 | Tester manuellement le téléchargement d'épisodes | H | 2h | - | T3.6-T3.10, T5.3 | ⬜ |
143+| T6.5 | Tester la suppression de flux | H | 1h | - | T4.7, T4.8 | ⬜ |
144+| T6.6 | Tester l'édition de flux | H | 1h | - | T4.14, T4.15 | ⬜ |
145+| T6.7 | Vérifier la gestion des erreurs (URL invalide, réseau, permissions) | M | 2h | - | Toutes | ⬜ |
146+| T6.8 | Optimiser les performances (pas de blocage UI pendant les téléchargements) | M | 2h | `src/app.rs`, `src/rss/*` | Toutes | ⬜ |
147+| T6.9 | Ajouter des logs détaillés pour le debug | M | 1h | Tous les modules | Toutes | ⬜ |
148+| T6.10 | Créer des tests unitaires pour les fonctions critiques | M | 4h | `src/rss/parser.rs`, `src/rss/sync.rs`, `src/config/storage.rs` | Toutes | ⬜ |
149+| T6.11 | Vérifier la compatibilité Windows/Linux | M | 2h | - | Toutes | ⬜ |
150+| T6.12 | Corriger les bugs identifiés | M | 4h | Variables | T6.1-T6.11 | ⬜ |
151+
152+**Total Phase 6** : 24 heures (3 jours révisés)
153+
154+---
155+
156+## Phase 7 : Finalisation
157+
158+### Objectif : Préparer l'application pour la distribution
159+
160+| ID | Tâche | Priorité | Durée | Fichiers | Dépendances | Statut |
161+|----|-------|----------|-------|---------|-------------|--------|
162+| T7.1 | Ajouter une icône pour l'application (fichier `assets/icon.png`) | M | 1h | `assets/icon.png` | T1.3 | ⬜ |
163+| T7.2 | Configurer le nom, version, description dans `Cargo.toml` | M | 0.5h | `Cargo.toml` | T1.2 | ⬜ |
164+| T7.3 | Créer un fichier `README.md` avec la documentation | M | 2h | `README.md` | Toutes | ⬜ |
165+| T7.4 | Configurer le build pour Windows (`cargo build --release`) | M | 1h | - | Toutes | ⬜ |
166+| T7.5 | Configurer le build pour Linux | M | 1h | - | Toutes | ⬜ |
167+| T7.6 | Nettoyer le code (supprimer les debug prints, commentaires inutiles) | L | 2h | Tous les fichiers source | Toutes | ⬜ |
168+| T7.7 | Vérifier les warnings de compilation | L | 1h | - | Toutes | ⬜ |
169+| T7.8 | Créer un fichier `.gitignore` approprié | L | 0.5h | `.gitignore` | T1.1 | ⬜ |
170+| T7.9 | Commiter tout le code avec des messages clairs | L | 1h | - | Toutes | ⬜ |
171+| T7.10 | Créer une release GitHub (optionnel) | L | 1h | - | T7.9 | ⬜ |
172+
173+**Total Phase 7** : 11 heures (1.5 jours révisés)
174+
175+---
176+
177+## Résumé Global
178+
179+| Phase | Nombre de Tâches | Durée Totale | Statut |
180+|-------|------------------|--------------|--------|
181+| Phase 1 | 8 tâches | 5h | ⬜ |
182+| Phase 2 | 12 tâches | 14h | ⬜ |
183+| Phase 3 | 11 tâches | 23h | ⬜ |
184+| Phase 4 | 17 tâches | 32h | ⬜ |
185+| Phase 5 | 10 tâches | 16h | ⬜ |
186+| Phase 6 | 12 tâches | 24h | ⬜ |
187+| Phase 7 | 10 tâches | 11h | ⬜ |
188+| **Total** | **80 tâches** | **125 heures** (~16 jours) | ⬜ |
189+
190+---
191+
192+## Ordre Recommandé de Réalisation
193+
194+### Semaine 1 (Initialisation + Modèles + Parsing)
195+1. T1.1 → T1.8 (Phase 1 complète)
196+2. T2.1 → T2.12 (Phase 2 complète)
197+3. T3.1 → T3.11 (Phase 3 complète)
198+
199+### Semaine 2 (UI + Synchronisation)
200+4. T4.1 → T4.17 (Phase 4 complète)
201+5. T5.1 → T5.10 (Phase 5 complète)
202+
203+### Semaine 3 (Intégration + Finalisation)
204+6. T6.1 → T6.12 (Phase 6 complète)
205+7. T7.1 → T7.10 (Phase 7 complète)
206+
207+---
208+
209+## Conseils de Développement
210+
211+### Bonnes Pratiques
212+- **Commits fréquents** : Commiter après chaque tâche terminée
213+- **Tests unitaires** : Ajouter des tests dès que possible (surtout Phase 2 et 3)
214+- **Documentation** : Documenter les fonctions publiques avec `///`
215+- **Gestion des erreurs** : Utiliser des types d'erreur custom plutôt que `String`
216+- **Logging** : Utiliser `log::info!`, `log::error!`, etc. pour le debug
217+
218+### Commandes Utiles
219+```bash
220+# Vérifier la compilation
221+cargo check
222+
223+# Exécuter l'application
224+cargo run
225+
226+# Build en mode release
227+cargo build --release
228+
229+# Exécuter les tests
230+cargo test
231+
232+# Formater le code
233+cargo fmt
234+
235+# Analyser le code (linter)
236+cargo clippy
237+```
238+
239+### Resources
240+- Documentation egui : https://docs.rs/egui/latest/egui/
241+- Documentation eframe : https://docs.rs/eframe/latest/eframe/
242+- Crate rss : https://docs.rs/rss/latest/rss/
243+- Crate reqwest : https://docs.rs/reqwest/latest/reqwest/
244+
245+---
246+
247+## Suivi des Progrès
248+
249+Crée un fichier `spec/progress.md` ou utilise un outil comme GitHub Projects pour suivre l'avancement de chaque tâche.
250+
251+*Exemple de format pour progress.md* :
252+```markdown
253+## Progrès
254+
255+- [x] T1.1 - Créer le projet Rust
256+- [x] T1.2 - Configurer Cargo.toml
257+- [ ] T1.3 - Créer la structure de dossiers
258+...
259+```
260+
261+---
262+
263+*Document généré le 03/07/2026 - Version 1.0*