Files
OpCore-Simplify/Scripts/utils.py
Hoang Hong Quan 0e608a56ce Add GUI Support for OpCore Simplify (#512)
* Refactor OpCore-Simplify to GUI version

* New ConfigEditor

* Add requirement checks and installation in launchers

* Add GitHub Actions workflow to generate manifest.json

* Set compression level for asset

* Skip .git and __pycache__ folders

* Refactor update process to include integrity checker

* Add SMBIOS model selection

* Update README.md

* Update to main branch
2025-12-30 14:19:47 +07:00

163 lines
5.5 KiB
Python

import os
import json
import plistlib
import shutil
import re
import binascii
import subprocess
import zipfile
import tempfile
import traceback
import contextlib
import logging
class Utils:
def __init__(self):
self.gui_handler = None
self.logger = logging.getLogger("OpCoreSimplify")
@contextlib.contextmanager
def safe_block(self, task_name="Operation", suppress_error=True):
try:
yield
except Exception as e:
error_details = "".join(traceback.format_exc())
self.log_message("Error during '{}': {}\n{}".format(task_name, str(e), error_details), level="ERROR")
if not suppress_error:
raise
def log_message(self, message, level="INFO", to_build_log=False):
log_level = getattr(logging, level.upper(), logging.INFO)
extra = {'to_build_log': to_build_log}
self.logger.log(log_level, message, extra=extra)
return True
def clean_temporary_dir(self):
temporary_dir = tempfile.gettempdir()
for file in os.listdir(temporary_dir):
if file.startswith("ocs_"):
if not os.path.isdir(os.path.join(temporary_dir, file)):
continue
try:
shutil.rmtree(os.path.join(temporary_dir, file))
except Exception as e:
self.log_message("[UTILS] Failed to remove temp directory {}: {}".format(file, e), "Error")
pass
def get_temporary_dir(self):
return tempfile.mkdtemp(prefix="ocs_")
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 find_matching_paths(self, root_path, extension_filter=None, name_filter=None, type_filter=None):
def is_valid_item(name):
if name.startswith("."):
return False
if extension_filter and not name.lower().endswith(extension_filter.lower()):
return False
if name_filter and name_filter not in name:
return False
return True
found_paths = []
for root, dirs, files in os.walk(root_path):
relative_root = root.replace(root_path, "")[1:]
if type_filter in (None, "dir"):
for d in dirs:
if is_valid_item(d):
found_paths.append((os.path.join(relative_root, d), "dir"))
if type_filter in (None, "file"):
for file in files:
if is_valid_item(file):
found_paths.append((os.path.join(relative_root, file), "file"))
return sorted(found_paths, key=lambda path: path[0])
def create_folder(self, path, remove_content=False):
if os.path.exists(path):
if remove_content:
shutil.rmtree(path)
os.makedirs(path)
else:
os.makedirs(path)
def hex_to_bytes(self, string):
try:
hex_string = re.sub(r'[^0-9a-fA-F]', '', string)
if len(re.sub(r"\s+", "", string)) != len(hex_string):
return string
return binascii.unhexlify(hex_string)
except binascii.Error:
return string
def int_to_hex(self, number):
return format(number, '02X')
def to_little_endian_hex(self, hex_string):
hex_string = hex_string.lower().lstrip("0x")
return ''.join(reversed([hex_string[i:i+2] for i in range(0, len(hex_string), 2)])).upper()
def string_to_hex(self, string):
return ''.join(format(ord(char), '02X') for char in string)
def extract_zip_file(self, zip_path, extraction_directory=None):
if extraction_directory is None:
extraction_directory = os.path.splitext(zip_path)[0]
os.makedirs(extraction_directory, exist_ok=True)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extraction_directory)
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 parse_darwin_version(self, darwin_version):
major, minor, patch = map(int, darwin_version.split('.'))
return major, minor, patch
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)