From 81690e3c7c4753d96c46ea53dcb4230a0d23bb34 Mon Sep 17 00:00:00 2001 From: Hardik Zinzuvadiya <25708027+Z4nzu@users.noreply.github.com> Date: Sun, 15 Mar 2026 18:12:35 +0530 Subject: [PATCH] Feature: Install all tools in a category (option 97) HackingToolsCollection.show_options(): - Count not-installed tools using is_installed property - Show option 97 'Install all (N not installed)' when N > 0 - On select: iterates all not-installed tools, calls tool.install() with progress counter (1/N, 2/N, ...) and error handling per tool - Hidden when all tools are already installed - Updated inline help to mention option 97 --- core.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core.py b/core.py index b2bbd9b..5e3cd8e 100644 --- a/core.py +++ b/core.py @@ -61,8 +61,9 @@ def _show_inline_help(): (" Navigation\n", "bold white"), (" ─────────────────────────────────\n", "dim"), (" 1–N ", "bold cyan"), ("select item\n", "white"), + (" 97 ", "bold cyan"), ("install all (in category)\n", "white"), (" 99 ", "bold cyan"), ("go back\n", "white"), - (" 98 ", "bold cyan"), ("open project page\n", "white"), + (" 98 ", "bold cyan"), ("open project page / archived\n", "white"), (" ? ", "bold cyan"), ("show this help\n", "white"), (" q ", "bold cyan"), ("quit hackingtool\n", "white"), ), @@ -333,6 +334,13 @@ class HackingToolsCollection: status = "[green]✔[/green]" if tool.is_installed else "[dim]✘[/dim]" table.add_row(str(index), status, tool.TITLE, desc) + # Count not-installed tools for "Install All" label + not_installed = [t for t in active if not t.is_installed] + if not_installed: + table.add_row( + "[bold green]97[/bold green]", "", + f"[bold green]Install all ({len(not_installed)} not installed)[/bold green]", "", + ) if archived: table.add_row("[dim]98[/dim]", "", f"[archived]Archived tools ({len(archived)})[/archived]", "") if incompatible: @@ -362,6 +370,18 @@ class HackingToolsCollection: if choice == 99: return + elif choice == 97 and not_installed: + console.print(Panel( + f"[bold]Installing {len(not_installed)} tools...[/bold]", + border_style="green", box=box.ROUNDED, + )) + for i, tool in enumerate(not_installed, start=1): + console.print(f"\n[bold cyan]({i}/{len(not_installed)})[/bold cyan] {tool.TITLE}") + try: + tool.install() + except Exception: + console.print(f"[error]✘ Failed: {tool.TITLE}[/error]") + Prompt.ask("\n[dim]Press Enter to continue[/dim]", default="") elif choice == 98 and archived: self._show_archived_tools() elif 1 <= choice <= len(active):