Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimised _debug.py #166

Merged
merged 2 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 48 additions & 81 deletions CODE/_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,35 @@
import configparser
import os
import platform
import subprocess
import sys
from datetime import datetime

import psutil
import requests

from logicytics import Log, DEBUG, VERSION, Check

if __name__ == "__main__":
log_debug = Log({"log_level": DEBUG, "filename": "../ACCESS/LOGS/DEBUG/DEBUG.log", "truncate_message": False})
log_debug = Log(
{"log_level": DEBUG,
"filename": "../ACCESS/LOGS/DEBUG/DEBUG.log",
"truncate_message": False}
)


class HealthCheck:
@staticmethod
def check_files(directory: str, required_files: list[str]) -> tuple[str, str]:
def check_files(directory: str, required_files: list[str]):
"""
Checks if all required files are present in the directory and its subdirectories.

Args:
directory (str): Path to the directory to check.
required_files (list[str]): List of required file names with relative paths.

Returns:
tuple[str, str]: Status message and severity level.
"""
try:
log_debug.debug(f"Checking directory: {directory}")
if not os.path.exists(directory):
log_debug.error(f"Directory {directory} does not exist.")
return f"Directory {directory} does not exist.", "ERROR"

# Gather all files with relative paths
actual_files = []
Expand Down Expand Up @@ -68,14 +66,13 @@ def check_files(directory: str, required_files: list[str]) -> tuple[str, str]:
log_debug.debug(f"Extra files: {extra_files}")

if missing_files:
return f"Missing files: {', '.join(missing_files)}", "ERROR"
log_debug.error(f"Missing files: {', '.join(missing_files)}")
if extra_files:
return f"Extra files found: {', '.join(extra_files)}", "WARNING"
return "All required files are present.", "INFO"
log_debug.warning(f"Extra files found: {', '.join(extra_files)}")
log_debug.info("All required files are present.")

except Exception as e:
log_debug.error(f"Unexpected error during file check: {e}")
return f"Unexpected error during file check: {e}", "ERROR"

@staticmethod
def get_online_config() -> dict | None:
Expand All @@ -92,47 +89,38 @@ def get_online_config() -> dict | None:
config.read_string(requests.get(url, timeout=15).text)
return config
except requests.exceptions.RequestException as e:
log_debug.warning(f"Connection error: {e}")
log_debug.error(f"Connection error: {e}")
return None

@staticmethod
def compare_versions(local_version: str, remote_version: str) -> tuple[str, str, str]:
def compare_versions(local_version: str, remote_version: str):
"""
Compares local and remote versions.

Args:
local_version (str): Local version.
remote_version (str): Remote version.

Returns:
tuple[str, str, str]: Comparison result, version details, and severity level.
"""
if local_version == remote_version:
return "Version is up to date.", f"Your Version: {local_version}", "INFO"
if local_version > remote_version:
return (
"Version is ahead of the repository.",
f"Your Version: {local_version}, Repository Version: {remote_version}",
"WARNING",
)
return (
"Version is behind the repository.",
f"Your Version: {local_version}, Repository Version: {remote_version}",
"ERROR",
)
log_debug.info(f"Version is up to date. Your Version: {local_version}")
elif local_version > remote_version:
log_debug.warning("Version is ahead of the repository. "
f"Your Version: {local_version}, "
f"Repository Version: {remote_version}")
else:
log_debug.error("Version is behind the repository."
f"Your Version: {local_version}, Repository Version: {remote_version}"
)


class DebugCheck:
@staticmethod
def sys_internal_binaries(path: str) -> tuple[str, str]:
def sys_internal_binaries(path: str):
"""
Checks the SysInternal Binaries in the given directory.

Args:
path (str): Directory path.

Returns:
tuple[str, str]: Status message and severity level.
"""
try:
if not os.path.exists(path):
Expand All @@ -145,34 +133,15 @@ def sys_internal_binaries(path: str) -> tuple[str, str]:
has_exe = any(file.endswith(".exe") for file in contents)

if any(file.endswith(".ignore") for file in contents):
return "A `.sys.ignore` file was found - Ignoring", "WARNING"
if has_zip and not has_exe:
return "Only zip files - Missing EXEs due to no `ignore` file", "ERROR"
if has_zip and has_exe:
return "Both zip and exe files - All good", "INFO"

return "SysInternal Binaries Not Found: Missing Files - Corruption detected", "ERROR"
log_debug.warning("A `.sys.ignore` file was found - Ignoring")
elif has_zip and not has_exe:
log_debug.error("Only zip files - Missing EXEs due to no `ignore` file")
elif has_zip and has_exe:
log_debug.info("Both zip and exe files - All good")
else:
log_debug.error("SysInternal Binaries Not Found: Missing Files - Corruption detected")
except Exception as e:
return f"Unexpected error: {e}", "ERROR"

@staticmethod
def execution_policy() -> bool:
"""
Checks if the execution policy is unrestricted.

Returns:
bool: True if unrestricted, False otherwise.
"""
try:
result = subprocess.run(
["powershell", "-Command", "Get-ExecutionPolicy"],
capture_output=True,
text=True,
)
return result.stdout.strip().lower() == "unrestricted"
except Exception as e:
log_debug.error(f"Failed to check execution policy: {e}")
return False
log_debug.error(f"Unexpected error: {e}")

@staticmethod
def cpu_info() -> tuple[str, str, str]:
Expand All @@ -189,6 +158,20 @@ def cpu_info() -> tuple[str, str, str]:
)


def python_version():
version = sys.version.split()[0]
try:
major, minor = map(int, version.split(".")[:2])
if (major, minor) == (3, 11):
log_debug.info(f"Python Version: {version} - Perfect")
elif major == 3:
log_debug.warning(f"Python Version: {version} - Recommended: 3.11.x")
else:
log_debug.error(f"Python Version: {version} - Incompatible")
except Exception as e:
log_debug.error(f"Failed to parse Python Version: {e}")


def debug():
"""
Executes system checks and logs results.
Expand All @@ -201,18 +184,14 @@ def debug():
# Online Configuration Check
config = HealthCheck.get_online_config()
if config:
version_check = HealthCheck.compare_versions(VERSION, config["System Settings"]["version"])
log_debug.string(version_check[0], version_check[2])
log_debug.raw(f"[{datetime.now():%Y-%m-%d %H:%M:%S}] > DATA: {version_check[1]}")
HealthCheck.compare_versions(VERSION, config["System Settings"]["version"])

# File Integrity Check
required_files = config["System Settings"].get("files", "").split(",")
message, severity = HealthCheck.check_files(".", required_files)
log_debug.string(message, severity)
HealthCheck.check_files(".", required_files)

# SysInternal Binaries Check
message, severity = DebugCheck.sys_internal_binaries("SysInternal_Suite")
log_debug.string(message, severity)
DebugCheck.sys_internal_binaries("SysInternal_Suite")

# System Checks
log_debug.info("Admin privileges found" if Check.admin() else "Admin privileges not found")
Expand All @@ -222,23 +201,11 @@ def debug():
log_debug.info(f"Local execution path: {sys.prefix}")
log_debug.info(
"Running in a virtual environment" if sys.prefix != sys.base_prefix else "Not running in a virtual environment")

# Execution Policy Check
log_debug.info(
"Execution policy is unrestricted" if DebugCheck.execution_policy() else "Execution policy is not unrestricted")
"Execution policy is unrestricted" if Check.execution_policy() else "Execution policy is not unrestricted")

# Python Version Check
python_version = sys.version.split()[0]
try:
major, minor = map(int, python_version.split(".")[:2])
if (major, minor) == (3, 11):
log_debug.info(f"Python Version: {python_version} - Perfect")
elif major == 3:
log_debug.warning(f"Python Version: {python_version} - Recommended: 3.11.x")
else:
log_debug.error(f"Python Version: {python_version} - Incompatible")
except Exception as e:
log_debug.error(f"Failed to parse Python Version: {e}")
python_version()

# CPU Info
for info in DebugCheck.cpu_info():
Expand Down
10 changes: 10 additions & 0 deletions CODE/logicytics/Checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ctypes
import os.path
import subprocess
import zipfile

from logicytics.Execute import Execute
Expand All @@ -21,6 +22,15 @@ def admin() -> bool:
except AttributeError:
return False

@staticmethod
def execution_policy() -> bool:
result = subprocess.run(
["powershell", "-Command", "Get-ExecutionPolicy"],
capture_output=True,
text=True,
)
return result.stdout.strip().lower() == "unrestricted"

@staticmethod
def uac() -> bool:
"""
Expand Down
Loading