mirror of
https://github.com/outbackdingo/OpCore-Simplify.git
synced 2026-01-27 18:19:49 +00:00
Initial commit
This commit is contained in:
244
Scripts/utils.py
Executable file
244
Scripts/utils.py
Executable file
@@ -0,0 +1,244 @@
|
||||
from Scripts import resource_fetcher
|
||||
import os
|
||||
import json
|
||||
import plistlib
|
||||
import shutil
|
||||
import re
|
||||
import binascii
|
||||
import subprocess
|
||||
import pathlib
|
||||
|
||||
class Utils:
|
||||
def __init__(self, script_name = "OpCore Simplify"):
|
||||
self.script_name = script_name
|
||||
self.fetcher = resource_fetcher.ResourceFetcher({
|
||||
"Accept": "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
})
|
||||
self.repo_url = "https://raw.githubusercontent.com/lzhoang2801/OpCore-Simplify/main/version.json"
|
||||
|
||||
def write_file(self, file_path, data):
|
||||
file_extension = os.path.splitext(file_path)[1]
|
||||
|
||||
with open(file_path, "w" if file_extension == ".json" else "wb") as file:
|
||||
if file_extension == ".json":
|
||||
json.dump(data, file, indent=4)
|
||||
else:
|
||||
if file_extension == ".plist":
|
||||
data = plistlib.dumps(data)
|
||||
|
||||
file.write(data)
|
||||
|
||||
def read_file(self, file_path):
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
file_extension = os.path.splitext(file_path)[1]
|
||||
|
||||
with open(file_path, "r" if file_extension == ".json" else "rb") as file_handle:
|
||||
if file_extension == ".plist":
|
||||
data = plistlib.load(file_handle)
|
||||
elif file_extension == ".json":
|
||||
data = json.load(file_handle)
|
||||
else:
|
||||
data = file_handle.read()
|
||||
return data
|
||||
|
||||
def search_dict_iter(self, dictionary, search_term, equal=True, reverse=False):
|
||||
dictionary_copy = dictionary.copy()
|
||||
|
||||
if reverse:
|
||||
dictionary_copy = dict(list(dictionary_copy.items())[::-1])
|
||||
|
||||
stack = [(dictionary_copy, None)]
|
||||
|
||||
while stack:
|
||||
current_dict, parent_dict = stack.pop()
|
||||
for key, value in current_dict.items():
|
||||
if equal and value == search_term or not equal and search_term in value:
|
||||
return current_dict
|
||||
if isinstance(value, dict):
|
||||
stack.append((value, current_dict))
|
||||
if equal and key == search_term or not equal and search_term in key:
|
||||
return value
|
||||
|
||||
return {}
|
||||
|
||||
def recursively_search(self, directory, matching_file_extension=None, matching_file_name_pattern=None, parent_directory=""):
|
||||
matching_paths = []
|
||||
|
||||
if not os.path.exists(directory):
|
||||
print(f"Error: The directory {directory} does not exist.")
|
||||
return matching_paths
|
||||
|
||||
for child_directory in os.listdir(directory):
|
||||
if "MACOSX" in child_directory or "dSYM" in child_directory:
|
||||
continue
|
||||
|
||||
file_name = os.path.splitext(os.path.basename(child_directory))[0]
|
||||
file_extension = os.path.splitext(os.path.basename(child_directory))[1]
|
||||
|
||||
if (matching_file_extension is not None and matching_file_extension == file_extension) or (matching_file_name_pattern is not None and matching_file_name_pattern in file_name):
|
||||
path = os.path.join(parent_directory, child_directory)
|
||||
full_path = os.path.join(directory, child_directory)
|
||||
|
||||
if not os.path.isdir(full_path) or not os.path.exists(os.path.join(full_path, file_name + file_extension)):
|
||||
matching_paths.append(path)
|
||||
|
||||
child_directory = os.path.join(directory, child_directory)
|
||||
if os.path.isdir(child_directory):
|
||||
matching_paths.extend(self.recursively_search(child_directory, matching_file_extension, matching_file_name_pattern, os.path.join(parent_directory, os.path.basename(child_directory))))
|
||||
|
||||
return matching_paths
|
||||
|
||||
def sort_dict_by_key(self, input_dict, sort_key):
|
||||
return dict(sorted(input_dict.items(), key=lambda item: item[1].get(sort_key, "")))
|
||||
|
||||
def mkdirs(self, *directories):
|
||||
for directory in directories:
|
||||
if not os.path.exists(os.path.dirname(directory)):
|
||||
os.makedirs(os.path.dirname(directory))
|
||||
if os.path.exists(directory):
|
||||
shutil.rmtree(directory)
|
||||
os.mkdir(directory)
|
||||
|
||||
def hex_to_bytes(self, string):
|
||||
try:
|
||||
# Remove non-hex characters (e.g., hyphens)
|
||||
hex_string = re.sub(r'[^0-9a-fA-F]', '', string)
|
||||
|
||||
if len(re.sub(r"\s+", "", string)) != len(hex_string):
|
||||
return string
|
||||
|
||||
# Convert hex string to bytes
|
||||
bytes_data = binascii.unhexlify(hex_string)
|
||||
|
||||
return bytes_data
|
||||
except binascii.Error:
|
||||
# Handle invalid hex string
|
||||
return string
|
||||
|
||||
def int_to_hex(self, number):
|
||||
try:
|
||||
return format(number, '02X')
|
||||
except:
|
||||
return number
|
||||
|
||||
def hex_to_int(self, hex_string):
|
||||
return int(hex_string, 16)
|
||||
|
||||
def contains_any(self, data, search_item, start=0, end=None):
|
||||
return next((item for item in data[start:end] if item.lower() in search_item.lower()), None)
|
||||
|
||||
def check_latest_version(self):
|
||||
response = self.fetcher.fetch_and_parse_content(self.repo_url, "json")
|
||||
|
||||
latest_version = response.get('version')
|
||||
|
||||
if not latest_version:
|
||||
print("Version information is missing in the JSON file.")
|
||||
return None
|
||||
|
||||
return latest_version
|
||||
|
||||
def normalize_path(self, path):
|
||||
# Remove all surrounding quotes if present
|
||||
path = re.sub(r'^[\'"]+|[\'"]+$', '', path)
|
||||
|
||||
# Remove trailing spaces
|
||||
path = path.strip()
|
||||
|
||||
# Expand ~ to the user's home directory
|
||||
path = os.path.expanduser(path)
|
||||
|
||||
# Normalize path separators for the target operating system
|
||||
if os.name == 'nt': # Windows
|
||||
# Replace single backslashes with forward slashes
|
||||
path = path.replace('\\', '/')
|
||||
# Remove redundant slashes
|
||||
path = re.sub(r'/+', '/', path)
|
||||
else:
|
||||
# Replace backslashes with forward slashes
|
||||
path = path.replace('\\', '/')
|
||||
|
||||
# Normalize the path
|
||||
path = os.path.normpath(path)
|
||||
|
||||
# Convert the path to an absolute path and normalize it according to the OS
|
||||
return str(pathlib.Path(path).resolve())
|
||||
|
||||
def open_folder(self, folder_path):
|
||||
if os.name == 'posix':
|
||||
if 'darwin' in os.uname().sysname.lower():
|
||||
subprocess.run(['open', folder_path])
|
||||
else:
|
||||
subprocess.run(['xdg-open', folder_path])
|
||||
elif os.name == 'nt':
|
||||
os.startfile(folder_path)
|
||||
else:
|
||||
raise NotImplementedError("This function is only supported on macOS, Windows, and Linux.")
|
||||
|
||||
def request_input(self, prompt="Press Enter to continue..."):
|
||||
try:
|
||||
user_response = input(prompt)
|
||||
except NameError:
|
||||
user_response = raw_input(prompt)
|
||||
|
||||
if not isinstance(user_response, str):
|
||||
user_response = str(user_response)
|
||||
|
||||
return user_response
|
||||
|
||||
def clear_screen(self):
|
||||
os.system('cls' if os.name=='nt' else 'clear')
|
||||
|
||||
def head(self, text = None, width = 68, resize=True):
|
||||
if resize:
|
||||
self.adjust_window_size()
|
||||
self.clear_screen()
|
||||
if text == None:
|
||||
text = self.script_name
|
||||
separator = "#" * width
|
||||
title = f" {text} "
|
||||
if len(title) > width - 2:
|
||||
title = title[:width-4] + "..."
|
||||
title = title.center(width - 2) # Center the title within the width minus 2 for the '#' characters
|
||||
|
||||
print(f"{separator}\n#{title}#\n{separator}")
|
||||
|
||||
def adjust_window_size(self, content=""):
|
||||
lines = content.splitlines()
|
||||
rows = len(lines)
|
||||
cols = max(len(line) for line in lines) if lines else 0
|
||||
print('\033[8;{};{}t'.format(max(rows+6, 30), max(cols+2, 100)))
|
||||
|
||||
@staticmethod
|
||||
def message(text, msg_type="attention"):
|
||||
# ANSI escape codes for different colors and bold font
|
||||
RED_BOLD = "\033[1;31m"
|
||||
YELLOW_BOLD = "\033[1;33m"
|
||||
CYAN_BOLD = "\033[1;36m"
|
||||
RESET = "\033[0m"
|
||||
|
||||
if msg_type == "attention":
|
||||
color_code = RED_BOLD
|
||||
elif msg_type == "warning":
|
||||
color_code = YELLOW_BOLD
|
||||
elif msg_type == "reminder":
|
||||
color_code = CYAN_BOLD
|
||||
else:
|
||||
color_code = RESET
|
||||
|
||||
return f"{color_code}{text}{RESET}"
|
||||
|
||||
def exit_program(self, custom_content=""):
|
||||
self.head()
|
||||
print(custom_content)
|
||||
print("For more information, to report errors, or to contribute to the product:")
|
||||
print("* Facebook: https://www.facebook.com/macforce2601")
|
||||
print("* Telegram: https://t.me/lzhoang2601")
|
||||
print("* GitHub: https://github.com/lzhoang2801/OpCore-Simplify")
|
||||
print("")
|
||||
|
||||
print("Thank you for using our program!\n")
|
||||
exit(0)
|
||||
Reference in New Issue
Block a user