1+ from rich .console import Console
2+ from rich .panel import Panel
3+ from rich .table import Table
4+ from rich import box
5+ from rich .traceback import install
6+ from rich .theme import Theme
7+
18import os
29import sys
310import webbrowser
411from platform import system
512from traceback import print_exc
6- from typing import Callable
7- from typing import List
8- from typing import Tuple
13+ from typing import Callable , List , Tuple
14+
15+ # Enable rich tracebacks
16+ install ()
17+ _theme = Theme ({"purple" : "#7B61FF" })
18+ console = Console (theme = _theme )
919
1020
1121def clear_screen ():
@@ -24,153 +34,159 @@ def validate_input(ip, val_range):
2434
2535
2636class HackingTool (object ):
27- # About the HackingTool
28- TITLE : str = "" # used to show info in the menu
37+ TITLE : str = ""
2938 DESCRIPTION : str = ""
30-
3139 INSTALL_COMMANDS : List [str ] = []
3240 INSTALLATION_DIR : str = ""
33-
3441 UNINSTALL_COMMANDS : List [str ] = []
35-
3642 RUN_COMMANDS : List [str ] = []
37-
3843 OPTIONS : List [Tuple [str , Callable ]] = []
39-
4044 PROJECT_URL : str = ""
4145
42- def __init__ (self , options = None , installable : bool = True ,
43- runnable : bool = True ):
46+ def __init__ (self , options = None , installable = True , runnable = True ):
4447 options = options or []
4548 if isinstance (options , list ):
4649 self .OPTIONS = []
4750 if installable :
48- self .OPTIONS .append ((' Install' , self .install ))
51+ self .OPTIONS .append ((" Install" , self .install ))
4952 if runnable :
50- self .OPTIONS .append ((' Run' , self .run ))
53+ self .OPTIONS .append ((" Run" , self .run ))
5154 self .OPTIONS .extend (options )
5255 else :
53- raise Exception (
54- "options must be a list of (option_name, option_fn) tuples" )
56+ raise Exception ("options must be a list of (option_name, option_fn) tuples" )
5557
5658 def show_info (self ):
57- desc = self .DESCRIPTION
59+ desc = f"[cyan] { self .DESCRIPTION } [/cyan]"
5860 if self .PROJECT_URL :
59- desc += '\n \t [*] '
60- desc += self .PROJECT_URL
61- os .system (f'echo "{ desc } "|boxes -d boy | lolcat' )
61+ desc += f"\n [green]🔗 { self .PROJECT_URL } [/green]"
62+ console .print (Panel (desc , title = f"[bold purple]{ self .TITLE } [/bold purple]" , border_style = "purple" , box = box .DOUBLE ))
6263
63- def show_options (self , parent = None ):
64+ def show_options (self , parent = None ):
6465 clear_screen ()
6566 self .show_info ()
67+
68+ table = Table (title = "Options" , box = box .SIMPLE_HEAVY )
69+ table .add_column ("No." , style = "bold cyan" , justify = "center" )
70+ table .add_column ("Action" , style = "bold yellow" )
71+
6672 for index , option in enumerate (self .OPTIONS ):
67- print (f"[{ index + 1 } ] { option [0 ]} " )
73+ table .add_row (str (index + 1 ), option [0 ])
74+
6875 if self .PROJECT_URL :
69- print (f"[{ 98 } ] Open project page" )
70- print (f"[{ 99 } ] Back to { parent .TITLE if parent is not None else 'Exit' } " )
71- option_index = input ("Select an option : " ).strip ()
76+ table .add_row ("98" , "Open Project Page" )
77+ table .add_row ("99" , f"Back to { parent .TITLE if parent else 'Exit' } " )
78+
79+ console .print (table )
80+
81+ option_index = input ("\n [?] Select an option: " ).strip ()
7282 try :
7383 option_index = int (option_index )
7484 if option_index - 1 in range (len (self .OPTIONS )):
7585 ret_code = self .OPTIONS [option_index - 1 ][1 ]()
7686 if ret_code != 99 :
77- input ("\n \ n Press ENTER to continue:" ). strip ( )
87+ input ("\n Press [Enter] to continue..." )
7888 elif option_index == 98 :
7989 self .show_project_page ()
8090 elif option_index == 99 :
8191 if parent is None :
8292 sys .exit ()
8393 return 99
8494 except (TypeError , ValueError ):
85- print ("Please enter a valid option" )
86- input ("\n \ n Press ENTER to continue:" ). strip ( )
95+ console . print ("[red]⚠ Please enter a valid option.[/red] " )
96+ input ("\n Press [Enter] to continue..." )
8797 except Exception :
88- print_exc ( )
89- input ("\n \ n Press ENTER to continue:" ). strip ( )
90- return self .show_options (parent = parent )
98+ console . print_exception ( show_locals = True )
99+ input ("\n Press [Enter] to continue..." )
100+ return self .show_options (parent = parent )
91101
92- def before_install (self ):
93- pass
102+ def before_install (self ): pass
94103
95104 def install (self ):
96105 self .before_install ()
97106 if isinstance (self .INSTALL_COMMANDS , (list , tuple )):
98107 for INSTALL_COMMAND in self .INSTALL_COMMANDS :
108+ console .print (f"[yellow]→ { INSTALL_COMMAND } [/yellow]" )
99109 os .system (INSTALL_COMMAND )
100110 self .after_install ()
101111
102112 def after_install (self ):
103- print ("Successfully installed!" )
113+ console . print ("[green]✔ Successfully installed![/green] " )
104114
105115 def before_uninstall (self ) -> bool :
106- """ Ask for confirmation from the user and return """
107116 return True
108117
109118 def uninstall (self ):
110119 if self .before_uninstall ():
111120 if isinstance (self .UNINSTALL_COMMANDS , (list , tuple )):
112121 for UNINSTALL_COMMAND in self .UNINSTALL_COMMANDS :
122+ console .print (f"[red]→ { UNINSTALL_COMMAND } [/red]" )
113123 os .system (UNINSTALL_COMMAND )
114124 self .after_uninstall ()
115125
116- def after_uninstall (self ):
117- pass
126+ def after_uninstall (self ): pass
118127
119- def before_run (self ):
120- pass
128+ def before_run (self ): pass
121129
122130 def run (self ):
123131 self .before_run ()
124132 if isinstance (self .RUN_COMMANDS , (list , tuple )):
125133 for RUN_COMMAND in self .RUN_COMMANDS :
134+ console .print (f"[cyan]⚙ Running:[/cyan] [bold]{ RUN_COMMAND } [/bold]" )
126135 os .system (RUN_COMMAND )
127136 self .after_run ()
128137
129- def after_run (self ):
130- pass
138+ def after_run (self ): pass
131139
132- def is_installed (self , dir_to_check = None ):
133- print ("Unimplemented: DO NOT USE" )
140+ def is_installed (self , dir_to_check = None ):
141+ console . print ("[yellow]⚠ Unimplemented: DO NOT USE[/yellow] " )
134142 return "?"
135143
136144 def show_project_page (self ):
145+ console .print (f"[blue]🌐 Opening project page: { self .PROJECT_URL } [/blue]" )
137146 webbrowser .open_new_tab (self .PROJECT_URL )
138147
139148
140149class HackingToolsCollection (object ):
141- TITLE : str = "" # used to show info in the menu
150+ TITLE : str = ""
142151 DESCRIPTION : str = ""
143- TOOLS = [] # type : List[Any[HackingTool, HackingToolsCollection] ]
152+ TOOLS : List = [ ]
144153
145154 def __init__ (self ):
146155 pass
147156
148157 def show_info (self ):
149- os .system ("figlet -f standard -c {} | lolcat" .format (self .TITLE ))
150- # os.system(f'echo "{self.DESCRIPTION}"|boxes -d boy | lolcat')
151- # print(self.DESCRIPTION)
158+ console .rule (f"[bold purple]{ self .TITLE } [/bold purple]" , style = "purple" )
159+ console .print (f"[italic cyan]{ self .DESCRIPTION } [/italic cyan]\n " )
152160
153- def show_options (self , parent = None ):
161+ def show_options (self , parent = None ):
154162 clear_screen ()
155163 self .show_info ()
164+
165+ table = Table (title = "Available Tools" , box = box .MINIMAL_DOUBLE_HEAD )
166+ table .add_column ("No." , justify = "center" , style = "bold cyan" )
167+ table .add_column ("Tool Name" , style = "bold yellow" )
168+
156169 for index , tool in enumerate (self .TOOLS ):
157- print (f"[{ index } { tool .TITLE } " )
158- print (f"[{ 99 } ] Back to { parent .TITLE if parent is not None else 'Exit' } " )
159- tool_index = input ("Choose a tool to proceed: " ).strip ()
170+ table .add_row (str (index ), tool .TITLE )
171+
172+ table .add_row ("99" , f"Back to { parent .TITLE if parent else 'Exit' } " )
173+ console .print (table )
174+
175+ tool_index = input ("\n [?] Choose a tool: " ).strip ()
160176 try :
161177 tool_index = int (tool_index )
162178 if tool_index in range (len (self .TOOLS )):
163- ret_code = self .TOOLS [tool_index ].show_options (parent = self )
179+ ret_code = self .TOOLS [tool_index ].show_options (parent = self )
164180 if ret_code != 99 :
165- input ("\n \ n Press ENTER to continue:" ). strip ( )
181+ input ("\n Press [Enter] to continue..." )
166182 elif tool_index == 99 :
167183 if parent is None :
168184 sys .exit ()
169185 return 99
170186 except (TypeError , ValueError ):
171- print ("Please enter a valid option" )
172- input ("\n \ n Press ENTER to continue:" ). strip ( )
187+ console . print ("[red]⚠ Please enter a valid option.[/red] " )
188+ input ("\n Press [Enter] to continue..." )
173189 except Exception :
174- print_exc ( )
175- input ("\n \ n Press ENTER to continue:" ). strip ( )
176- return self .show_options (parent = parent )
190+ console . print_exception ( show_locals = True )
191+ input ("\n Press [Enter] to continue..." )
192+ return self .show_options (parent = parent )
0 commit comments