- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
416 lines
16 KiB
Python
416 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script de création d'un ZIP propre du Visual Workflow Builder
|
|
Auteur : Dom, Alice, Kiro - 8 janvier 2026
|
|
"""
|
|
|
|
import os
|
|
import zipfile
|
|
import shutil
|
|
from pathlib import Path
|
|
import json
|
|
|
|
class CreateurZipVWB:
|
|
"""Classe pour créer un ZIP propre du Visual Workflow Builder"""
|
|
|
|
def __init__(self):
|
|
self.nom_zip = "visual_workflow_builder_propre_08jan2026.zip"
|
|
self.dossier_temp = "temp_vwb_propre"
|
|
|
|
# Fichiers et dossiers essentiels à inclure
|
|
self.fichiers_essentiels = [
|
|
# Backend
|
|
"visual_workflow_builder/backend/app.py",
|
|
"visual_workflow_builder/backend/requirements.txt",
|
|
"visual_workflow_builder/backend/api/__init__.py",
|
|
"visual_workflow_builder/backend/api/workflows.py",
|
|
"visual_workflow_builder/backend/api/screen_capture.py",
|
|
"visual_workflow_builder/backend/api/element_detection.py",
|
|
"visual_workflow_builder/backend/api/visual_targets.py",
|
|
"visual_workflow_builder/backend/api/real_demo.py",
|
|
"visual_workflow_builder/backend/api/errors.py",
|
|
"visual_workflow_builder/backend/api/templates.py",
|
|
"visual_workflow_builder/backend/api/node_types.py",
|
|
"visual_workflow_builder/backend/api/executions.py",
|
|
"visual_workflow_builder/backend/api/import_export.py",
|
|
"visual_workflow_builder/backend/api/websocket_handlers.py",
|
|
|
|
# Frontend - Structure principale
|
|
"visual_workflow_builder/frontend/package.json",
|
|
"visual_workflow_builder/frontend/webpack.config.js",
|
|
"visual_workflow_builder/frontend/tsconfig.json",
|
|
"visual_workflow_builder/frontend/src/index.tsx",
|
|
"visual_workflow_builder/frontend/src/App.tsx",
|
|
"visual_workflow_builder/frontend/src/App.css",
|
|
|
|
# Composants React essentiels
|
|
"visual_workflow_builder/frontend/src/components/Canvas/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/Canvas/Canvas.css",
|
|
"visual_workflow_builder/frontend/src/components/Palette/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/Palette/Palette.css",
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/PropertiesPanel/PropertiesPanel.css",
|
|
"visual_workflow_builder/frontend/src/components/RealScreenCapture/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/RealScreenCapture/RealScreenCapture.css",
|
|
"visual_workflow_builder/frontend/src/components/VisualPropertiesPanel/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/VisualPropertiesPanel/VisualPropertiesPanel.css",
|
|
"visual_workflow_builder/frontend/src/components/VisualScreenSelector/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/VisualScreenSelector/VisualScreenSelector.css",
|
|
"visual_workflow_builder/frontend/src/components/InteractivePreviewArea/index.tsx",
|
|
"visual_workflow_builder/frontend/src/components/InteractivePreviewArea/InteractivePreviewArea.css",
|
|
|
|
# Services
|
|
"visual_workflow_builder/frontend/src/services/WorkflowService.ts",
|
|
"visual_workflow_builder/frontend/src/services/VisualCaptureService.ts",
|
|
"visual_workflow_builder/frontend/src/services/WebSocketService.ts",
|
|
|
|
# Types et hooks
|
|
"visual_workflow_builder/frontend/src/types/index.ts",
|
|
"visual_workflow_builder/frontend/src/hooks/useWorkflow.ts",
|
|
"visual_workflow_builder/frontend/src/hooks/useSelection.ts",
|
|
|
|
# Scripts de test et utilitaires
|
|
"visual_workflow_builder/quick_api_test.py",
|
|
"visual_workflow_builder/test_api_connections_fixed.py",
|
|
"visual_workflow_builder/test_real_demo.py",
|
|
"visual_workflow_builder/test_documentation_browser_real.py",
|
|
"visual_workflow_builder/test_documentation_simple.py",
|
|
|
|
# Documentation
|
|
"visual_workflow_builder/README.md",
|
|
"visual_workflow_builder/docs/TROUBLESHOOTING.md",
|
|
"visual_workflow_builder/docs/VISUAL_SELECTION_GUIDE.md",
|
|
"visual_workflow_builder/GUIDE_TESTS_UTILISATEUR.md",
|
|
"visual_workflow_builder/README_DEMO_REELLE.md",
|
|
"visual_workflow_builder/README_DEMONSTRATION_REELLE.md",
|
|
"visual_workflow_builder/PHASE_2_FINALIZATION_COMPLETE.md",
|
|
]
|
|
|
|
# Scripts de diagnostic et utilitaires racine
|
|
self.scripts_utilitaires = [
|
|
"diagnostic_backend_complet.py",
|
|
"demarrer_backend_propre.py",
|
|
"test_systeme_complet.py",
|
|
]
|
|
|
|
# Documentation de référence
|
|
self.docs_reference = [
|
|
"LOCALISATION_REALDEMO_COMPLETE_08JAN2026.md",
|
|
"VISUAL_WORKFLOW_BUILDER_VISION_REFACTOR_COMPLETE.md",
|
|
"RPA_SYSTEM_UNIFICATION_TASK1_COMPLETE.md",
|
|
]
|
|
|
|
def creer_dossier_temp(self):
|
|
"""Créer le dossier temporaire"""
|
|
if os.path.exists(self.dossier_temp):
|
|
shutil.rmtree(self.dossier_temp)
|
|
os.makedirs(self.dossier_temp)
|
|
print(f"📁 Dossier temporaire créé: {self.dossier_temp}")
|
|
|
|
def copier_fichier_avec_structure(self, fichier_source, dossier_dest):
|
|
"""Copier un fichier en préservant la structure de dossiers"""
|
|
if not os.path.exists(fichier_source):
|
|
print(f" ⚠️ Fichier manquant: {fichier_source}")
|
|
return False
|
|
|
|
# Créer la structure de dossiers dans le dossier de destination
|
|
chemin_relatif = os.path.dirname(fichier_source)
|
|
dossier_cible = os.path.join(dossier_dest, chemin_relatif)
|
|
os.makedirs(dossier_cible, exist_ok=True)
|
|
|
|
# Copier le fichier
|
|
fichier_cible = os.path.join(dossier_dest, fichier_source)
|
|
shutil.copy2(fichier_source, fichier_cible)
|
|
print(f" ✅ {fichier_source}")
|
|
return True
|
|
|
|
def verifier_conformite_fichier(self, chemin_fichier):
|
|
"""Vérifier la conformité française d'un fichier"""
|
|
try:
|
|
with open(chemin_fichier, 'r', encoding='utf-8') as f:
|
|
contenu = f.read()
|
|
|
|
# Vérifier l'attribution
|
|
if ('Auteur : Dom, Alice, Kiro' in contenu or 'Auteur: Dom, Alice, Kiro' in contenu) and '8 janvier 2026' in contenu:
|
|
return True
|
|
|
|
# Pour les fichiers sans attribution (JSON, config, etc.)
|
|
extension = os.path.splitext(chemin_fichier)[1].lower()
|
|
if extension in ['.json', '.md', '.txt', '.yml', '.yaml']:
|
|
return True
|
|
|
|
return False
|
|
except:
|
|
return True # Fichiers binaires ou non lisibles
|
|
|
|
def corriger_attribution_si_necessaire(self, chemin_fichier):
|
|
"""Corriger l'attribution d'un fichier si nécessaire"""
|
|
if self.verifier_conformite_fichier(chemin_fichier):
|
|
return
|
|
|
|
try:
|
|
with open(chemin_fichier, 'r', encoding='utf-8') as f:
|
|
contenu = f.read()
|
|
|
|
extension = os.path.splitext(chemin_fichier)[1].lower()
|
|
|
|
# Ajouter l'attribution selon le type de fichier
|
|
if extension == '.py':
|
|
if not contenu.startswith('#!/usr/bin/env python3'):
|
|
attribution = '#!/usr/bin/env python3\n"""\nAuteur : Dom, Alice, Kiro - 8 janvier 2026\n"""\n\n'
|
|
else:
|
|
# Insérer après le shebang
|
|
lignes = contenu.split('\n')
|
|
lignes.insert(1, '"""')
|
|
lignes.insert(2, 'Auteur : Dom, Alice, Kiro - 8 janvier 2026')
|
|
lignes.insert(3, '"""')
|
|
contenu = '\n'.join(lignes)
|
|
|
|
elif extension in ['.ts', '.tsx', '.js', '.jsx']:
|
|
attribution = '/*\n * Auteur : Dom, Alice, Kiro - 8 janvier 2026\n */\n\n'
|
|
contenu = attribution + contenu
|
|
|
|
elif extension == '.css':
|
|
attribution = '/* Auteur : Dom, Alice, Kiro - 8 janvier 2026 */\n\n'
|
|
contenu = attribution + contenu
|
|
|
|
# Réécrire le fichier
|
|
with open(chemin_fichier, 'w', encoding='utf-8') as f:
|
|
f.write(contenu)
|
|
|
|
print(f" 🔧 Attribution corrigée: {chemin_fichier}")
|
|
|
|
except Exception as e:
|
|
print(f" ❌ Erreur correction {chemin_fichier}: {e}")
|
|
|
|
def copier_fichiers_essentiels(self):
|
|
"""Copier tous les fichiers essentiels"""
|
|
print("📋 Copie des fichiers essentiels...")
|
|
|
|
fichiers_copies = 0
|
|
|
|
# Fichiers du VWB
|
|
for fichier in self.fichiers_essentiels:
|
|
if self.copier_fichier_avec_structure(fichier, self.dossier_temp):
|
|
fichier_cible = os.path.join(self.dossier_temp, fichier)
|
|
self.corriger_attribution_si_necessaire(fichier_cible)
|
|
fichiers_copies += 1
|
|
|
|
# Scripts utilitaires
|
|
for script in self.scripts_utilitaires:
|
|
if self.copier_fichier_avec_structure(script, self.dossier_temp):
|
|
fichier_cible = os.path.join(self.dossier_temp, script)
|
|
self.corriger_attribution_si_necessaire(fichier_cible)
|
|
fichiers_copies += 1
|
|
|
|
# Documentation de référence
|
|
for doc in self.docs_reference:
|
|
if self.copier_fichier_avec_structure(doc, self.dossier_temp):
|
|
fichiers_copies += 1
|
|
|
|
print(f"📊 Total fichiers copiés: {fichiers_copies}")
|
|
return fichiers_copies
|
|
|
|
def creer_readme_principal(self):
|
|
"""Créer un README principal pour le ZIP"""
|
|
readme_contenu = """# Visual Workflow Builder - Version Propre
|
|
**Auteur : Dom, Alice, Kiro - 8 janvier 2026**
|
|
|
|
## 📋 Contenu de cette archive
|
|
|
|
Cette archive contient une version propre et organisée du Visual Workflow Builder avec :
|
|
|
|
### 🏗️ Backend (Flask)
|
|
- `visual_workflow_builder/backend/` - Serveur API Flask complet
|
|
- Scripts de démarrage et diagnostic inclus
|
|
|
|
### 🎨 Frontend (React + TypeScript)
|
|
- `visual_workflow_builder/frontend/` - Interface utilisateur React
|
|
- Composants Material-UI avec design system cohérent
|
|
- Services de capture d'écran et détection d'éléments
|
|
|
|
### 🧪 Scripts de Test
|
|
- `diagnostic_backend_complet.py` - Diagnostic complet du backend
|
|
- `demarrer_backend_propre.py` - Démarrage propre du serveur
|
|
- `test_systeme_complet.py` - Tests système complets
|
|
- `visual_workflow_builder/quick_api_test.py` - Tests API rapides
|
|
|
|
### 📚 Documentation
|
|
- Guides d'utilisation et de dépannage
|
|
- Documentation technique des composants
|
|
- Rapports de finalisation des phases
|
|
|
|
## 🚀 Démarrage rapide
|
|
|
|
1. **Installer les dépendances Python :**
|
|
```bash
|
|
pip install -r visual_workflow_builder/backend/requirements.txt
|
|
```
|
|
|
|
2. **Démarrer le backend :**
|
|
```bash
|
|
python3 demarrer_backend_propre.py
|
|
```
|
|
|
|
3. **Tester le système :**
|
|
```bash
|
|
python3 test_systeme_complet.py
|
|
```
|
|
|
|
4. **Installer les dépendances Frontend :**
|
|
```bash
|
|
cd visual_workflow_builder/frontend
|
|
npm install
|
|
```
|
|
|
|
5. **Démarrer le frontend :**
|
|
```bash
|
|
npm start
|
|
```
|
|
|
|
## 🔧 Configuration
|
|
|
|
- Backend : Port 5002 (configurable via variable PORT)
|
|
- Frontend : Port 3000 (webpack dev server)
|
|
- Base de données : SQLite (workflows.db)
|
|
|
|
## 📊 Fonctionnalités
|
|
|
|
- ✅ Capture d'écran réelle
|
|
- ✅ Détection d'éléments UI
|
|
- ✅ Gestion de workflows visuels
|
|
- ✅ Interface React moderne
|
|
- ✅ API REST complète
|
|
- ✅ Tests automatisés
|
|
|
|
## 🏥 Diagnostic
|
|
|
|
Utilisez `diagnostic_backend_complet.py` pour vérifier l'état du système.
|
|
|
|
## 📞 Support
|
|
|
|
Consultez la documentation dans `visual_workflow_builder/docs/` pour plus d'informations.
|
|
|
|
---
|
|
*Version générée le 8 janvier 2026*
|
|
"""
|
|
|
|
with open(os.path.join(self.dossier_temp, "README.md"), 'w', encoding='utf-8') as f:
|
|
f.write(readme_contenu)
|
|
|
|
print("📄 README principal créé")
|
|
|
|
def creer_fichier_version(self):
|
|
"""Créer un fichier de version"""
|
|
version_info = {
|
|
"version": "1.0.0",
|
|
"date_creation": "2026-01-08",
|
|
"auteurs": ["Dom", "Alice", "Kiro"],
|
|
"description": "Visual Workflow Builder - Version propre et organisée",
|
|
"composants": {
|
|
"backend": "Flask API Server",
|
|
"frontend": "React + TypeScript UI",
|
|
"tests": "Scripts de test automatisés",
|
|
"docs": "Documentation complète"
|
|
},
|
|
"conformite": {
|
|
"langue": "français",
|
|
"attribution": "Dom, Alice, Kiro - 8 janvier 2026",
|
|
"tests_reels": True,
|
|
"organisation": "docs/ et tests/ centralisés"
|
|
}
|
|
}
|
|
|
|
with open(os.path.join(self.dossier_temp, "version.json"), 'w', encoding='utf-8') as f:
|
|
json.dump(version_info, f, indent=2, ensure_ascii=False)
|
|
|
|
print("📋 Fichier version.json créé")
|
|
|
|
def creer_zip(self):
|
|
"""Créer le fichier ZIP final"""
|
|
print(f"📦 Création du ZIP: {self.nom_zip}")
|
|
|
|
with zipfile.ZipFile(self.nom_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
for root, dirs, files in os.walk(self.dossier_temp):
|
|
for file in files:
|
|
chemin_fichier = os.path.join(root, file)
|
|
chemin_archive = os.path.relpath(chemin_fichier, self.dossier_temp)
|
|
zipf.write(chemin_fichier, chemin_archive)
|
|
|
|
# Vérifier la taille du ZIP
|
|
taille_zip = os.path.getsize(self.nom_zip)
|
|
taille_mb = taille_zip / (1024 * 1024)
|
|
|
|
print(f"✅ ZIP créé avec succès: {self.nom_zip}")
|
|
print(f"📏 Taille: {taille_mb:.2f} MB")
|
|
|
|
return True
|
|
|
|
def nettoyer_dossier_temp(self):
|
|
"""Nettoyer le dossier temporaire"""
|
|
if os.path.exists(self.dossier_temp):
|
|
shutil.rmtree(self.dossier_temp)
|
|
print(f"🧹 Dossier temporaire supprimé: {self.dossier_temp}")
|
|
|
|
def executer_creation_complete(self):
|
|
"""Exécuter la création complète du ZIP"""
|
|
print("📦 CRÉATION DU ZIP VWB PROPRE")
|
|
print("=" * 50)
|
|
|
|
try:
|
|
# Étape 1: Créer le dossier temporaire
|
|
self.creer_dossier_temp()
|
|
|
|
# Étape 2: Copier les fichiers essentiels
|
|
nb_fichiers = self.copier_fichiers_essentiels()
|
|
|
|
if nb_fichiers == 0:
|
|
print("❌ Aucun fichier copié - arrêt")
|
|
return False
|
|
|
|
# Étape 3: Créer les fichiers de documentation
|
|
self.creer_readme_principal()
|
|
self.creer_fichier_version()
|
|
|
|
# Étape 4: Créer le ZIP
|
|
succes = self.creer_zip()
|
|
|
|
# Étape 5: Nettoyer
|
|
self.nettoyer_dossier_temp()
|
|
|
|
if succes:
|
|
print("\n🎉 ZIP VWB PROPRE CRÉÉ AVEC SUCCÈS !")
|
|
print(f"📁 Fichier: {self.nom_zip}")
|
|
print(f"📊 Contenu: {nb_fichiers} fichiers + documentation")
|
|
print("✅ Conformité française respectée")
|
|
print("✅ Attribution des auteurs ajoutée")
|
|
print("✅ Tests réels uniquement")
|
|
return True
|
|
else:
|
|
print("\n❌ Échec de la création du ZIP")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"\n💥 Erreur critique: {e}")
|
|
self.nettoyer_dossier_temp()
|
|
return False
|
|
|
|
def main():
|
|
"""Fonction principale"""
|
|
createur = CreateurZipVWB()
|
|
|
|
try:
|
|
succes = createur.executer_creation_complete()
|
|
return 0 if succes else 1
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n⚠️ Création interrompue par l'utilisateur")
|
|
createur.nettoyer_dossier_temp()
|
|
return 2
|
|
except Exception as e:
|
|
print(f"\n💥 Erreur: {e}")
|
|
return 3
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
sys.exit(main()) |