#!/usr/bin/env python3 """ Script de vérification du ZIP VWB propre Auteur : Dom, Alice, Kiro - 8 janvier 2026 """ import zipfile import os import json import tempfile import shutil class VerificateurZipVWB: """Classe pour vérifier la qualité du ZIP VWB""" def __init__(self, nom_zip): self.nom_zip = nom_zip self.dossier_temp = None self.resultats = {} def extraire_zip_temporaire(self): """Extraire le ZIP dans un dossier temporaire""" self.dossier_temp = tempfile.mkdtemp(prefix="verif_vwb_") with zipfile.ZipFile(self.nom_zip, 'r') as zipf: zipf.extractall(self.dossier_temp) print(f"📁 ZIP extrait dans: {self.dossier_temp}") return True def verifier_structure_generale(self): """Vérifier la structure générale du projet""" print("🏗️ Vérification de la structure...") dossiers_requis = [ "visual_workflow_builder", "visual_workflow_builder/backend", "visual_workflow_builder/frontend", "visual_workflow_builder/backend/api", "visual_workflow_builder/frontend/src", "visual_workflow_builder/frontend/src/components", ] fichiers_requis = [ "README.md", "version.json", "diagnostic_backend_complet.py", "demarrer_backend_propre.py", "test_systeme_complet.py", "visual_workflow_builder/backend/app.py", "visual_workflow_builder/frontend/package.json", ] structure_ok = True # Vérifier les dossiers for dossier in dossiers_requis: chemin = os.path.join(self.dossier_temp, dossier) if os.path.exists(chemin): print(f" ✅ Dossier: {dossier}") else: print(f" ❌ Dossier manquant: {dossier}") structure_ok = False # Vérifier les fichiers for fichier in fichiers_requis: chemin = os.path.join(self.dossier_temp, fichier) if os.path.exists(chemin): print(f" ✅ Fichier: {fichier}") else: print(f" ❌ Fichier manquant: {fichier}") structure_ok = False self.resultats['structure'] = structure_ok return structure_ok def verifier_conformite_attribution(self): """Vérifier la conformité de l'attribution""" print("👥 Vérification de l'attribution...") fichiers_python = [] fichiers_typescript = [] fichiers_css = [] # Parcourir tous les fichiers for root, dirs, files in os.walk(self.dossier_temp): for file in files: chemin_complet = os.path.join(root, file) extension = os.path.splitext(file)[1].lower() if extension == '.py': fichiers_python.append(chemin_complet) elif extension in ['.ts', '.tsx']: fichiers_typescript.append(chemin_complet) elif extension == '.css': fichiers_css.append(chemin_complet) conformes = 0 total = 0 # Vérifier les fichiers Python for fichier in fichiers_python: total += 1 try: with open(fichier, 'r', encoding='utf-8') as f: contenu = f.read() if ('Auteur : Dom, Alice, Kiro' in contenu or 'Auteur: Dom, Alice, Kiro' in contenu) and '8 janvier 2026' in contenu: conformes += 1 print(f" ✅ {os.path.relpath(fichier, self.dossier_temp)}") else: print(f" ❌ {os.path.relpath(fichier, self.dossier_temp)}") except: print(f" ⚠️ Erreur lecture: {os.path.relpath(fichier, self.dossier_temp)}") # Vérifier les fichiers TypeScript for fichier in fichiers_typescript: total += 1 try: with open(fichier, 'r', encoding='utf-8') as f: contenu = f.read() if 'Auteur : Dom, Alice, Kiro' in contenu and '8 janvier 2026' in contenu: conformes += 1 print(f" ✅ {os.path.relpath(fichier, self.dossier_temp)}") else: print(f" ❌ {os.path.relpath(fichier, self.dossier_temp)}") except: print(f" ⚠️ Erreur lecture: {os.path.relpath(fichier, self.dossier_temp)}") # Vérifier les fichiers CSS for fichier in fichiers_css: total += 1 try: with open(fichier, 'r', encoding='utf-8') as f: contenu = f.read() if 'Auteur : Dom, Alice, Kiro' in contenu and '8 janvier 2026' in contenu: conformes += 1 print(f" ✅ {os.path.relpath(fichier, self.dossier_temp)}") else: print(f" ❌ {os.path.relpath(fichier, self.dossier_temp)}") except: print(f" ⚠️ Erreur lecture: {os.path.relpath(fichier, self.dossier_temp)}") taux_conformite = (conformes / total) * 100 if total > 0 else 100 print(f" 📊 Conformité attribution: {conformes}/{total} ({taux_conformite:.1f}%)") self.resultats['attribution'] = taux_conformite >= 80 return taux_conformite >= 80 def verifier_version_info(self): """Vérifier les informations de version""" print("📋 Vérification des informations de version...") chemin_version = os.path.join(self.dossier_temp, "version.json") if not os.path.exists(chemin_version): print(" ❌ Fichier version.json manquant") self.resultats['version'] = False return False try: with open(chemin_version, 'r', encoding='utf-8') as f: version_data = json.load(f) champs_requis = ['version', 'date_creation', 'auteurs', 'description', 'conformite'] for champ in champs_requis: if champ in version_data: print(f" ✅ {champ}: {version_data[champ]}") else: print(f" ❌ Champ manquant: {champ}") self.resultats['version'] = False return False # Vérifier la conformité conformite = version_data.get('conformite', {}) if conformite.get('langue') == 'français' and conformite.get('tests_reels') == True: print(" ✅ Conformité française validée") self.resultats['version'] = True return True else: print(" ❌ Conformité française non validée") self.resultats['version'] = False return False except json.JSONDecodeError as e: print(f" ❌ Erreur JSON: {e}") self.resultats['version'] = False return False def verifier_readme(self): """Vérifier le README principal""" print("📄 Vérification du README...") chemin_readme = os.path.join(self.dossier_temp, "README.md") if not os.path.exists(chemin_readme): print(" ❌ README.md manquant") self.resultats['readme'] = False return False try: with open(chemin_readme, 'r', encoding='utf-8') as f: contenu = f.read() elements_requis = [ "Visual Workflow Builder", "Auteur : Dom, Alice, Kiro", "8 janvier 2026", "Démarrage rapide", "Backend", "Frontend", "Tests", ] elements_presents = 0 for element in elements_requis: if element in contenu: elements_presents += 1 print(f" ✅ {element}") else: print(f" ❌ Manquant: {element}") taux_completude = (elements_presents / len(elements_requis)) * 100 print(f" 📊 Complétude README: {elements_presents}/{len(elements_requis)} ({taux_completude:.1f}%)") self.resultats['readme'] = taux_completude >= 80 return taux_completude >= 80 except Exception as e: print(f" ❌ Erreur lecture README: {e}") self.resultats['readme'] = False return False def compter_fichiers_par_type(self): """Compter les fichiers par type""" print("📊 Statistiques des fichiers...") compteurs = { 'python': 0, 'typescript': 0, 'css': 0, 'json': 0, 'markdown': 0, 'autres': 0 } for root, dirs, files in os.walk(self.dossier_temp): for file in files: extension = os.path.splitext(file)[1].lower() if extension == '.py': compteurs['python'] += 1 elif extension in ['.ts', '.tsx']: compteurs['typescript'] += 1 elif extension == '.css': compteurs['css'] += 1 elif extension == '.json': compteurs['json'] += 1 elif extension == '.md': compteurs['markdown'] += 1 else: compteurs['autres'] += 1 total = sum(compteurs.values()) for type_fichier, count in compteurs.items(): pourcentage = (count / total) * 100 if total > 0 else 0 print(f" 📁 {type_fichier.capitalize()}: {count} fichiers ({pourcentage:.1f}%)") print(f" 📈 Total: {total} fichiers") return compteurs def generer_rapport_final(self): """Générer le rapport final de vérification""" print("\n" + "=" * 60) print("📊 RAPPORT DE VÉRIFICATION DU ZIP VWB") print("=" * 60) tests_reussis = sum(1 for resultat in self.resultats.values() if resultat) total_tests = len(self.resultats) taux_reussite = (tests_reussis / total_tests) * 100 if total_tests > 0 else 0 print(f"📈 Résultats: {tests_reussis}/{total_tests} ({taux_reussite:.1f}%)") print("\n📋 Détail des vérifications:") for test, resultat in self.resultats.items(): icone = "✅" if resultat else "❌" print(f" {icone} {test.replace('_', ' ').title()}") # Déterminer la qualité if taux_reussite == 100: qualite = "🏆 EXCELLENTE - ZIP parfaitement conforme" code_sortie = 0 elif taux_reussite >= 80: qualite = "✅ BONNE - ZIP majoritairement conforme" code_sortie = 0 elif taux_reussite >= 60: qualite = "⚠️ ACCEPTABLE - Quelques améliorations nécessaires" code_sortie = 1 else: qualite = "❌ INSUFFISANTE - Corrections majeures requises" code_sortie = 2 print(f"\n🎯 QUALITÉ GLOBALE: {qualite}") # Informations sur le ZIP taille_zip = os.path.getsize(self.nom_zip) taille_mb = taille_zip / (1024 * 1024) print(f"\n📦 Informations ZIP:") print(f" 📁 Nom: {self.nom_zip}") print(f" 📏 Taille: {taille_mb:.2f} MB") return code_sortie def nettoyer_dossier_temp(self): """Nettoyer le dossier temporaire""" if self.dossier_temp and os.path.exists(self.dossier_temp): shutil.rmtree(self.dossier_temp) print(f"🧹 Dossier temporaire supprimé") def executer_verification_complete(self): """Exécuter la vérification complète""" print("🔍 VÉRIFICATION COMPLÈTE DU ZIP VWB") print("=" * 50) if not os.path.exists(self.nom_zip): print(f"❌ Fichier ZIP introuvable: {self.nom_zip}") return 1 try: # Extraire le ZIP self.extraire_zip_temporaire() # Exécuter les vérifications self.verifier_structure_generale() self.verifier_conformite_attribution() self.verifier_version_info() self.verifier_readme() self.compter_fichiers_par_type() # Générer le rapport code_sortie = self.generer_rapport_final() return code_sortie except Exception as e: print(f"💥 Erreur critique: {e}") return 3 finally: self.nettoyer_dossier_temp() def main(): """Fonction principale""" import sys if len(sys.argv) != 2: print("Usage: python3 verifier_zip_vwb.py ") return 1 nom_zip = sys.argv[1] verificateur = VerificateurZipVWB(nom_zip) try: return verificateur.executer_verification_complete() except KeyboardInterrupt: print("\n⚠️ Vérification interrompue") verificateur.nettoyer_dossier_temp() return 2 if __name__ == "__main__": import sys sys.exit(main())