interface_demarrage.py

Bienvenue sur CFTPfr.fr Forums core interface_demarrage.py

  • Ce sujet est vide.
Affichage de 1 message (sur 1 au total)
  • Auteur
    Messages
  • #212
    Mario Da Conceicao
    Maître des clés

    Sauvegarde de travail — version du 25/07/2026. Contient les mécanismes Windows-only (STARTUPINFO, CREATE_NO_WINDOW) à réécrire pour Linux, et le bug connu "Lancer l’IA" (voir Tome 2).

    import tkinter as tk
    from tkinter import messagebox, simpledialog
    from pathlib import Path
    import subprocess
    import os
    import json
    import hashlib
    import secrets
    import importlib.util
    
    # --- Configuration des chemins (ABSOLUS) ---
    BASE_DIR = Path(r"D:\MIRA_Project")
    PYTHONW = Path(r"D:\MIRA_Project\WPy64-313130\python\pythonw.exe").resolve()
    MIRA_OS_FILE = Path(r"D:\MIRA_Project\mira_os\mira_os.py").resolve()
    CHAT_FILE = Path(r"D:\MIRA_Project\mira_ai\chat_ia.py").resolve()
    USERS_FILE = Path(r"D:\MIRA_Project\mira_ai\utilisateurs.json").resolve()
    PLUGINS_DIR = Path(r"D:\MIRA_Project\mira_ai\plugins").resolve()
    CONFIG_FILE = Path(r"D:\MIRA_Project\mira_ai\config.json").resolve()
    MIRA_LANG_FILE = Path(r"D:\MIRA_Project\mira_lang\main.py").resolve()
    
    # --- Fonctions de hachage des mots de passe ---
    def hacher_mot_de_passe(mot_de_passe: str) -> str:
        salt = secrets.token_hex(16)
        hash_mdp = hashlib.sha256((mot_de_passe + salt).encode("utf-8")).hexdigest()
        return f"{salt}:{hash_mdp}"
    
    def verifier_mot_de_passe(mot_de_passe: str, stocke: str) -> bool:
        try:
            salt, hash_stocke = stocke.split(":")
            return hashlib.sha256((mot_de_passe + salt).encode("utf-8")).hexdigest() == hash_stocke
        except Exception:
            return False
    
    # --- Gestion des plugins ---
    class PluginManager:
        def __init__(self, plugins_dir=PLUGINS_DIR):
            self.plugins_dir = Path(plugins_dir)
            self.plugins = {}
            self.charger_plugins()
    
        def charger_plugins(self):
            self.plugins = {}
            if not self.plugins_dir.exists():
                self.plugins_dir.mkdir(parents=True, exist_ok=True)
                return
            for file in self.plugins_dir.glob("*.py"):
                if file.name.startswith("_"):
                    continue
                try:
                    spec = importlib.util.spec_from_file_location(file.stem, file)
                    module = importlib.util.module_from_spec(spec)
                    spec.loader.exec_module(module)
                    if hasattr(module, "INTENTION") and hasattr(module, "executer"):
                        self.plugins[module.INTENTION] = module
                except Exception as e:
                    print(f"Erreur chargement plugin {file.name}: {e}")
    
        def executer(self, intention, message, app):
            module = self.plugins.get(intention)
            if module:
                try:
                    return module.executer(message, app)
                except Exception as e:
                    return f"Erreur dans le plugin '{intention}': {e}"
            return None
    
    # --- Interface principale ---
    class InterfaceDemarrage:
        def __init__(self):
            self.fenetre = tk.Tk()
            self.fenetre.title("MIRA_OS - Centre de contrôle")
            self.fenetre.geometry("600x550")
    
            (BASE_DIR / "mira_ai").mkdir(parents=True, exist_ok=True)
            PLUGINS_DIR.mkdir(parents=True, exist_ok=True)
    
            self.verifier_utilisateurs_par_defaut()
            self.plugin_manager = PluginManager()
            self.creer_interface()
    
        def verifier_utilisateurs_par_defaut(self):
            if not USERS_FILE.exists():
                try:
                    with open(USERS_FILE, "w", encoding="utf-8") as f:
                        json.dump({
                            "utilisateurs": [
                                {"nom": "admin", "mot_de_passe": hacher_mot_de_passe("admin123"), "role": "administrateur"}
                            ]
                        }, f, indent=4, ensure_ascii=False)
                except Exception as e:
                    messagebox.showerror("Erreur", f"Impossible de créer le fichier: {e}")
    
        def creer_interface(self):
            tk.Label(self.fenetre, text="Bienvenue dans MIRA_OS", font=("Arial", 16, "bold")).pack(pady=10)
    
            frame_boutons = tk.Frame(self.fenetre)
            frame_boutons.pack(pady=20)
    
            boutons = [
                ("🖥️ Lancer MIRA_OS", self.lancer_mira_os, "#4CAF50", 0, 0),
                ("🤖 Lancer l'IA", self.lancer_ia, "#2196F3", 0, 1),
                ("💬 Chat avec l'IA", self.lancer_chat, "#FF9800", 0, 2),
                ("📘 Lancer MIRA_LANG", self.lancer_lang, "#3F51B5", 1, 0),
                ("🔄 Mise à jour", self.mise_a_jour_ia, "#17A2B8", 1, 1),
                ("👤 Gérer les utilisateurs", self.gerer_utilisateurs, "#9C27B0", 1, 2),
                ("🔌 Recharger plugins", self.recharger_plugins, "#607D8B", 2, 0)
            ]
    
            for texte, commande, couleur, row, col in boutons:
                tk.Button(
                    frame_boutons,
                    text=texte,
                    command=commande,
                    width=15,
                    height=3,
                    font=("Arial", 10, "bold"),
                    bg=couleur,
                    fg="white"
                ).grid(row=row, column=col, padx=10, pady=10)
    
            tk.Button(
                self.fenetre,
                text="❌ Quitter",
                command=self.quitter,
                width=10,
                height=2,
                font=("Arial", 10, "bold"),
                bg="#F44336",
                fg="white"
            ).pack(pady=20)
    
        def lancer_processus(self, fichier_py):
            if not PYTHONW.exists():
                messagebox.showerror(
                    "Erreur critique",
                    f"pythonw.exe est introuvable.\n\n"
                    f"Chemin attendu :\n{PYTHONW}\n\n"
                    "Vérifiez que WPy64-313130 est installé dans D:\\MIRA_Project\\."
                )
                return
    
            if not fichier_py.exists():
                messagebox.showerror(
                    "Erreur critique",
                    f"Fichier introuvable.\n\n"
                    f"Chemin attendu :\n{fichier_py}\n\n"
                    "Vérifiez que le fichier existe et que le chemin est correct."
                )
                return
    
            try:
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                startupinfo.wShowWindow = subprocess.SW_HIDE
    
                process = subprocess.Popen(
                    [str(PYTHONW), str(fichier_py)],
                    cwd=str(fichier_py.parent),
                    startupinfo=startupinfo,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    text=True,
                    creationflags=subprocess.CREATE_NO_WINDOW
                )
    
                try:
                    stdout, stderr = process.communicate(timeout=1)
                    if process.returncode != 0:
                        messagebox.showerror(
                            "Erreur d'exécution",
                            f"Le script a échoué avec le code {process.returncode}.\n\n"
                            f"Erreur :\n{stderr}\n\n"
                            f"Sortie :\n{stdout}\n\n"
                            f"Fichier : {fichier_py}\n"
                            f"Dossier : {fichier_py.parent}"
                        )
                except subprocess.TimeoutExpired:
                    pass
    
            except FileNotFoundError as e:
                messagebox.showerror(
                    "Erreur système",
                    f"Fichier ou programme introuvable :\n{e}\n\n"
                    f"Vérifiez que :\n- {PYTHONW} existe\n- {fichier_py} existe"
                )
            except PermissionError as e:
                messagebox.showerror(
                    "Erreur de permissions",
                    f"Permission refusée pour exécuter :\n{e}\n\n"
                    "Essayez de lancer l'invite de commandes en tant qu'administrateur."
                )
            except Exception as e:
                messagebox.showerror(
                    "Erreur inattendue",
                    f"Impossible de lancer le processus :\n{e}\n\n"
                    f"Python : {PYTHONW}\nFichier : {fichier_py}"
                )
    
        def lancer_mira_os(self):
            self.lancer_processus(MIRA_OS_FILE)
    
        def lancer_ia(self):
            self.lancer_processus(MIRA_OS_FILE)  # Note: Ici, on lance MIRA_OS_FILE pour l'IA (à adapter si besoin)
    
        def lancer_chat(self):
            self.lancer_processus(CHAT_FILE)
    
        def lancer_lang(self):
            self.lancer_processus(MIRA_LANG_FILE)
    
        def mise_a_jour_ia(self):
            nouveaux_plugins = self.plugin_manager.charger_plugins()
            if nouveaux_plugins:
                messagebox.showinfo("Mise à jour", f"Nouveaux plugins détectés :\n- " + "\n- ".join(nouveaux_plugins))
            else:
                messagebox.showinfo("Mise à jour", "Aucun nouveau plugin détecté.")
    
        def gerer_utilisateurs(self):
            nom = simpledialog.askstring("Connexion", "Nom d'utilisateur :")
            if not nom:
                return
            mot_de_passe = simpledialog.askstring("Connexion", "Mot de passe :", show="*")
            if not mot_de_passe:
                return
            if self.verifier_utilisateur(nom, mot_de_passe):
                self.fenetre_utilisateurs()
            else:
                messagebox.showerror("Erreur", "Nom d'utilisateur ou mot de passe incorrect.")
    
        def verifier_utilisateur(self, nom, mot_de_passe):
            if not USERS_FILE.exists():
                return False
            try:
                with open(USERS_FILE, "r", encoding="utf-8") as f:
                    data = json.load(f)
                for utilisateur in data.get("utilisateurs", []):
                    if utilisateur["nom"] == nom and verifier_mot_de_passe(mot_de_passe, utilisateur["mot_de_passe"]):
                        return True
                return False
            except Exception:
                return False
    
        def fenetre_utilisateurs(self):
            fenetre_users = tk.Toplevel(self.fenetre)
            fenetre_users.title("Gestion des utilisateurs")
            fenetre_users.geometry("400x300")
    
            tk.Button(
                fenetre_users,
                text="➕ Ajouter un utilisateur",
                command=self.ajouter_utilisateur,
                width=30,
                height=2,
                font=("Arial", 10, "bold"),
                bg="#4CAF50",
                fg="white"
            ).pack(pady=10)
    
            tk.Button(
                fenetre_users,
                text="➖ Supprimer un utilisateur",
                command=self.supprimer_utilisateur,
                width=30,
                height=2,
                font=("Arial", 10, "bold"),
                bg="#F44336",
                fg="white"
            ).pack(pady=10)
    
        def ajouter_utilisateur(self):
            nom = simpledialog.askstring("Nouvel utilisateur", "Nom :")
            if not nom:
                return
            mot_de_passe = simpledialog.askstring("Nouvel utilisateur", "Mot de passe :", show="*")
            if not mot_de_passe:
                return
            role = simpledialog.askstring("Nouvel utilisateur", "Rôle :", initialvalue="utilisateur") or "utilisateur"
    
            try:
                if USERS_FILE.exists():
                    with open(USERS_FILE, "r", encoding="utf-8") as f:
                        data = json.load(f)
                else:
                    data = {"utilisateurs": []}
    
                for u in data["utilisateurs"]:
                    if u["nom"] == nom:
                        messagebox.showerror("Erreur", f"L'utilisateur {nom} existe déjà !")
                        return
    
                data["utilisateurs"].append({
                    "nom": nom,
                    "mot_de_passe": hacher_mot_de_passe(mot_de_passe),
                    "role": role
                })
    
                with open(USERS_FILE, "w", encoding="utf-8") as f:
                    json.dump(data, f, indent=4, ensure_ascii=False)
    
                messagebox.showinfo("Succès", f"Utilisateur {nom} ajouté !")
            except Exception as e:
                messagebox.showerror("Erreur", f"Erreur: {e}")
    
        def supprimer_utilisateur(self):
            nom = simpledialog.askstring("Supprimer un utilisateur", "Nom :")
            if not nom:
                return
            if not USERS_FILE.exists():
                messagebox.showerror("Erreur", "Aucun utilisateur.")
                return
            try:
                with open(USERS_FILE, "r", encoding="utf-8") as f:
                    data = json.load(f)
    
                utilisateurs = [u for u in data["utilisateurs"] if u["nom"] != nom]
                if len(utilisateurs) == len(data["utilisateurs"]):
                    messagebox.showerror("Erreur", f"Utilisateur {nom} introuvable.")
                    return
    
                data["utilisateurs"] = utilisateurs
                with open(USERS_FILE, "w", encoding="utf-8") as f:
                    json.dump(data, f, indent=4, ensure_ascii=False)
    
                messagebox.showinfo("Succès", f"Utilisateur {nom} supprimé !")
            except Exception as e:
                messagebox.showerror("Erreur", f"Erreur: {e}")
    
        def recharger_plugins(self):
            nouveaux = self.plugin_manager.charger_plugins()
            if nouveaux:
                messagebox.showinfo("Plugins", f"Nouveaux plugins chargés:\n- " + "\n- ".join(nouveaux))
            else:
                messagebox.showinfo("Plugins", "Aucun nouveau plugin détecté.")
    
        def quitter(self):
            self.fenetre.destroy()
    
        def run(self):
            self.fenetre.mainloop()
    
    if __name__ == "__main__":
        app = InterfaceDemarrage()
        app.run()
Affichage de 1 message (sur 1 au total)
  • Vous devez être connecté pour répondre à ce sujet.
Retour en haut