88import requests
99import config
1010import logger
11+ import enum
1112
1213class Window ():
1314 """Manage visual interface"""
@@ -19,7 +20,12 @@ def __init__(self) -> None:
1920 print ('Window initialization started.' )
2021 self .cfg = config .Config ()
2122 self .logger = logger .Logger ()
22- self .__version__ = '1.0.2.0'
23+ self .__version__ = '1.0.2.1'
24+
25+ self .functions = {
26+ 'Test Connect' : self .connect ,
27+ 'Mass Execute' : self .execute_cmd ,
28+ }
2329
2430 def callback (self , sender , data ):
2531 """
@@ -43,101 +49,116 @@ def create(self) -> None:
4349 no_move = True ,
4450 tag = 'w_main' ):
4551
46- with dpg .group (horizontal = True ):
47- dpg .add_button (label = 'Refresh' ,
48- tag = 'b_refresh' ,
49- callback = lambda : dpg .configure_item (item = 'servers_list' ,
50- items = self .cfg .get_servers ()))
51- dpg .add_button (label = 'Connect' ,
52- tag = 'b_connect' ,
53- callback = self .connect )
54-
55- dpg .add_button (label = 'Execute' ,
56- tag = 'b_execute' ,
57- callback = self .execute_cmd )
58-
59- dpg .add_listbox (items = self .cfg .get_servers (),
60- num_items = 8 ,
61- width = 200 ,
62- tag = 'servers_list' )
63-
64- with dpg .group (horizontal = True ):
65- dpg .add_button (label = 'Show Info' ,
66- tag = 'b_unsafe' ,
67- callback = self .show_context )
68- dpg .add_button (label = 'Hide Info' ,
69- tag = 'b_safe' ,
70- callback = self .hide_context )
71-
72- with dpg .group (horizontal = True ):
73- dpg .add_text (label = 'IP' ,
74- show = False ,
75- color = (0 , 255 , 0 ),
76- tag = 'ip' ,)
77- dpg .add_text (label = 'Username' ,
78- show = False ,
79- color = (220 , 0 , 40 ),
80- tag = 'username' )
81- dpg .add_text (label = 'Password' ,
82- show = False ,
83- color = (220 , 0 , 40 ),
84- tag = 'password' )
85- dpg .add_separator ()
86- dpg .add_input_text (label = 'Commands File' ,
87- default_value = 'commands' ,
88- width = 200 ,
89- tag = 'i_commands' )
90-
91- with dpg .group (horizontal = True ):
92- dpg .add_button (label = 'Clear' ,
93- tag = 'b_clear' ,
94- callback = lambda : dpg .set_value ('i_commands' , '' ))
95- dpg .add_radio_button (label = 'File extension' ,
96- items = ['.txt' , '.json' ],
97- default_value = '.txt' ,
98- horizontal = True ,
99- tag = 'rb_extension' )
100- dpg .add_separator ()
101- dpg .add_input_text (label = '' ,
102- readonly = True ,
103- multiline = True ,
104- enabled = False ,
105- width = 350 ,
106- height = 150 ,
107- tag = 'i_logs_area' )
108-
109- with dpg .group (horizontal = True ):
110- dpg .add_button (label = 'Clear Logs' ,
111- callback = self .logger .reset )
112-
113- dpg .add_button (label = 'Update' ,
114- show = False ,
115- tag = 'b_update' ,
116- callback = lambda : webbrowser .open (
117- 'https://github.com/OpsecGuy/Awesome-Server-Manager'
118- ))
52+ with dpg .tab_bar (label = "Menu" ):
53+ with dpg .tab (label = "Main" ):
54+ with dpg .group (horizontal = True ):
55+ dpg .add_button (label = 'Refresh List' ,
56+ tag = 'b_refresh' ,
57+ callback = lambda : dpg .configure_item (item = 'servers_list' ,
58+ items = self .cfg .get_servers ()))
59+ with dpg .group (horizontal = True ):
60+ dpg .add_listbox (items = self .cfg .get_servers (),
61+ num_items = 8 ,
62+ width = 200 ,
63+ tag = 'servers_list' )
64+ with dpg .group (horizontal = False ):
65+ dpg .add_text (label = 'IP' ,
66+ show = False ,
67+ color = (0 , 255 , 0 ),
68+ tag = 'ip' ,)
69+ dpg .add_text (label = 'Username' ,
70+ show = False ,
71+ color = (220 , 0 , 40 ),
72+ tag = 'username' )
73+ dpg .add_text (label = 'Password' ,
74+ show = False ,
75+ color = (220 , 0 , 40 ),
76+ tag = 'password' )
77+ dpg .add_separator ()
78+ dpg .add_input_text (label = 'Commands File' ,
79+ default_value = 'commands' ,
80+ width = 200 ,
81+ tag = 'i_commands' )
82+
83+ with dpg .group (horizontal = True ):
84+ dpg .add_radio_button (label = 'File extension' ,
85+ items = ['.txt' , '.json' ],
86+ default_value = '.txt' ,
87+ horizontal = True ,
88+ tag = 'rb_extension' )
89+ dpg .add_separator ()
90+ dpg .add_combo (items = tuple (self .functions .keys ()), tag = 'i_function' )
91+ dpg .add_button (label = 'Start' , tag = 'b_start' , callback = lambda : self .functions .get (f"{ dpg .get_value ('i_function' )} " )())
92+ dpg .add_button (label = 'Update Client' ,
93+ show = False ,
94+ tag = 'b_update' ,
95+ callback = lambda : webbrowser .open (
96+ 'https://github.com/OpsecGuy/Awesome-Server-Manager/releases'
97+ ))
98+ with dpg .tab (label = "Logs" ):
99+ dpg .add_input_text (label = '' ,
100+ readonly = True ,
101+ multiline = True ,
102+ enabled = False ,
103+ width = 350 ,
104+ height = 150 ,
105+ tag = 'i_logs_area' )
106+ with dpg .group (horizontal = True ):
107+ dpg .add_button (label = 'Clear Logs' ,
108+ callback = self .logger .reset )
109+ with dpg .tab (label = "Settings" ):
110+ dpg .add_checkbox (label = 'Show Server Info' , tag = 'c_show_server_info' )
111+ dpg .add_input_float (label = 'Server timeout' ,
112+ default_value = 3.0 ,
113+ min_value = 1.0 ,
114+ max_value = 15.0 ,
115+ min_clamped = True ,
116+ max_clamped = True ,
117+ format = '%.1f' ,
118+ width = 200 ,
119+ tag = 'i_server_timeout' )
120+
121+ # Tooltips area
122+ with dpg .tooltip (parent = 'c_show_server_info' ):
123+ dpg .add_text ('Shows/Hides server info in Main tab.\n ip\n login\n password\n ' )
124+ with dpg .tooltip (parent = 'i_server_timeout' ):
125+ dpg .add_text ('Sets connection timeout for all functions.' )
126+ with dpg .tooltip (parent = 'i_commands' ):
127+ dpg .add_text ('Sets name of file storing commands.\n Provide file name only!' )
119128
120129 def update (self ) -> None :
121130 """
122131 Keeps GUI updated when changes are done.
123132 """
133+ last_changed = False
124134 while True :
125135 if os .path .exists (self .cfg .config_path ) is False :
126136 self .logger .log (f'Could not find { self .cfg .config_file } .\n \
127137 New config has been created.' )
128138 self .cfg .create_example ()
129139
130- dpg .set_value ('ip' , self .cfg .get_value (dpg .get_value ('servers_list' ), 'IP' ))
131- dpg .set_value ('username' , self .cfg .get_value (dpg .get_value ('servers_list' ), 'username' ))
132- dpg .set_value ('password' , self .cfg .get_value (dpg .get_value ('servers_list' ), 'password' ))
140+ if dpg .get_value ('c_show_server_info' ) == True :
141+ last_changed = True
142+ if last_changed == True :
143+ self .show_context ()
144+ dpg .set_value ('ip' , self .cfg .get_value (dpg .get_value ('servers_list' ), 'IP' ))
145+ dpg .set_value ('username' , self .cfg .get_value (dpg .get_value ('servers_list' ), 'username' ))
146+ dpg .set_value ('password' , self .cfg .get_value (dpg .get_value ('servers_list' ), 'password' ))
147+ else :
148+ last_changed = False
149+ self .hide_context ()
150+
151+ # Static
133152 dpg .set_value ('i_logs_area' , '\n ' .join (self .logger .logs_buffer ))
134153
154+ # Resizable
135155 vp_width = dpg .get_viewport_width ()
136156 vp_height = dpg .get_viewport_height ()
137157 dpg .configure_item (item = 'w_main' , width = vp_width - 5 )
138158 dpg .configure_item (item = 'w_main' , height = vp_height - 5 )
139159 dpg .configure_item (item = 'i_logs_area' , width = vp_width - 30 )
140-
160+
161+ # Version check
141162 if self .get_current_version () != self .__version__ :
142163 dpg .configure_item ('b_update' , show = True )
143164
@@ -252,13 +273,13 @@ def connect(self) -> bool:
252273 client = paramiko .SSHClient ()
253274 client .set_missing_host_key_policy (paramiko .AutoAddPolicy ())
254275 if self .is_valid (protection = 'light' ):
255- self .logger .log (f'[CONNECT] Connecting to { dpg .get_value ("ip " )} ' )
276+ self .logger .log (f'[CONNECT] Connecting to { self . cfg . get_value ( dpg .get_value ("servers_list" ), "IP " )} ' )
256277 try :
257- client .connect (hostname = dpg .get_value ('ip' ),
278+ client .connect (hostname = self . cfg . get_value ( dpg .get_value ("servers_list" ), "IP" ),
258279 port = int (self .cfg .get_value (dpg .get_value ('servers_list' ), 'port' )),
259- username = dpg .get_value (' username' ),
260- password = dpg .get_value (' password' ),
261- timeout = 3.0 )
280+ username = self . cfg . get_value ( dpg .get_value ("servers_list" ), " username" ),
281+ password = self . cfg . get_value ( dpg .get_value ("servers_list" ), " password" ),
282+ timeout = dpg . get_value ( 'i_server_timeout' ) )
262283 client .close ()
263284 self .logger .log ('[CONNECT] Task Completed!' )
264285 except socket .timeout :
@@ -274,23 +295,23 @@ def execute_cmd(self) -> bool:
274295 client = paramiko .SSHClient ()
275296 client .set_missing_host_key_policy (paramiko .AutoAddPolicy ())
276297 if self .is_valid (protection = 'full' ):
277- self .logger .log (f'[EXECUTE] Connecting to { dpg .get_value ("ip " )} ' )
298+ self .logger .log (f'[EXECUTE] Connecting to { self . cfg . get_value ( dpg .get_value ("servers_list" ), "IP " )} ' )
278299 try :
279- client .connect (hostname = dpg .get_value ('ip' ),
300+ client .connect (hostname = self . cfg . get_value ( dpg .get_value ("servers_list" ), "IP" ),
280301 port = int (self .cfg .get_value (dpg .get_value ('servers_list' ), 'port' )),
281- username = dpg .get_value (' username' ),
282- password = dpg .get_value (' password' ),
283- timeout = 3.0 )
302+ username = self . cfg . get_value ( dpg .get_value ("servers_list" ), " username" ),
303+ password = self . cfg . get_value ( dpg .get_value ("servers_list" ), " password" ),
304+ timeout = dpg . get_value ( 'i_server_timeout' ) )
284305 except socket .timeout :
285306 self .logger .log ('[EXECUTE] Fail: Server Timed out!' )
286307 return
287308
288309 try :
289- with open (f'log_{ dpg .get_value ("ip " )} .txt' , 'w+' , encoding = 'utf-8' ) as log_file :
290- self .logger .log (f'[EXECUTE] Writing server logs to log_{ dpg .get_value ("ip " )} .txt' )
310+ with open (f'log_{ self . cfg . get_value ( dpg .get_value ("servers_list" ), "IP " )} .txt' , 'w+' , encoding = 'utf-8' ) as log_file :
311+ self .logger .log (f'[EXECUTE] Writing server logs to log_{ self . cfg . get_value ( dpg .get_value ("servers_list" ), "IP " )} .txt' )
291312 try :
292313 stdin , stdout , stderr = client .exec_command (self .parse_command ())
293- self .logger .log ('[EXECUTE] Commands executed correctly! ' )
314+ self .logger .log ('[EXECUTE] Executing commands... ' )
294315 except paramiko .SSHException :
295316 self .logger .log ('[EXECUTE] Failed to execute commands!' )
296317 return
0 commit comments