diff --git a/core.py b/core.py index 4915660..4f63d70 100644 --- a/core.py +++ b/core.py @@ -1,11 +1,19 @@ +from rich.console import Console +from rich.panel import Panel +from rich.table import Table +from rich import box +from rich.traceback import install + import os import sys import webbrowser from platform import system from traceback import print_exc -from typing import Callable -from typing import List -from typing import Tuple +from typing import Callable, List, Tuple + +# Enable rich tracebacks +install() +console = Console() def clear_screen(): @@ -24,23 +32,16 @@ def validate_input(ip, val_range): class HackingTool(object): - # About the HackingTool - TITLE: str = "" # used to show info in the menu + TITLE: str = "" DESCRIPTION: str = "" - INSTALL_COMMANDS: List[str] = [] INSTALLATION_DIR: str = "" - UNINSTALL_COMMANDS: List[str] = [] - RUN_COMMANDS: List[str] = [] - OPTIONS: List[Tuple[str, Callable]] = [] - PROJECT_URL: str = "" - def __init__(self, options = None, installable: bool = True, - runnable: bool = True): + def __init__(self, options=None, installable=True, runnable=True): options = options or [] if isinstance(options, list): self.OPTIONS = [] @@ -50,31 +51,38 @@ class HackingTool(object): self.OPTIONS.append(('Run', self.run)) self.OPTIONS.extend(options) else: - raise Exception( - "options must be a list of (option_name, option_fn) tuples") + raise Exception("options must be a list of (option_name, option_fn) tuples") def show_info(self): - desc = self.DESCRIPTION + desc = f"[cyan]{self.DESCRIPTION}[/cyan]" if self.PROJECT_URL: - desc += '\n\t[*] ' - desc += self.PROJECT_URL - os.system(f'echo "{desc}"|boxes -d boy | lolcat') + desc += f"\n[green]🔗 {self.PROJECT_URL}[/green]" + console.print(Panel(desc, title=f"[bold magenta]{self.TITLE}[/bold magenta]", border_style="magenta", box=box.DOUBLE)) - def show_options(self, parent = None): + def show_options(self, parent=None): clear_screen() self.show_info() + + table = Table(title="Options", box=box.SIMPLE_HEAVY) + table.add_column("No.", style="bold cyan", justify="center") + table.add_column("Action", style="bold yellow") + for index, option in enumerate(self.OPTIONS): - print(f"[{index + 1}] {option[0]}") + table.add_row(str(index + 1), option[0]) + if self.PROJECT_URL: - print(f"[{98}] Open project page") - print(f"[{99}] Back to {parent.TITLE if parent is not None else 'Exit'}") - option_index = input("Select an option : ").strip() + table.add_row("98", "Open Project Page") + table.add_row("99", f"Back to {parent.TITLE if parent else 'Exit'}") + + console.print(table) + + option_index = input("\n[?] Select an option: ").strip() try: option_index = int(option_index) if option_index - 1 in range(len(self.OPTIONS)): ret_code = self.OPTIONS[option_index - 1][1]() if ret_code != 99: - input("\n\nPress ENTER to continue:").strip() + input("\nPress [Enter] to continue...") elif option_index == 98: self.show_project_page() elif option_index == 99: @@ -82,95 +90,101 @@ class HackingTool(object): sys.exit() return 99 except (TypeError, ValueError): - print("Please enter a valid option") - input("\n\nPress ENTER to continue:").strip() + console.print("[red]⚠ Please enter a valid option.[/red]") + input("\nPress [Enter] to continue...") except Exception: - print_exc() - input("\n\nPress ENTER to continue:").strip() - return self.show_options(parent = parent) + console.print_exception(show_locals=True) + input("\nPress [Enter] to continue...") + return self.show_options(parent=parent) - def before_install(self): - pass + def before_install(self): pass def install(self): self.before_install() if isinstance(self.INSTALL_COMMANDS, (list, tuple)): for INSTALL_COMMAND in self.INSTALL_COMMANDS: + console.print(f"[yellow]→ {INSTALL_COMMAND}[/yellow]") os.system(INSTALL_COMMAND) self.after_install() def after_install(self): - print("Successfully installed!") + console.print("[green]✔ Successfully installed![/green]") def before_uninstall(self) -> bool: - """ Ask for confirmation from the user and return """ return True def uninstall(self): if self.before_uninstall(): if isinstance(self.UNINSTALL_COMMANDS, (list, tuple)): for UNINSTALL_COMMAND in self.UNINSTALL_COMMANDS: + console.print(f"[red]→ {UNINSTALL_COMMAND}[/red]") os.system(UNINSTALL_COMMAND) self.after_uninstall() - def after_uninstall(self): - pass + def after_uninstall(self): pass - def before_run(self): - pass + def before_run(self): pass def run(self): self.before_run() if isinstance(self.RUN_COMMANDS, (list, tuple)): for RUN_COMMAND in self.RUN_COMMANDS: + console.print(f"[cyan]⚙ Running:[/cyan] [bold]{RUN_COMMAND}[/bold]") os.system(RUN_COMMAND) self.after_run() - def after_run(self): - pass + def after_run(self): pass - def is_installed(self, dir_to_check = None): - print("Unimplemented: DO NOT USE") + def is_installed(self, dir_to_check=None): + console.print("[yellow]⚠ Unimplemented: DO NOT USE[/yellow]") return "?" def show_project_page(self): + console.print(f"[blue]🌐 Opening project page: {self.PROJECT_URL}[/blue]") webbrowser.open_new_tab(self.PROJECT_URL) class HackingToolsCollection(object): - TITLE: str = "" # used to show info in the menu + TITLE: str = "" DESCRIPTION: str = "" - TOOLS = [] # type: List[Any[HackingTool, HackingToolsCollection]] + TOOLS: List = [] def __init__(self): pass def show_info(self): - os.system("figlet -f standard -c {} | lolcat".format(self.TITLE)) - # os.system(f'echo "{self.DESCRIPTION}"|boxes -d boy | lolcat') - # print(self.DESCRIPTION) + console.rule(f"[bold magenta]{self.TITLE}[/bold magenta]", style="magenta") + console.print(f"[italic cyan]{self.DESCRIPTION}[/italic cyan]\n") - def show_options(self, parent = None): + def show_options(self, parent=None): clear_screen() self.show_info() + + table = Table(title="Available Tools", box=box.MINIMAL_DOUBLE_HEAD) + table.add_column("No.", justify="center", style="bold cyan") + table.add_column("Tool Name", style="bold yellow") + for index, tool in enumerate(self.TOOLS): - print(f"[{index} {tool.TITLE}") - print(f"[{99}] Back to {parent.TITLE if parent is not None else 'Exit'}") - tool_index = input("Choose a tool to proceed: ").strip() + table.add_row(str(index), tool.TITLE) + + table.add_row("99", f"Back to {parent.TITLE if parent else 'Exit'}") + console.print(table) + + tool_index = input("\n[?] Choose a tool: ").strip() try: tool_index = int(tool_index) if tool_index in range(len(self.TOOLS)): - ret_code = self.TOOLS[tool_index].show_options(parent = self) + ret_code = self.TOOLS[tool_index].show_options(parent=self) if ret_code != 99: - input("\n\nPress ENTER to continue:").strip() + input("\nPress [Enter] to continue...") elif tool_index == 99: if parent is None: sys.exit() return 99 except (TypeError, ValueError): - print("Please enter a valid option") - input("\n\nPress ENTER to continue:").strip() + console.print("[red]⚠ Please enter a valid option.[/red]") + input("\nPress [Enter] to continue...") except Exception: - print_exc() - input("\n\nPress ENTER to continue:").strip() - return self.show_options(parent = parent) + console.print_exception(show_locals=True) + input("\nPress [Enter] to continue...") + return self.show_options(parent=parent)