Ludovic commited on
Commit
533d37b
·
1 Parent(s): 04969c3
Files changed (2) hide show
  1. app/static/js/script.js +83 -39
  2. app/templates/index.html +9 -5
app/static/js/script.js CHANGED
@@ -1,57 +1,90 @@
1
  document.addEventListener('DOMContentLoaded', () => {
 
 
2
  const uploadForm = document.getElementById('upload-form');
3
  const imageFilesInput = document.getElementById('image-files');
4
  const messageArea = document.getElementById('message-area');
5
- // const fileList = document.getElementById('file-list'); // N'est plus utilisé pour afficher les résultats
6
 
7
  const progressContainer = document.getElementById('progress-container');
8
  const progressBarFill = document.getElementById('progress-bar');
9
  const progressTextElement = document.getElementById('progress-text');
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  uploadForm.addEventListener('submit', async (event) => {
12
- event.preventDefault();
13
- messageArea.textContent = '';
14
- messageArea.className = ''; // Effacer les classes précédentes [cite: 134]
15
- // fileList.innerHTML = ''; // Plus nécessaire [cite: 134]
16
 
17
- const files = imageFilesInput.files;
18
- const numFiles = files.length;
 
19
 
20
- if (numFiles === 0) {
21
- messageArea.textContent = 'Veuillez sélectionner au moins une image.';
22
- messageArea.classList.add('error'); // [cite: 135]
23
- return;
24
- }
 
 
 
 
 
25
 
26
- progressTextElement.textContent = `Préparation de ${numFiles} image(s)...`;
27
- progressBarFill.style.width = '0%';
28
- progressBarFill.classList.remove('determinate'); // Activer l'animation indéterminée
29
- progressBarFill.textContent = '';
30
- progressContainer.style.display = 'block';
 
 
31
 
32
- const formData = new FormData();
33
- for (const file of files) { // [cite: 138]
34
- formData.append('files', file); // [cite: 139]
35
- }
 
36
 
37
- try {
38
  progressTextElement.textContent = `Traitement de ${numFiles} image(s) en cours, veuillez patienter...`;
 
39
 
40
  const response = await fetch('/api/upload-images/', {
41
  method: 'POST',
42
  body: formData,
43
  });
 
44
 
45
  if (response.ok) {
46
- // Le serveur renvoie un fichier ZIP
47
  const blob = await response.blob();
48
  const contentDisposition = response.headers.get('content-disposition');
49
- let filename = "captions.zip"; // Nom par défaut
50
  if (contentDisposition) {
51
  const filenameMatch = contentDisposition.match(/filename="?(.+)"?/i);
52
- if (filenameMatch && filenameMatch.length === 2)
53
  filename = filenameMatch[1];
 
54
  }
 
55
 
56
  const link = document.createElement('a');
57
  link.href = URL.createObjectURL(blob);
@@ -59,33 +92,44 @@ document.addEventListener('DOMContentLoaded', () => {
59
  document.body.appendChild(link);
60
  link.click();
61
  document.body.removeChild(link);
62
- URL.revokeObjectURL(link.href); // Libérer l'objet URL
 
63
 
64
  messageArea.textContent = `${numFiles} image(s) traitée(s). Le fichier ZIP '${filename}' est en cours de téléchargement.`;
65
  messageArea.classList.add('success');
66
 
67
  progressBarFill.style.width = '100%';
68
- progressBarFill.classList.add('determinate'); // Stopper l'animation
69
  progressBarFill.textContent = 'Terminé !';
70
  progressTextElement.textContent = "Traitement terminé avec succès !";
71
-
72
 
73
  } else {
74
- // Gérer les erreurs HTTP (ex: 400, 401, 500, 503)
75
- const errorResult = await response.json().catch(() => null); // Essayer de parser JSON, sinon null
76
- if (errorResult && errorResult.detail) {
77
- messageArea.textContent = `Erreur: ${errorResult.detail}`;
78
- } else {
79
- messageArea.textContent = `Une erreur est survenue (code: ${response.status}). Veuillez réessayer.`;
 
 
 
 
 
 
80
  }
 
 
 
81
  messageArea.classList.add('error');
82
- progressContainer.style.display = 'none'; // Cacher la barre en cas d'erreur
83
  }
84
  } catch (error) {
85
- console.error('Upload error:', error); // [cite: 149]
86
- messageArea.textContent = 'Erreur de connexion ou le serveur ne répond pas. Vérifiez la console du navigateur et du serveur.'; // [cite: 148]
87
- messageArea.classList.add('error'); // [cite: 148]
88
- progressContainer.style.display = 'none'; // Cacher la barre
89
  }
90
  });
 
91
  });
 
1
  document.addEventListener('DOMContentLoaded', () => {
2
+ console.log("DOM entièrement chargé et analysé. Initialisation du script.");
3
+
4
  const uploadForm = document.getElementById('upload-form');
5
  const imageFilesInput = document.getElementById('image-files');
6
  const messageArea = document.getElementById('message-area');
 
7
 
8
  const progressContainer = document.getElementById('progress-container');
9
  const progressBarFill = document.getElementById('progress-bar');
10
  const progressTextElement = document.getElementById('progress-text');
11
 
12
+ // Vérification initiale des éléments DOM essentiels
13
+ if (!uploadForm) console.error("ERREUR CRITIQUE: L'élément 'upload-form' est introuvable dans le HTML.");
14
+ if (!imageFilesInput) console.error("ERREUR CRITIQUE: L'élément 'image-files' est introuvable.");
15
+ if (!messageArea) console.error("ERREUR CRITIQUE: L'élément 'message-area' est introuvable.");
16
+ if (!progressContainer) console.error("ERREUR CRITIQUE: L'élément 'progress-container' est introuvable.");
17
+ if (!progressBarFill) console.error("ERREUR CRITIQUE: L'élément 'progress-bar' est introuvable.");
18
+ if (!progressTextElement) console.error("ERREUR CRITIQUE: L'élément 'progress-text' est introuvable.");
19
+
20
+ if (!uploadForm || !imageFilesInput || !messageArea || !progressContainer || !progressBarFill || !progressTextElement) {
21
+ const errorMsg = "Un ou plusieurs éléments d'interface utilisateur sont manquants. L'application ne peut pas fonctionner correctement. Veuillez vérifier les IDs dans les fichiers HTML et JS.";
22
+ console.error(errorMsg);
23
+ if (messageArea) { // Tenter d'afficher une erreur à l'utilisateur si possible
24
+ messageArea.textContent = errorMsg;
25
+ messageArea.className = 'error';
26
+ }
27
+ // Afficher une alerte pour être sûr que l'utilisateur voit le problème critique
28
+ alert(errorMsg);
29
+ return; // Arrêter l'exécution si les éléments critiques ne sont pas là
30
+ }
31
+ console.log("Tous les éléments DOM principaux ont été trouvés.");
32
+
33
  uploadForm.addEventListener('submit', async (event) => {
34
+ console.log("Événement 'submit' du formulaire capturé.");
35
+ event.preventDefault();
36
+ console.log("event.preventDefault() a été appelé pour empêcher la soumission standard.");
 
37
 
38
+ try {
39
+ messageArea.textContent = '';
40
+ messageArea.className = '';
41
 
42
+ const files = imageFilesInput.files;
43
+ const numFiles = files.length;
44
+ console.log(`Nombre de fichiers sélectionnés par l'utilisateur : ${numFiles}`);
45
+
46
+ if (numFiles === 0) {
47
+ messageArea.textContent = 'Veuillez sélectionner au moins une image.';
48
+ messageArea.classList.add('error');
49
+ console.warn("Aucun fichier sélectionné, soumission annulée par le script.");
50
+ return;
51
+ }
52
 
53
+ console.log("Configuration de l'affichage de la barre de progression...");
54
+ progressTextElement.textContent = `Préparation de ${numFiles} image(s)...`;
55
+ progressBarFill.style.width = '0%';
56
+ progressBarFill.classList.remove('determinate');
57
+ progressBarFill.textContent = '';
58
+ progressContainer.style.display = 'block';
59
+ console.log("Barre de progression configurée et affichée.");
60
 
61
+ const formData = new FormData();
62
+ for (const file of files) {
63
+ formData.append('files', file);
64
+ }
65
+ console.log("FormData construit avec les fichiers.");
66
 
 
67
  progressTextElement.textContent = `Traitement de ${numFiles} image(s) en cours, veuillez patienter...`;
68
+ console.log("Début de la requête fetch vers l'API /api/upload-images/...");
69
 
70
  const response = await fetch('/api/upload-images/', {
71
  method: 'POST',
72
  body: formData,
73
  });
74
+ console.log(`Réponse reçue du serveur avec le statut : ${response.status} ${response.statusText}`);
75
 
76
  if (response.ok) {
77
+ console.log("Réponse OK (statut 2xx). Traitement du blob ZIP en cours...");
78
  const blob = await response.blob();
79
  const contentDisposition = response.headers.get('content-disposition');
80
+ let filename = "captions_output.zip"; // Nom par défaut
81
  if (contentDisposition) {
82
  const filenameMatch = contentDisposition.match(/filename="?(.+)"?/i);
83
+ if (filenameMatch && filenameMatch.length === 2) {
84
  filename = filenameMatch[1];
85
+ }
86
  }
87
+ console.log(`Nom du fichier ZIP à télécharger (extrait des en-têtes ou par défaut) : ${filename}`);
88
 
89
  const link = document.createElement('a');
90
  link.href = URL.createObjectURL(blob);
 
92
  document.body.appendChild(link);
93
  link.click();
94
  document.body.removeChild(link);
95
+ URL.revokeObjectURL(link.href);
96
+ console.log("Téléchargement du fichier ZIP initié via un clic simulé.");
97
 
98
  messageArea.textContent = `${numFiles} image(s) traitée(s). Le fichier ZIP '${filename}' est en cours de téléchargement.`;
99
  messageArea.classList.add('success');
100
 
101
  progressBarFill.style.width = '100%';
102
+ progressBarFill.classList.add('determinate'); // Arrêter l'animation indéterminée
103
  progressBarFill.textContent = 'Terminé !';
104
  progressTextElement.textContent = "Traitement terminé avec succès !";
105
+ console.log("Interface utilisateur mise à jour pour indiquer le succès et la fin du traitement.");
106
 
107
  } else {
108
+ console.error(`Erreur HTTP côté serveur : ${response.status} ${response.statusText}`);
109
+ // Essayer de lire le corps de l'erreur, qui pourrait être du JSON ou du texte brut.
110
+ let errorDetail = `Erreur ${response.status}.`;
111
+ try {
112
+ const errorResult = await response.json(); // Tenter de parser comme JSON
113
+ if (errorResult && errorResult.detail) {
114
+ errorDetail = errorResult.detail;
115
+ }
116
+ } catch (e) {
117
+ // Si ce n'est pas du JSON, tenter de lire comme texte brut
118
+ const errorText = await response.text().catch(() => "Impossible de lire le corps de l'erreur du serveur.");
119
+ errorDetail += ` ${errorText.substring(0, 300)}`; // Limiter la longueur pour l'affichage
120
  }
121
+
122
+ messageArea.textContent = `Une erreur est survenue : ${errorDetail}`;
123
+ console.error(`Détail de l'erreur du serveur : ${errorDetail}`);
124
  messageArea.classList.add('error');
125
+ if (progressContainer) progressContainer.style.display = 'none';
126
  }
127
  } catch (error) {
128
+ console.error('Une erreur globale est survenue dans le gestionnaire de soumission du formulaire (try...catch externe) :', error);
129
+ messageArea.textContent = 'Une erreur critique est survenue dans le script de la page. Veuillez vérifier la console du navigateur pour plus de détails.';
130
+ messageArea.classList.add('error');
131
+ if (progressContainer) progressContainer.style.display = 'none'; // Masquer la barre en cas d'erreur grave
132
  }
133
  });
134
+ console.log("Le gestionnaire d'événement 'submit' a été attaché au formulaire.");
135
  });
app/templates/index.html CHANGED
@@ -15,22 +15,26 @@
15
  </header>
16
  <main>
17
  <section id="upload-section">
18
- <h2>Téléverser des Images</h2> <form id="upload-form" enctype="multipart/form-data">
 
19
  <input type="file" id="image-files" name="files" multiple accept="image/*">
20
  <button type="submit">Générer les Descriptions</button>
21
  </form>
22
- <div id="progress-container" style="display:none;"> <p id="progress-text">Traitement des images en cours...</p>
 
23
  <div class="progress-bar-wrapper">
24
  <div id="progress-bar" class="progress-bar-fill"></div>
25
  </div>
26
  </div>
27
  </section>
28
  <section id="results-section">
29
- <h2>Résultats</h2> <div id="message-area"></div>
30
- </section>
 
31
  </main>
32
  <footer>
33
- <p>&copy; 2025 Votre Application AutoCaption</p> </footer>
 
34
  <script src="{{ url_for('static', path='/js/script.js') }}"></script>
35
  </body>
36
  </html>
 
15
  </header>
16
  <main>
17
  <section id="upload-section">
18
+ <h2>Téléverser des Images</h2>
19
+ <form id="upload-form" enctype="multipart/form-data">
20
  <input type="file" id="image-files" name="files" multiple accept="image/*">
21
  <button type="submit">Générer les Descriptions</button>
22
  </form>
23
+ <div id="progress-container" style="display:none;">
24
+ <p id="progress-text">Traitement des images en cours...</p>
25
  <div class="progress-bar-wrapper">
26
  <div id="progress-bar" class="progress-bar-fill"></div>
27
  </div>
28
  </div>
29
  </section>
30
  <section id="results-section">
31
+ <h2>Résultats</h2>
32
+ <div id="message-area"></div>
33
+ </section>
34
  </main>
35
  <footer>
36
+ <p>&copy; 2025 Votre Application AutoCaption</p>
37
+ </footer>
38
  <script src="{{ url_for('static', path='/js/script.js') }}"></script>
39
  </body>
40
  </html>