99
1010from prettytable import PrettyTable
1111
12- from logicytics import Log , execute , check , get , file_management , flag , DEBUG , DELETE_LOGS , config
12+ from logicytics import (
13+ Log ,
14+ execute ,
15+ check ,
16+ get ,
17+ file_management ,
18+ flag ,
19+ DEBUG ,
20+ DELETE_LOGS ,
21+ config ,
22+ )
1323
1424# Initialization
1525log = Log ({"log_level" : DEBUG , "delete_log" : DELETE_LOGS })
1626ACTION , SUB_ACTION = None , None
17- MAX_WORKERS = config .getint ("Settings" , "max_workers" , fallback = min (32 , (os .cpu_count () or 1 ) + 4 ))
27+ MAX_WORKERS = config .getint (
28+ "Settings" , "max_workers" , fallback = min (32 , (os .cpu_count () or 1 ) + 4 )
29+ )
1830log .debug (f"MAX_WORKERS: { MAX_WORKERS } " )
1931
2032
@@ -28,7 +40,9 @@ def __safe_remove(file_name: str, file_list: list[str] | set[str]) -> list[str]:
2840 if file_name in file_set :
2941 file_set .remove (file_name )
3042 else :
31- log .critical (f"The file { file_name } should exist in this directory - But was not found!" )
43+ log .critical (
44+ f"The file { file_name } should exist in this directory - But was not found!"
45+ )
3246 return list (file_set )
3347
3448 @staticmethod
@@ -63,17 +77,22 @@ def __generate_execution_list(self) -> list[str]:
6377 - Logs the final execution list for debugging purposes
6478 - Warns users about potential long execution times for certain actions
6579 """
66- execution_list = get .list_of_files ("." , only_extensions = (".py" , ".exe" , ".ps1" , ".bat" ),
67- exclude_files = ["Logicytics.py" ],
68- exclude_dirs = ["logicytics" , "SysInternal_Suite" ])
80+ execution_list = get .list_of_files (
81+ "." ,
82+ only_extensions = (".py" , ".exe" , ".ps1" , ".bat" ),
83+ exclude_files = ["Logicytics.py" ],
84+ exclude_dirs = ["logicytics" , "SysInternal_Suite" ],
85+ )
6986 files_to_remove = {
7087 "sensitive_data_miner.py" ,
7188 "dir_list.py" ,
7289 "tree.ps1" ,
7390 "vulnscan.py" ,
7491 "event_log.py" ,
7592 }
76- execution_list = [file for file in execution_list if file not in files_to_remove ]
93+ execution_list = [
94+ file for file in execution_list if file not in files_to_remove
95+ ]
7796
7897 if ACTION == "minimal" :
7998 execution_list = [
@@ -93,18 +112,23 @@ def __generate_execution_list(self) -> list[str]:
93112 "netadapter.ps1" ,
94113 "property_scraper.ps1" ,
95114 "window_feature_miner.ps1" ,
96- "tree.ps1"
115+ "tree.ps1" ,
97116 ]
98117
99118 elif ACTION == "modded" :
100119 # Add all files in MODS to execution list
101- execution_list = get .list_of_files ("../MODS" , only_extensions = (".py" , ".exe" , ".ps1" , ".bat" ),
102- append_file_list = execution_list , exclude_files = ["Logicytics.py" ],
103- exclude_dirs = ["logicytics" , "SysInternal_Suite" ])
120+ execution_list = get .list_of_files (
121+ "../MODS" ,
122+ only_extensions = (".py" , ".exe" , ".ps1" , ".bat" ),
123+ append_file_list = execution_list ,
124+ exclude_files = ["Logicytics.py" ],
125+ exclude_dirs = ["logicytics" , "SysInternal_Suite" ],
126+ )
104127
105128 elif ACTION == "depth" :
106129 log .warning (
107- "This flag will use clunky and huge scripts, and so may take a long time, but reap great rewards." )
130+ "This flag will use clunky and huge scripts, and so may take a long time, but reap great rewards."
131+ )
108132 files_to_append = {
109133 "sensitive_data_miner.py" ,
110134 "dir_list.py" ,
@@ -124,7 +148,9 @@ def __generate_execution_list(self) -> list[str]:
124148 exit (1 )
125149
126150 if len (execution_list ) == 0 :
127- log .critical ("Nothing is in the execution list.. This is due to faulty code or corrupted Logicytics files!" )
151+ log .critical (
152+ "Nothing is in the execution list.. This is due to faulty code or corrupted Logicytics files!"
153+ )
128154 exit (1 )
129155
130156 log .debug (f"Execution list length: { len (execution_list )} " )
@@ -163,8 +189,10 @@ def __threaded(self):
163189 """Executes scripts in parallel using threading."""
164190 log .debug ("Using threading" )
165191 with ThreadPoolExecutor (max_workers = MAX_WORKERS ) as executor :
166- futures = {executor .submit (self .__script_handler , script ): script
167- for script in self .execution_list }
192+ futures = {
193+ executor .submit (self .__script_handler , script ): script
194+ for script in self .execution_list
195+ }
168196
169197 for future in as_completed (futures ):
170198 script = futures [future ]
@@ -214,12 +242,15 @@ def __performance(self):
214242
215243 try :
216244 with open (
217- f"../ACCESS/LOGS/PERFORMANCE/Performance_Summary_"
218- f"{ datetime .now ().strftime ('%Y-%m-%d_%H-%M-%S' )} .txt" , "w"
245+ f"../ACCESS/LOGS/PERFORMANCE/Performance_Summary_"
246+ f"{ datetime .now ().strftime ('%Y-%m-%d_%H-%M-%S' )} .txt" ,
247+ "w" ,
219248 ) as f :
220249 f .write (table .get_string ())
221250 f .write ("\n Note: This test only measures execution time.\n " )
222- log .info ("Performance check complete! Performance log found in ACCESS/LOGS/PERFORMANCE" )
251+ log .info (
252+ "Performance check complete! Performance log found in ACCESS/LOGS/PERFORMANCE"
253+ )
223254 except Exception as e :
224255 log .error (f"Error writing performance log: { e } " )
225256
@@ -228,25 +259,31 @@ class SpecialAction:
228259 @staticmethod
229260 def update () -> tuple [str , str ]:
230261 """
231- Updates the repository by pulling the latest changes from the remote repository.
262+ Updates the repository by pulling the latest changes from the remote repository.
232263
233- This function navigates to the parent directory, pulls the latest changes using Git,
234- and then returns to the current working directory.
264+ This function navigates to the parent directory, pulls the latest changes using Git,
265+ and then returns to the current working directory.
235266
236- Returns:
237- str: The output from the git pull command.
238- """
267+ Returns:
268+ str: The output from the git pull command.
269+ """
239270 # Check if git command is available
240271 try :
241- if subprocess .run (["git" , "--version" ], capture_output = True ).returncode != 0 :
272+ if (
273+ subprocess .run (["git" , "--version" ], capture_output = True ).returncode
274+ != 0
275+ ):
242276 return "Git is not installed or not available in the PATH." , "error"
243277 except FileNotFoundError :
244278 return "Git is not installed or not available in the PATH." , "error"
245279
246280 # Check if the project is a git repository
247281 try :
248282 if not os .path .exists (os .path .join (os .getcwd (), "../.git" )):
249- return "This project is not a git repository. The update flag uses git." , "error"
283+ return (
284+ "This project is not a git repository. The update flag uses git." ,
285+ "error" ,
286+ )
250287 except Exception as e :
251288 return f"Error checking for git repository: { e } " , "error"
252289
@@ -279,20 +316,22 @@ def execute_new_window(file_path: str):
279316 """
280317 sr_current_dir = os .path .dirname (os .path .abspath (__file__ ))
281318 sr_script_path = os .path .join (sr_current_dir , file_path )
282- sr_process = subprocess .Popen (["cmd.exe" , "/c" , "start" , sys .executable , sr_script_path ])
319+ sr_process = subprocess .Popen (
320+ ["cmd.exe" , "/c" , "start" , sys .executable , sr_script_path ]
321+ )
283322 sr_process .wait ()
284323 exit (0 )
285324
286325
287326def get_flags ():
288327 """
289328 Retrieves action and sub-action flags from the Flag module and sets global variables.
290-
329+
291330 This function extracts the current action and sub-action from the Flag module, setting global
292331 ACTION and SUB_ACTION variables. It logs the retrieved values for debugging and tracing purposes.
293-
332+
294333 No parameters.
295-
334+
296335 Side effects:
297336 - Sets global variables ACTION and SUB_ACTION
298337 - Logs debug information about current action and sub-action
@@ -307,20 +346,20 @@ def get_flags():
307346def handle_special_actions ():
308347 """
309348 Handles special actions based on the current action flag.
310-
349+
311350 This function performs specific actions depending on the global `ACTION` variable:
312351 - For "debug": Opens the debug menu by executing '_debug.py'
313352 - For "dev": Opens the developer menu by executing '_dev.py'
314353 - For "update": Updates the repository using Health.update() method
315354 - For "restore": Displays a warning and opens the backup location
316355 - For "backup": Creates backups of the CODE and MODS directories
317-
356+
318357 Side Effects:
319358 - Logs informational, debug, warning, or error messages
320359 - May execute external Python scripts
321360 - May open file locations
322361 - May terminate the program after completing special actions
323-
362+
324363 Raises:
325364 SystemExit: Exits the program after completing certain special actions
326365 """
@@ -358,30 +397,35 @@ def handle_special_actions():
358397def check_privileges ():
359398 """
360399 Checks if the script is running with administrative privileges and handles UAC (User Account Control) settings.
361-
400+
362401 This function verifies if the script has admin privileges. If not, it either logs a warning (in debug mode) or
363402 prompts the user to run the script with admin privileges and exits. It also checks if UAC is enabled and logs
364403 warnings accordingly.
365-
404+
366405 Raises:
367406 SystemExit: If the script is not running with admin privileges and not in debug mode.
368-
407+
369408 Notes:
370409 - Requires the `Check` module with `admin()` and `uac()` methods
371410 - Depends on global `DEBUG` configuration variable
372411 - Logs warnings or critical messages based on privilege and UAC status
373412 """
374413 if not check .admin ():
375414 if DEBUG == "DEBUG" :
376- log .warning ("Running in debug mode, continuing without admin privileges - This may cause issues" )
415+ log .warning (
416+ "Running in debug mode, continuing without admin privileges - This may cause issues"
417+ )
377418 else :
378419 log .critical (
379- "Please run this script with admin privileges - To ignore this message, run with DEBUG in config" )
420+ "Please run this script with admin privileges - To ignore this message, run with DEBUG in config"
421+ )
380422 input ("Press Enter to exit..." )
381423 exit (1 )
382424
383425 if check .uac ():
384- log .warning ("UAC is enabled, this may cause issues - Please disable UAC if possible" )
426+ log .warning (
427+ "UAC is enabled, this may cause issues - Please disable UAC if possible"
428+ )
385429
386430
387431class ZIP :
@@ -394,11 +438,15 @@ def files(cls):
394438
395439 @staticmethod
396440 def __and_log (directory : str , name : str ):
397- log .debug (f"Zipping directory '{ directory } ' with name '{ name } ' under action '{ ACTION } '" )
441+ log .debug (
442+ f"Zipping directory '{ directory } ' with name '{ name } ' under action '{ ACTION } '"
443+ )
398444 zip_values = file_management .Zip .and_hash (
399445 directory ,
400446 name ,
401- ACTION if ACTION is not None else f"ERROR_NO_ACTION_SPECIFIED_{ datetime .now ().isoformat ()} "
447+ ACTION
448+ if ACTION is not None
449+ else f"ERROR_NO_ACTION_SPECIFIED_{ datetime .now ().isoformat ()} " ,
402450 )
403451 if isinstance (zip_values , str ):
404452 log .error (zip_values )
@@ -429,7 +477,7 @@ def handle_sub_action():
429477def Logicytics ():
430478 """
431479 Orchestrates the complete Logicytics workflow, managing script execution, system actions, and user interactions.
432-
480+
433481 This function serves as the primary entry point for the Logicytics utility, coordinating a series of system-level operations:
434482 - Retrieves command-line configuration flags
435483 - Processes special actions
@@ -438,7 +486,7 @@ def Logicytics():
438486 - Compresses generated output files
439487 - Handles final system sub-actions
440488 - Provides a graceful exit mechanism
441-
489+
442490 Performs actions sequentially without returning a value, designed to be the main execution flow of the Logicytics utility.
443491 """
444492 # Get flags_list and configs
@@ -461,7 +509,9 @@ def Logicytics():
461509 try :
462510 Logicytics ()
463511 except KeyboardInterrupt :
464- log .warning ("Force shutdown detected! Some temporary files might be left behind." )
512+ log .warning (
513+ "Force shutdown detected! Some temporary files might be left behind."
514+ )
465515 log .warning ("Next time, let the program finish naturally for complete cleanup." )
466516 # Emergency cleanup - zip generated files
467517 ZIP .files ()
0 commit comments