clarity.main
1# coding: utf-8 2# Main dev: alextoutcourt72 3# New dev: MJVhack 4import os 5import sys 6import argparse 7from platform import system 8from time import sleep 9from typing import List 10import pkgutil 11import importlib 12import inspect 13 14# imports robustes 15from clarity.core import ( 16 Colors, ClarityToolsCollection, ClarityTool, hr, menu, 17 expand_path, ensure_dir, clear, AppConfig 18) 19def build_tools() -> List: 20 """Charge dynamiquement tous les outils depuis le package clarity.tools.""" 21 tools = [] 22 # Chemin vers le package des outils 23 import clarity.tools 24 package = clarity.tools 25 package_path = package.__path__ 26 package_name = package.__name__ 27 28 # Parcourt tous les modules dans le package des outils 29 for _, module_name, _ in pkgutil.walk_packages(package_path, package_name + '.'): 30 try: 31 # Importe le module dynamiquement 32 module = importlib.import_module(module_name) 33 34 # Inspecte le module à la recherche de classes d'outils 35 for name, obj in inspect.getmembers(module, inspect.isclass): 36 # Vérifie si la classe est une sous-classe de ClarityTool(sCollection) 37 # et si elle vient bien de notre module (pas une classe importée) 38 if (issubclass(obj, ClarityTool) or issubclass(obj, ClarityToolsCollection)) and obj.__module__ == module_name: 39 # Ignore les classes de base elles-mêmes 40 if obj not in [ClarityTool, ClarityToolsCollection]: 41 # Instancie l'outil et l'ajoute à la liste 42 tools.append(obj()) 43 print(f"{Colors.GREEN}[+] Outil chargé: {obj.TITLE}{Colors.RESET}") 44 45 except ImportError as e: 46 print(f"{Colors.YELLOW}[!] Module d'outil ignoré (erreur d'import): {module_name}. {e}{Colors.RESET}") 47 except Exception as e: 48 print(f"{Colors.RED}[X] Erreur critique en chargeant {module_name}: {e}{Colors.RESET}") 49 50 # Trie les outils par leur titre pour un affichage cohérent 51 tools.sort(key=lambda x: x.TITLE) 52 return tools 53 54all_tools = build_tools() 55 56class AllTools(ClarityToolsCollection): 57 TITLE = "All tools" 58 TOOLS = all_tools 59 def show_info(self): 60 clear() 61 menu() 62 63# -------- Gestion du chemin d’installation ----------------------------------- 64def platform_pathfile() -> str: 65 plat = system() 66 if plat == 'Windows': 67 return expand_path(r"~\claritytoolpath.txt") 68 elif plat in ('Linux', 'Darwin'): 69 return expand_path("~/.claritytoolpath") 70 else: 71 print("Your Platform is not supported") 72 sys.exit(0) 73 74def default_home() -> str: 75 return expand_path("~/.clarity-tool") if system() != 'Windows' else expand_path(r"~\Clarity-Tool") 76 77def load_home(set_to: str | None = None, reset=False) -> str: 78 env = os.environ.get("CLARITY_HOME") 79 pathfile = platform_pathfile() 80 81 if reset and os.path.exists(pathfile): 82 try: os.remove(pathfile) 83 except OSError: pass 84 85 if set_to: 86 home = expand_path(set_to) 87 with open(pathfile, "w", encoding="utf-8") as f: 88 f.write(home) 89 return home 90 91 if env: 92 return expand_path(env) 93 94 if os.path.exists(pathfile): 95 try: 96 with open(pathfile, "r", encoding="utf-8") as f: 97 return expand_path(f.readline().strip()) 98 except Exception: 99 pass 100 101 home = default_home() 102 with open(pathfile, "w", encoding="utf-8") as f: 103 f.write(home) 104 return home 105 106# -------- CLI ---------------------------------------------------------------- 107def parse_args(): 108 p = argparse.ArgumentParser(description="Clarity Tool – modern CLI/UX") 109 p.add_argument("--list", action="store_true", help="Lister tous les outils disponibles") 110 p.add_argument("--run", type=str, help="Nom EXACT d’un outil à ouvrir") 111 p.add_argument("--action", type=str, help="Nom EXACT d’une action de l’outil (ex: Update)") 112 p.add_argument("--set-path", type=str, help="Définir le répertoire d’installation") 113 p.add_argument("--reset-path", action="store_true", help="Réinitialiser le répertoire d’installation") 114 return p.parse_args() 115 116def find_tool_by_title(title: str): 117 for t in all_tools: 118 if t.TITLE == title: 119 return t 120 return None 121 122def main(): 123 args = parse_args() 124 125 # ---- Gestion du chemin d'installation ---- 126 try: 127 home = load_home(set_to=args.set_path, reset=args.reset_path) 128 ensure_dir(home) # S'assure que le dossier existe, avec gestion d'erreur 129 AppConfig.HOME_PATH = home # Stocke le chemin dans la config globale 130 print(f"{Colors.DIM}Répertoire de travail des outils : {home}{Colors.RESET}") 131 except Exception as e: 132 print(f"{Colors.RED}Erreur critique avec le répertoire d'installation: {e}{Colors.RESET}") 133 sys.exit(1) 134 135 # ---- Chargement et exécution ---- 136 # Le reste du code fonctionne sans changer de répertoire de travail. 137 138 # Mode liste 139 if args.list: 140 print(hr()) 141 print(f"{Colors.BOLD}Outils disponibles:{Colors.RESET}") 142 for t in all_tools: 143 print(f" - {t.TITLE}") 144 print(hr()) 145 sys.exit(0) 146 147 # Mode run non interactif 148 if args.run: 149 tool = find_tool_by_title(args.run) 150 if not tool: 151 print(f"{Colors.RED}Outil introuvable: {args.run}{Colors.RESET}") 152 sys.exit(2) 153 if args.action: 154 # chercher une option qui matche 155 for label, fn in getattr(tool, "OPTIONS", []): 156 if label == args.action: 157 ret = fn() 158 sys.exit(0 if ret in (None, 0) else ret) 159 print(f"{Colors.RED}Action introuvable sur {tool.TITLE}: {args.action}{Colors.RESET}") 160 sys.exit(3) 161 else: 162 # ouvre le menu de l’outil 163 tool.show_options(parent=AllTools()) 164 sys.exit(0) 165 166 # Mode interactif 167 AllTools().show_options() 168 169if __name__ == "__main__": 170 try: 171 main() 172 except KeyboardInterrupt: 173 print(f"\n{Colors.GRAY}Fermeture demandée. À bientôt!{Colors.RESET}") 174 sleep(0.5)
def
build_tools() -> List:
20def build_tools() -> List: 21 """Charge dynamiquement tous les outils depuis le package clarity.tools.""" 22 tools = [] 23 # Chemin vers le package des outils 24 import clarity.tools 25 package = clarity.tools 26 package_path = package.__path__ 27 package_name = package.__name__ 28 29 # Parcourt tous les modules dans le package des outils 30 for _, module_name, _ in pkgutil.walk_packages(package_path, package_name + '.'): 31 try: 32 # Importe le module dynamiquement 33 module = importlib.import_module(module_name) 34 35 # Inspecte le module à la recherche de classes d'outils 36 for name, obj in inspect.getmembers(module, inspect.isclass): 37 # Vérifie si la classe est une sous-classe de ClarityTool(sCollection) 38 # et si elle vient bien de notre module (pas une classe importée) 39 if (issubclass(obj, ClarityTool) or issubclass(obj, ClarityToolsCollection)) and obj.__module__ == module_name: 40 # Ignore les classes de base elles-mêmes 41 if obj not in [ClarityTool, ClarityToolsCollection]: 42 # Instancie l'outil et l'ajoute à la liste 43 tools.append(obj()) 44 print(f"{Colors.GREEN}[+] Outil chargé: {obj.TITLE}{Colors.RESET}") 45 46 except ImportError as e: 47 print(f"{Colors.YELLOW}[!] Module d'outil ignoré (erreur d'import): {module_name}. {e}{Colors.RESET}") 48 except Exception as e: 49 print(f"{Colors.RED}[X] Erreur critique en chargeant {module_name}: {e}{Colors.RESET}") 50 51 # Trie les outils par leur titre pour un affichage cohérent 52 tools.sort(key=lambda x: x.TITLE) 53 return tools
Charge dynamiquement tous les outils depuis le package clarity.tools.
all_tools =
[<clarity.tools.automsf.Msfvenom object>, <clarity.tools.wordlist_tools.bobsrck object>, <clarity.tools.ddos.DDOS object>, <clarity.tools.sql_tool.SqlInjectionTools object>, <clarity.tools.sql_tool.Sqlmap object>, <clarity.tools.tool_manager.UninstallTool object>, <clarity.tools.tool_manager.ToolManager object>, <clarity.tools.tool_manager.UpdateTool object>, <clarity.tools.xss_tools.XssTools object>, <clarity.tools.xss_tools.XSStrike object>, <clarity.tools.wordlist_tools.WordlistTools object>]
57class AllTools(ClarityToolsCollection): 58 TITLE = "All tools" 59 TOOLS = all_tools 60 def show_info(self): 61 clear() 62 menu()
TOOLS =
[<clarity.tools.automsf.Msfvenom object>, <clarity.tools.wordlist_tools.bobsrck object>, <clarity.tools.ddos.DDOS object>, <clarity.tools.sql_tool.SqlInjectionTools object>, <clarity.tools.sql_tool.Sqlmap object>, <clarity.tools.tool_manager.UninstallTool object>, <clarity.tools.tool_manager.ToolManager object>, <clarity.tools.tool_manager.UpdateTool object>, <clarity.tools.xss_tools.XssTools object>, <clarity.tools.xss_tools.XSStrike object>, <clarity.tools.wordlist_tools.WordlistTools object>]
def
platform_pathfile() -> str:
def
default_home() -> str:
def
load_home(set_to: str | None = None, reset=False) -> str:
78def load_home(set_to: str | None = None, reset=False) -> str: 79 env = os.environ.get("CLARITY_HOME") 80 pathfile = platform_pathfile() 81 82 if reset and os.path.exists(pathfile): 83 try: os.remove(pathfile) 84 except OSError: pass 85 86 if set_to: 87 home = expand_path(set_to) 88 with open(pathfile, "w", encoding="utf-8") as f: 89 f.write(home) 90 return home 91 92 if env: 93 return expand_path(env) 94 95 if os.path.exists(pathfile): 96 try: 97 with open(pathfile, "r", encoding="utf-8") as f: 98 return expand_path(f.readline().strip()) 99 except Exception: 100 pass 101 102 home = default_home() 103 with open(pathfile, "w", encoding="utf-8") as f: 104 f.write(home) 105 return home
def
parse_args():
108def parse_args(): 109 p = argparse.ArgumentParser(description="Clarity Tool – modern CLI/UX") 110 p.add_argument("--list", action="store_true", help="Lister tous les outils disponibles") 111 p.add_argument("--run", type=str, help="Nom EXACT d’un outil à ouvrir") 112 p.add_argument("--action", type=str, help="Nom EXACT d’une action de l’outil (ex: Update)") 113 p.add_argument("--set-path", type=str, help="Définir le répertoire d’installation") 114 p.add_argument("--reset-path", action="store_true", help="Réinitialiser le répertoire d’installation") 115 return p.parse_args()
def
find_tool_by_title(title: str):
def
main():
123def main(): 124 args = parse_args() 125 126 # ---- Gestion du chemin d'installation ---- 127 try: 128 home = load_home(set_to=args.set_path, reset=args.reset_path) 129 ensure_dir(home) # S'assure que le dossier existe, avec gestion d'erreur 130 AppConfig.HOME_PATH = home # Stocke le chemin dans la config globale 131 print(f"{Colors.DIM}Répertoire de travail des outils : {home}{Colors.RESET}") 132 except Exception as e: 133 print(f"{Colors.RED}Erreur critique avec le répertoire d'installation: {e}{Colors.RESET}") 134 sys.exit(1) 135 136 # ---- Chargement et exécution ---- 137 # Le reste du code fonctionne sans changer de répertoire de travail. 138 139 # Mode liste 140 if args.list: 141 print(hr()) 142 print(f"{Colors.BOLD}Outils disponibles:{Colors.RESET}") 143 for t in all_tools: 144 print(f" - {t.TITLE}") 145 print(hr()) 146 sys.exit(0) 147 148 # Mode run non interactif 149 if args.run: 150 tool = find_tool_by_title(args.run) 151 if not tool: 152 print(f"{Colors.RED}Outil introuvable: {args.run}{Colors.RESET}") 153 sys.exit(2) 154 if args.action: 155 # chercher une option qui matche 156 for label, fn in getattr(tool, "OPTIONS", []): 157 if label == args.action: 158 ret = fn() 159 sys.exit(0 if ret in (None, 0) else ret) 160 print(f"{Colors.RED}Action introuvable sur {tool.TITLE}: {args.action}{Colors.RESET}") 161 sys.exit(3) 162 else: 163 # ouvre le menu de l’outil 164 tool.show_options(parent=AllTools()) 165 sys.exit(0) 166 167 # Mode interactif 168 AllTools().show_options()