Skip to content

Commit

Permalink
Made sure all functions have a docstring and specific data types for …
Browse files Browse the repository at this point in the history
…parameters and return values

Also, quick mini bug fixes to some files, and renaming some functions to make them better
  • Loading branch information
DefinetlyNotAI committed Sep 20, 2024
1 parent be8b296 commit a7e5655
Show file tree
Hide file tree
Showing 14 changed files with 335 additions and 73 deletions.
2 changes: 2 additions & 0 deletions CODE/Logicytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@

zip_values = Zip().and_hash(".", "CODE", action)
if isinstance(zip_values, str):
# If error, log it
log.error(zip_values)
else:
zip_loc, hash_loc = zip_values
Expand All @@ -222,6 +223,7 @@
log.info("Rebooting...")
subprocess.call("shutdown /r /t 3", shell=False)
if sub_action == "webhook":
# Implement this in future
log.warning("This feature is not fully implemented yet! Sorry")

log.info("Exiting...")
Expand Down
64 changes: 58 additions & 6 deletions CODE/__lib_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class Actions:
@staticmethod
def open_file(file: str) -> None:
def open_file(file: str):
"""
Opens a specified file using its default application in a cross-platform manner.
Args:
Expand Down Expand Up @@ -44,6 +44,18 @@ def run_command(command: str) -> str:

@staticmethod
def __parse_arguments() -> tuple[argparse.Namespace, argparse.ArgumentParser]:
"""
A static method used to parse command-line arguments for the Logicytics application.
It defines various flags that can be used to customize the behavior of the application,
including options for running in default or minimal mode, unzipping extra files,
backing up or restoring data, updating from GitHub, and more.
The method returns a tuple containing the parsed arguments and the argument parser object.
Returns:
tuple[argparse.Namespace, argparse.ArgumentParser]: A tuple containing the parsed arguments and the argument parser object.
"""
# Define the argument parser
parser = argparse.ArgumentParser(
description="Logicytics, The most powerful tool for system data analysis."
Expand Down Expand Up @@ -128,6 +140,15 @@ def __parse_arguments() -> tuple[argparse.Namespace, argparse.ArgumentParser]:

@staticmethod
def __exclusivity(args: argparse.Namespace) -> bool:
"""
Checks if exclusive flags are used in the provided arguments.
Args:
args (argparse.Namespace): The arguments to be checked.
Returns:
bool: True if exclusive flags are used, False otherwise.
"""
special_flag_used = False
if args.reboot or args.shutdown or args.webhook:
if not (
Expand All @@ -140,6 +161,15 @@ def __exclusivity(args: argparse.Namespace) -> bool:

@staticmethod
def __set_flags(args: argparse.Namespace) -> tuple[str, ...]:
"""
Sets flags based on the provided arguments.
Args:
args (argparse.Namespace): The arguments to be checked for flags.
Returns:
tuple[str, ...]: A tuple of flag names that are set to True.
"""
Flags = {key: getattr(args, key) for key in vars(args)}
true_keys = []
for key, value in Flags.items():
Expand All @@ -150,6 +180,11 @@ def __set_flags(args: argparse.Namespace) -> tuple[str, ...]:
return tuple(true_keys)

def flags(self) -> tuple[str, ...] | argparse.ArgumentParser:
"""
Handles the parsing and validation of command-line flags.
Returns either a tuple of used flag names or an ArgumentParser instance.
"""
args, parser = self.__parse_arguments()
special_flag_used = self.__exclusivity(args)

Expand Down Expand Up @@ -238,6 +273,12 @@ def check_current_files(directory: str) -> list:

@staticmethod
def mkdir():
"""
Creates the necessary directories for storing logs, backups, and data.
Returns:
None
"""
os.makedirs("../ACCESS/LOGS/", exist_ok=True)
os.makedirs("../ACCESS/LOGS/DEBUG", exist_ok=True)
os.makedirs("../ACCESS/BACKUP/", exist_ok=True)
Expand Down Expand Up @@ -284,6 +325,17 @@ def uac(self) -> bool:

@staticmethod
def sys_internal_zip():
"""
Extracts the SysInternal_Suite zip file if it exists and is not ignored.
This function checks if the SysInternal_Suite zip file exists and if it is not ignored.
If the zip file exists and is not ignored,
it extracts its contents to the SysInternal_Suite directory.
If the zip file is ignored, it prints a message indicating that it is skipping the extraction.
Raises:
Exception: If there is an error during the extraction process. The error message is printed to the console and the program exits.
"""
try:
ignore_file = os.path.exists("SysInternal_Suite/.sys.ignore")
zip_file = os.path.exists("SysInternal_Suite/SysInternal_Suite.zip")
Expand Down Expand Up @@ -323,7 +375,7 @@ def get_files(directory: str, file_list: list) -> list:
file_list.append(filename)
return file_list

def file(self, execution_list: list, Index: int) -> None:
def file(self, execution_list: list, Index: int):
# IT IS USED, DO NOT REMOVE
"""
Executes a file from the execution list at the specified index.
Expand All @@ -336,7 +388,7 @@ def file(self, execution_list: list, Index: int) -> None:
self.execute_script(execution_list[Index])
Log().info(f"{execution_list[Index]} executed")

def execute_script(self, script: str) -> None:
def execute_script(self, script: str):
"""
Executes a script file and handles its output based on the file extension.
Parameters:
Expand All @@ -353,7 +405,7 @@ def execute_script(self, script: str) -> None:
self.__run_other_script(script)

@staticmethod
def __unblock_ps1_script(script: str) -> None:
def __unblock_ps1_script(script: str):
"""
Unblocks and runs a PowerShell (.ps1) script.
Parameters:
Expand All @@ -369,7 +421,7 @@ def __unblock_ps1_script(script: str) -> None:
Log().critical(f"Failed to unblock script: {err}", "_L", "G", "E")

@staticmethod
def __run_python_script(script: str) -> None:
def __run_python_script(script: str):
"""
Runs a Python (.py) script.
Parameters:
Expand All @@ -383,7 +435,7 @@ def __run_python_script(script: str) -> None:
print(result.decode())

@staticmethod
def __run_other_script(script: str) -> None:
def __run_other_script(script: str):
"""
Runs a script with other extensions and logs output based on its content.
Parameters:
Expand Down
2 changes: 1 addition & 1 deletion CODE/__lib_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def error(self, message):
f"[{self.__timestamp()}] > ERROR: | {self.__pad_message(str(message))}\n"
)

def critical(self, message, FILECODE, ERRCODE, FUNCODE):
def critical(self, message, FILECODE: str, ERRCODE: str, FUNCODE: str):
"""
Logs a critical message to the error log File.
Expand Down
3 changes: 3 additions & 0 deletions CODE/__wrapper__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Optional wrapper that you can build manually, if you want to ignore the restrictions of python in the
# main Logicytics file. This wrapper is not compulsory, but it is recommended to use it to build the exe.

# Special wrapper that the exe Logicytics is made out of, not compulsory, just to ignore some restrictions of python.

# If you modify please run this command:
Expand Down
92 changes: 84 additions & 8 deletions CODE/_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@


class HealthCheck:
def get_config_data(self) -> bool | tuple[tuple[str, str, str], tuple[str, str, str]]:
def get_online_config(self) -> bool | tuple[tuple[str, str, str], tuple[str, str, str]]:
"""
Retrieves configuration data from a remote repository and compares it with the local configuration.
Returns:
bool: False if a connection error occurs, otherwise a tuple containing version check and file check results.
tuple[tuple[str, str, str], tuple[str, str, str]]: A tuple containing version check and file check results.
"""
try:
url = "https://raw.githubusercontent.com/DefinetlyNotAI/Logicytics/main/CODE/config.json"
config = json.loads(requests.get(url).text)
Expand All @@ -30,7 +37,18 @@ def get_config_data(self) -> bool | tuple[tuple[str, str, str], tuple[str, str,
return version_check, file_check

@staticmethod
def __compare_versions(local_version, remote_version) -> tuple[str, str, str]:
def __compare_versions(local_version: str, remote_version: str) -> tuple[str, str, str]:
"""
Compares the local version with the remote version and returns a tuple containing a comparison result message,
a version information message, and a severity level.
Args:
local_version (str): The version number of the local system.
remote_version (str): The version number of the remote repository.
Returns:
tuple[str, str, str]: A tuple containing a comparison result message, a version information message, and a severity level.
"""
if local_version == remote_version:
return "Version is up to date.", f"Your Version: {local_version}", "INFO"
elif local_version > remote_version:
Expand All @@ -39,7 +57,18 @@ def __compare_versions(local_version, remote_version) -> tuple[str, str, str]:
return "Version is behind the repository.", f"Your Version: {local_version}, Repository Version: {remote_version}", "ERROR"

@staticmethod
def __check_files(local_files, remote_files) -> tuple[str, str, str]:
def __check_files(local_files: list, remote_files: list) -> tuple[str, str, str]:
"""
Check if all the files in the local_files list are present in the remote_files list.
Args:
local_files (list): A list of files in the local repository.
remote_files (list): A list of files in the remote repository.
Returns:
tuple[str, str, str]: A tuple containing the result message, a message detailing the files present or missing,
and the log level.
"""
missing_files = set(remote_files) - set(local_files)
if not missing_files:
return "All files are present.", f"Your files: {local_files} contain all the files in the repository.", "INFO"
Expand All @@ -49,7 +78,22 @@ def __check_files(local_files, remote_files) -> tuple[str, str, str]:

class DebugCheck:
@staticmethod
def SysInternal_Binaries(path):
def SysInternal_Binaries(path: str) -> tuple[str, str]:
"""
Checks the contents of the given path and determines the status of the SysInternal Binaries.
Args:
path (str): The path to the directory containing the SysInternal Binaries.
Returns:
tuple[str, str]: A tuple containing a status message and a severity level.
The status message indicates the result of the check.
The severity level is either "INFO", "WARNING", or "ERROR".
Raises:
FileNotFoundError: If the given path does not exist.
Exception: If an unexpected error occurs during the check.
"""
try:
contents = os.listdir(path)
log_debug.debug(contents)
Expand All @@ -67,23 +111,55 @@ def SysInternal_Binaries(path):
return f"An Unexpected error occurred: {e}", "ERROR"

@staticmethod
def execution_policy():
def execution_policy() -> bool:
"""
Checks the current PowerShell execution policy.
Returns:
bool: True if the execution policy is unrestricted, False otherwise.
"""
result = subprocess.run(['powershell', '-Command', 'Get-ExecutionPolicy'], capture_output=True, text=True)
return result.stdout.strip().lower() == 'unrestricted'

@staticmethod
def cpu_info():
def cpu_info() -> tuple[str, str, str]:
"""
Retrieves information about the CPU.
Returns:
tuple[str, str, str]: A tuple containing the CPU architecture, vendor ID, and model.
"""
return 'CPU Architecture: ' + platform.machine(), 'CPU Vendor Id: ' + platform.system(), 'CPU Model: ' + f"{platform.release()} {platform.version()}"


def debug():
"""
Performs a series of system checks and logs the results.
This function performs the following checks:
1. Clears the debug log file.
2. Checks the integrity of files by comparing local and remote configurations.
3. Checks the status of SysInternal Binaries.
4. Checks for admin privileges.
5. Checks if User Account Control (UAC) is enabled.
6. Logs the execution paths.
7. Checks if the script is running in a virtual environment.
8. Checks the PowerShell execution policy.
9. Logs the Python version being used.
10. Logs the repository path.
11. Logs CPU information.
12. Logs the debug configuration.
Returns:
None
"""
# Clear Debug Log
if os.path.exists("../ACCESS/LOGS/DEBUG/DEBUG.LOG"):
os.remove("../ACCESS/LOGS/DEBUG/DEBUG.LOG")

# Check File integrity (Online)
if HealthCheck().get_config_data():
version_tuple, file_tuple = HealthCheck().get_config_data()
if HealthCheck().get_online_config():
version_tuple, file_tuple = HealthCheck().get_online_config()
log_debug_funcs.get(version_tuple[2], log_debug.debug)("\n".join(version_tuple[0]).replace('\n', ''))
log_debug_funcs.get(file_tuple[2], log_debug.debug)("\n".join(file_tuple[0]).replace('\n', ''))
message, type = DebugCheck.SysInternal_Binaries("SysInternal_Suite")
Expand Down
11 changes: 11 additions & 0 deletions CODE/_dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ def __dev_checks(self) -> bool:
return False

def run_dev(self):
"""
Executes the development checks and runs the test files.
This function performs the following steps:
1. Creates necessary directories.
2. Executes development checks to ensure guidelines and best practices are followed.
3. Collects and runs all Python test files in the `../TESTS` directory, excluding `__init__.py` and `test.py`.
Returns:
None
"""
Actions().mkdir()
if self.__dev_checks():
test_files = []
Expand Down
4 changes: 2 additions & 2 deletions CODE/_extra.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}


def unzip(zip_path: str) -> None:
def unzip(zip_path: str):
"""
Unzips a given zip file to a new directory with the same name.
Expand All @@ -31,7 +31,7 @@ def unzip(zip_path: str) -> None:
z.extractall(path=str(output_dir))


def menu() -> None:
def menu():
"""
Displays a menu of available executable scripts in the '../EXTRA/EXTRA' directory,
prompts the user to select a script, and runs the selected script using PowerShell.
Expand Down
Loading

0 comments on commit a7e5655

Please sign in to comment.