Redesign header: full HACKING TOOL art + ? and q in all sub-menus

hackingtool.py:
- Replace 6-line "HT" art with full 12-line "HACKING TOOL" block letters
- Right side gains 3 more info lines: python version, arch, status
- 12 art lines paired with 12 stat lines for consistent separator
- Layout optimized for wide terminals (100+ chars); gracefully
  truncates on narrow ones

core.py — ? and q support in all sub-menus:
- Add _show_inline_help() function: compact navigation reference
  (1-N select, 99 back, 98 project page, ? help, q quit)
- HackingTool.show_options(): parse ? → inline help, q → SystemExit
- HackingToolsCollection.show_options(): same ? and q handling
- Both menus now show hint bar: "Enter number · ? help · q quit"
- Prompt changed from "[?] Select" to ">" for consistency with main menu
- q/quit/exit raises SystemExit(0) to cleanly exit from any depth
This commit is contained in:
Hardik Zinzuvadiya 2026-03-15 17:28:21 +05:30
parent 6eb287e3ac
commit 7b1950c9a5
2 changed files with 71 additions and 21 deletions

53
core.py
View file

@ -9,6 +9,7 @@ from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
from rich.table import Table
from rich.text import Text
from rich.theme import Theme
from rich.traceback import install
@ -52,6 +53,26 @@ def validate_input(ip, val_range: list) -> int | None:
return None
def _show_inline_help():
"""Quick help available from any menu level."""
console.print(Panel(
Text.assemble(
(" Navigation\n", "bold white"),
(" ─────────────────────────────────\n", "dim"),
(" 1N ", "bold cyan"), ("select item\n", "white"),
(" 99 ", "bold cyan"), ("go back\n", "white"),
(" 98 ", "bold cyan"), ("open project page\n", "white"),
(" ? ", "bold cyan"), ("show this help\n", "white"),
(" q ", "bold cyan"), ("quit hackingtool\n", "white"),
),
title="[bold magenta] ? Quick Help [/bold magenta]",
border_style="magenta",
box=box.ROUNDED,
padding=(0, 2),
))
Prompt.ask("[dim]Press Enter to return[/dim]", default="")
class HackingTool:
TITLE: str = ""
DESCRIPTION: str = ""
@ -115,14 +136,24 @@ class HackingTool:
table.add_row("98", "Open Project Page")
table.add_row("99", f"Back to {parent.TITLE if parent else 'Main Menu'}")
console.print(table)
console.print(
"[dim] Enter number · [bold cyan]?[/bold cyan] help"
" · [bold cyan]q[/bold cyan] quit[/dim]"
)
raw = Prompt.ask("\n[bold cyan][?] Select an option[/bold cyan]", default="")
if not raw.strip():
raw = Prompt.ask("\n[bold cyan]>[/bold cyan]", default="").strip().lower()
if not raw:
continue
if raw in ("?", "help"):
_show_inline_help()
continue
if raw in ("q", "quit", "exit"):
raise SystemExit(0)
try:
choice = int(raw)
except ValueError:
console.print("[error]⚠ Please enter a number.[/error]")
console.print("[error]⚠ Enter a number, ? for help, or q to quit.[/error]")
Prompt.ask("[dim]Press Enter to continue[/dim]", default="")
continue
@ -278,14 +309,24 @@ class HackingToolsCollection:
table.add_row("99", f"Back to {parent.TITLE if parent else 'Main Menu'}", "")
console.print(table)
console.print(
"[dim] Enter number · [bold cyan]?[/bold cyan] help"
" · [bold cyan]q[/bold cyan] quit[/dim]"
)
raw = Prompt.ask("\n[bold cyan][?] Choose a tool[/bold cyan]", default="")
if not raw.strip():
raw = Prompt.ask("\n[bold cyan]>[/bold cyan]", default="").strip().lower()
if not raw:
continue
if raw in ("?", "help"):
_show_inline_help()
continue
if raw in ("q", "quit", "exit"):
raise SystemExit(0)
try:
choice = int(raw)
except ValueError:
console.print("[error]⚠ Please enter a number.[/error]")
console.print("[error]⚠ Enter a number, ? for help, or q to quit.[/error]")
continue
if choice == 99:

View file

@ -135,15 +135,21 @@ def show_help():
# ── Header: ASCII art + live system info ──────────────────────────────────────
# "HT" block-letter art — 6 lines, ~20 cols wide
_BANNER_ART = (
" ██╗ ██╗████████╗\n"
" ██║ ██║╚══██╔══╝\n"
" ███████║ ██║ \n"
" ██╔══██║ ██║ \n"
" ██║ ██║ ██║ \n"
" ╚═╝ ╚═╝ ╚═╝ "
)
# Full "HACKING TOOL" block-letter art — 12 lines, split layout with stats
_BANNER_ART = [
" ██╗ ██╗ █████╗ ██████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ",
" ██║ ██║██╔══██╗██╔════╝██║ ██╔╝██║████╗ ██║██╔════╝ ",
" ███████║███████║██║ █████╔╝ ██║██╔██╗ ██║██║ ███╗",
" ██╔══██║██╔══██║██║ ██╔═██╗ ██║██║╚██╗██║██║ ██║",
" ██║ ██║██║ ██║╚██████╗██║ ██╗██║██║ ╚████║╚██████╔╝",
" ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ",
" ████████╗ ██████╗ ██████╗ ██╗",
" ╚══██╔══╝██╔═══██╗██╔═══██╗██║",
" ██║ ██║ ██║██║ ██║██║",
" ██║ ██║ ██║██║ ██║██║",
" ██║ ╚██████╔╝╚██████╔╝███████╗",
" ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝",
]
_QUOTES = [
'"The quieter you become, the more you can hear."',
@ -198,9 +204,7 @@ def _sys_info() -> dict:
def _build_header() -> Panel:
info = _sys_info()
# Each art line paired with a stat line so the │ separator runs full height
art_lines = _BANNER_ART.split("\n") # 6 lines
# 12 stat lines paired with the 12 art lines
stat_lines = [
(" os ", info["os"][:34]),
(" kernel ", info["kernel"][:34]),
@ -208,6 +212,12 @@ def _build_header() -> Panel:
(" ip ", info["ip"]),
(" tools ", f"{len(all_tools)} categories · 150+ modules"),
(" session ", info["time"]),
("", ""),
(" python ", f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"),
(" arch ", platform.machine()),
(" status ", "✔ READY"),
("", ""),
("", ""),
]
grid = Table.grid(padding=0)
@ -216,10 +226,10 @@ def _build_header() -> Panel:
grid.add_column("lbl", no_wrap=True)
grid.add_column("val", no_wrap=True)
for art_line, (lbl_text, val_text) in zip(art_lines, stat_lines):
for art_line, (lbl_text, val_text) in zip(_BANNER_ART, stat_lines):
grid.add_row(
Text(art_line, style="bold bright_green"),
Text(" ", style="dim green"),
Text(" ", style="dim green"),
Text(lbl_text, style="dim green"),
Text(val_text, style="bright_green"),
)
@ -233,7 +243,6 @@ def _build_header() -> Panel:
body.add_row(Text(f" {quote}", style="italic dim"))
body.add_row(Text(" ⚠ For authorized security testing only",
style="bold dim red"))
body.add_row(Text(""))
return Panel(
body,