Enhance user prompts, add temporary dir handling

This commit is contained in:
Hoang Hong Quan
2025-10-22 00:59:12 +07:00
parent c4ed8bb4fe
commit 542ad9623c
8 changed files with 197 additions and 168 deletions
+104 -99
View File
@@ -29,33 +29,32 @@ class OCPE:
self.s = smbios.SMBIOS()
self.r = run.Run()
self.u = utils.Utils()
self.result_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "Results")
self.result_dir = self.u.get_temporary_dir()
def select_hardware_report(self):
self.hardware_sniffer = self.o.gather_hardware_sniffer()
self.ac.dsdt = self.ac.acpi.acpi_tables = None
while True:
self.u.head("Select hardware report")
print("")
if os.name == "nt":
print("\033[93mNote:\033[0m")
print("\033[1;93mNote:\033[0m")
print("- Ensure you are using the latest version of Hardware Sniffer before generating the hardware report.")
print("- Hardware Sniffer will not collect information related to Resizable BAR option of GPU (disabled by default) and monitor connections in Windows PE.")
print("")
if self.hardware_sniffer:
print("")
print("E. Export hardware report (Recommended)")
print("E. Export hardware report (Recommended)")
print("")
print("Q. Quit")
print("")
user_input = self.u.request_input("Drag and drop your hardware report here (.JSON){}: ".format(" or type \"E\" to export" if self.hardware_sniffer else ""))
user_input = self.u.request_input("Drag and drop your hardware report here (.JSON) or type \"E\" to export: ")
if user_input.lower() == "q":
self.u.exit_program()
if self.hardware_sniffer and user_input.lower() == "e":
if user_input.lower() == "e":
hardware_sniffer = self.o.gather_hardware_sniffer()
output = self.r.run({
"args":[self.hardware_sniffer, "-e"]
"args":[hardware_sniffer, "-e"]
})
if output[-1] != 0:
@@ -101,7 +100,7 @@ class OCPE:
print("\033[91mImportant:\033[0m")
print("Please consider these risks carefully before proceeding.")
print("")
print("\033[93mNote:\033[0m")
print("\033[1;93mNote:\033[0m")
print("If you experience black screen after login with OpenCore Legacy Patcher v2.2.0 or newer")
print("after applying root patches, please revert to version v2.1.2.")
print("")
@@ -157,7 +156,7 @@ class OCPE:
print(" {}. {}{}".format(darwin_version, name, label))
print("")
print("\033[93mNote:\033[0m")
print("\033[1;93mNote:\033[0m")
print("- To select a major version, enter the number (e.g., 19).")
print("- To specify a full version, use the Darwin version format (e.g., 22.4.6).")
print("")
@@ -177,9 +176,17 @@ class OCPE:
return target_version
def build_opencore_efi(self, hardware_report, disabled_devices, smbios_model, macos_version, needs_oclp):
self.u.head("Building OpenCore EFI")
print("")
print("1. Copy EFI base to results folder...", end=" ")
steps = [
"Copying EFI base to results folder",
"Applying ACPI patches",
"Copying kexts and snapshotting to config.plist",
"Generating config.plist",
"Cleaning up unused drivers, resources, and tools"
]
title = "Building OpenCore EFI"
self.u.progress_bar(title, steps, 0)
self.u.create_folder(self.result_dir, remove_content=True)
if not os.path.exists(self.k.ock_files_dir):
@@ -193,8 +200,8 @@ class OCPE:
if not config_data:
raise Exception("Error: The file {} does not exist.".format(config_file))
print("Done")
print("2. Apply ACPI patches...", end=" ")
self.u.progress_bar(title, steps, 1)
config_data["ACPI"]["Add"] = []
config_data["ACPI"]["Delete"] = []
config_data["ACPI"]["Patch"] = []
@@ -223,17 +230,17 @@ class OCPE:
config_data["ACPI"]["Patch"].extend(self.ac.dsdt_patches)
config_data["ACPI"]["Patch"] = self.ac.apply_acpi_patches(config_data["ACPI"]["Patch"])
print("Done")
print("3. Copy kexts and snapshot to config.plist...", end=" ")
self.u.progress_bar(title, steps, 2)
kexts_directory = os.path.join(self.result_dir, "EFI", "OC", "Kexts")
self.k.install_kexts_to_efi(macos_version, kexts_directory)
config_data["Kernel"]["Add"] = self.k.load_kexts(hardware_report, macos_version, kexts_directory)
print("Done")
print("4. Generate config.plist...", end=" ")
self.u.progress_bar(title, steps, 3)
self.co.genarate(hardware_report, disabled_devices, smbios_model, macos_version, needs_oclp, self.k.kexts, config_data)
self.u.write_file(config_file, config_data)
print("Done")
print("5. Clean up unused drivers, resources, and tools...", end=" ")
self.u.progress_bar(title, steps, 4)
files_to_remove = []
drivers_directory = os.path.join(self.result_dir, "EFI", "OC", "Drivers")
@@ -269,7 +276,6 @@ class OCPE:
if not tool_path in tool_loaded:
files_to_remove.append(os.path.join(tools_directory, tool_path))
removal_error = None
for file_path in files_to_remove:
try:
if os.path.isdir(file_path):
@@ -277,14 +283,10 @@ class OCPE:
else:
os.remove(file_path)
except Exception as e:
removal_error = True
print("Failed to remove file: {}".format(e))
if removal_error:
print("")
self.u.progress_bar(title, steps, len(steps), done=True)
print("Done")
print("")
print("OpenCore EFI build complete.")
time.sleep(2)
@@ -308,36 +310,37 @@ class OCPE:
return requirements
def results(self, org_hardware_report, hardware_report):
self.u.head("Results")
print("")
print("Your OpenCore EFI for {} has been built at:".format(hardware_report.get("Motherboard").get("Name")))
print("\t{}".format(self.result_dir))
bios_requirements = self.check_bios_requirements(org_hardware_report, hardware_report)
print("")
print("\033[93mBefore using EFI, please complete the following steps:\033[0m")
print("")
if bios_requirements:
print("* BIOS/UEFI Settings Required:")
for requirement in bios_requirements:
print(" - {}".format(requirement))
def before_using_efi(self, org_hardware_report, hardware_report):
while True:
self.u.head("Before Using EFI")
print("")
print("\033[93mPlease complete the following steps:\033[0m")
print("")
print("* USB Mapping:")
print(" - Use USBToolBox tool to map USB ports.")
print(" - Add created UTBMap.kext into the {} folder.".format("EFI\\OC\\Kexts" if os.name == "nt" else "EFI/OC/Kexts"))
print(" - Remove UTBDefault.kext in the {} folder.".format("EFI\\OC\\Kexts" if os.name == "nt" else "EFI/OC/Kexts"))
print(" - Edit config.plist:")
print(" - Use ProperTree to open your config.plist.")
print(" - Run OC Snapshot by pressing Command/Ctrl + R.")
print(" - If you have more than 15 ports on a single controller, enable the XhciPortLimit patch.")
print(" - Save the file when finished.")
print("")
self.u.open_folder(self.result_dir)
self.u.request_input()
bios_requirements = self.check_bios_requirements(org_hardware_report, hardware_report)
if bios_requirements:
print("* BIOS/UEFI Settings Required:")
for requirement in bios_requirements:
print(" - {}".format(requirement))
print("")
print("* USB Mapping:")
print(" - Use USBToolBox tool to map USB ports.")
print(" - Add created UTBMap.kext into the {} folder.".format("EFI\\OC\\Kexts" if os.name == "nt" else "EFI/OC/Kexts"))
print(" - Remove UTBDefault.kext in the {} folder.".format("EFI\\OC\\Kexts" if os.name == "nt" else "EFI/OC/Kexts"))
print(" - Edit config.plist:")
print(" - Use ProperTree to open your config.plist.")
print(" - Run OC Snapshot by pressing Command/Ctrl + R.")
print(" - If you have more than 15 ports on a single controller, enable the XhciPortLimit patch.")
print(" - Save the file when finished.")
print("")
print("Type \"AGREE\" to open the built EFI for you\n")
response = self.u.request_input("")
if response.lower() == "agree":
self.u.open_folder(self.result_dir)
break
else:
print("\033[91mInvalid input. Please try again.\033[0m")
def main(self):
hardware_report_path = None
@@ -351,20 +354,17 @@ class OCPE:
while True:
self.u.head()
print("")
print("Hardware Report: {}".format("No report selected" if not hardware_report_path else hardware_report_path))
print(" Hardware Report: {}".format(hardware_report_path or 'Not selected'))
print("")
if hardware_report_path:
print("* Hardware Compatibility:")
if native_macos_version:
print(" - Native macOS Version: {}".format(self.c.show_macos_compatibility((native_macos_version[-1], native_macos_version[0]))))
print(" macOS Version: {}".format(os_data.get_macos_name_by_darwin(macos_version) if macos_version else 'Not selected') + (' (' + macos_version + ')' if macos_version else '') + ('. \033[1;93mRequires OpenCore Legacy Patcher\033[0m' if needs_oclp else ''))
print(" SMBIOS: {}".format(smbios_model or 'Not selected'))
if disabled_devices:
print(" - Disabled Devices:")
for index, device_name in enumerate(disabled_devices, start=1):
print("{}{}. {}".format(" "*6, index, device_name))
print("* EFI Options:")
print(" - macOS Version: {}{}{}".format("Unknown" if not macos_version else os_data.get_macos_name_by_darwin(macos_version), "" if not macos_version else " ({})".format(macos_version), ". \033[1;93mRequires OpenCore Legacy Patcher\033[0m" if needs_oclp else ""))
print(" - SMBIOS: {}".format("Unknown" if not smbios_model else smbios_model))
print("")
print(" Disabled Devices:")
for device, _ in disabled_devices.items():
print(" - {}".format(device))
print("")
print("1. Select Hardware Report")
print("2. Select macOS Version")
print("3. Customize ACPI Patch")
@@ -374,16 +374,12 @@ class OCPE:
print("")
print("Q. Quit")
print("")
option = self.u.request_input("Select an option: ")
if option.lower() == "q":
self.u.exit_program()
try:
option = int(option)
except:
continue
if option == 1:
if option == "1":
hardware_report_path, hardware_report = self.select_hardware_report()
hardware_report, native_macos_version, ocl_patched_macos_version = self.c.check_compatibility(hardware_report)
macos_version = self.select_macos_version(hardware_report, native_macos_version, ocl_patched_macos_version)
@@ -394,40 +390,49 @@ class OCPE:
self.ac.select_acpi_patches(customized_hardware, disabled_devices)
needs_oclp = self.k.select_required_kexts(customized_hardware, macos_version, needs_oclp, self.ac.patches)
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
elif option < 7:
try:
customized_hardware
except:
self.u.request_input("\nPlease select a hardware report to proceed")
continue
if option == 2:
if not hardware_report_path:
self.u.head()
print("\n\n")
print("\033[1;93mPlease select a hardware report first.\033[0m")
print("\n\n")
self.u.request_input("Press Enter to go back...")
continue
if option == "2":
macos_version = self.select_macos_version(hardware_report, native_macos_version, ocl_patched_macos_version)
customized_hardware, disabled_devices, needs_oclp = self.h.hardware_customization(hardware_report, macos_version)
smbios_model = self.s.select_smbios_model(customized_hardware, macos_version)
needs_oclp = self.k.select_required_kexts(customized_hardware, macos_version, needs_oclp, self.ac.patches)
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
elif option == "3":
self.ac.customize_patch_selection()
elif option == "4":
self.k.kext_configuration_menu(macos_version)
elif option == "5":
smbios_model = self.s.customize_smbios_model(customized_hardware, smbios_model, macos_version)
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
elif option == "6":
if needs_oclp and not self.show_oclp_warning():
macos_version = self.select_macos_version(hardware_report, native_macos_version, ocl_patched_macos_version)
customized_hardware, disabled_devices, needs_oclp = self.h.hardware_customization(hardware_report, macos_version)
smbios_model = self.s.select_smbios_model(customized_hardware, macos_version)
needs_oclp = self.k.select_required_kexts(customized_hardware, macos_version, needs_oclp, self.ac.patches)
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
elif option == 3:
self.ac.customize_patch_selection()
elif option == 4:
self.k.kext_configuration_menu(macos_version)
elif option == 5:
smbios_model = self.s.customize_smbios_model(customized_hardware, smbios_model, macos_version)
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
elif option == 6:
if needs_oclp and not self.show_oclp_warning():
macos_version = self.select_macos_version(hardware_report, native_macos_version, ocl_patched_macos_version)
customized_hardware, disabled_devices, needs_oclp = self.h.hardware_customization(hardware_report, macos_version)
smbios_model = self.s.select_smbios_model(customized_hardware, macos_version)
needs_oclp = self.k.select_required_kexts(customized_hardware, macos_version, needs_oclp, self.ac.patches)
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
continue
continue
if not self.o.gather_bootloader_kexts(self.k.kexts, macos_version):
continue
if not self.o.gather_bootloader_kexts(self.k.kexts, macos_version):
continue
self.build_opencore_efi(customized_hardware, disabled_devices, smbios_model, macos_version, needs_oclp)
self.results(hardware_report, customized_hardware)
self.build_opencore_efi(customized_hardware, disabled_devices, smbios_model, macos_version, needs_oclp)
self.before_using_efi(hardware_report, customized_hardware)
self.u.head("Result")
print("")
print("Your OpenCore EFI for {} has been built at:".format(customized_hardware.get("Motherboard").get("Name")))
print("\t{}".format(self.result_dir))
print("")
self.u.request_input("Press Enter to main menu...")
if __name__ == '__main__':
update_flag = updater.Updater().run_update()
+1 -3
View File
@@ -3331,9 +3331,7 @@ DefinitionBlock ("", "SSDT", 2, "ZPSS", "WMIS", 0x00000000)
if kext.checked:
line = "\033[1;32m{}\033[0m".format(line)
contents.append(line)
contents.append("\033[1;36m")
contents.append("Note: You can select multiple kexts by entering their indices separated by commas (e.g., '1, 2, 3').")
contents.append("\033[0m")
contents.append("\033[1;93mNote:\033[0m You can select multiple kexts by entering their indices separated by commas (e.g., '1, 2, 3').")
contents.append("B. Back")
contents.append("Q. Quit")
contents.append("")
+3 -3
View File
@@ -221,7 +221,7 @@ class CompatibilityChecker:
print("{}- Audio Endpoint{}: {}".format(" "*6, "s" if len(audio_endpoints) > 1 else "", ", ".join(audio_endpoints)))
def check_biometric_compatibility(self):
print(" \033[93mNote:\033[0m Biometric authentication in macOS requires Apple T2 Chip,")
print(" \033[1;93mNote:\033[0m Biometric authentication in macOS requires Apple T2 Chip,")
print(" which is not available for Hackintosh systems.")
print("")
for biometric_device, biometric_props in self.hardware_report.get("Biometric", {}).items():
@@ -273,10 +273,10 @@ class CompatibilityChecker:
print("{}- Continuity Support: \033[1;32mFull\033[0m (AirDrop, Handoff, Universal Clipboard, Instant Hotspot,...)".format(" "*6))
elif device_id in pci_data.IntelWiFiIDs:
print("{}- Continuity Support: \033[1;33mPartial\033[0m (Handoff and Universal Clipboard with AirportItlwm)".format(" "*6))
print("{}\033[93mNote:\033[0m AirDrop, Universal Clipboard, Instant Hotspot,... not available".format(" "*6))
print("{}\033[1;93mNote:\033[0m AirDrop, Universal Clipboard, Instant Hotspot,... not available".format(" "*6))
elif device_id in pci_data.AtherosWiFiIDs:
print("{}- Continuity Support: \033[1;31mLimited\033[0m (No Continuity features available)".format(" "*6))
print("{}\033[93mNote:\033[0m Atheros cards are not recommended for macOS".format(" "*6))
print("{}\033[1;93mNote:\033[0m Atheros cards are not recommended for macOS".format(" "*6))
if "OCLP Compatibility" in device_props:
print("{}- OCLP Compatibility: {}".format(" "*6, self.show_macos_compatibility(device_props.get("OCLP Compatibility"))))
+1 -1
View File
@@ -286,7 +286,7 @@ class ConfigProdigy:
else:
contents.append(line)
contents.append("")
contents.append("\033[93mNote:\033[0m")
contents.append("\033[1;93mNote:\033[0m")
contents.append("- The default layout may not be optimal.")
contents.append("- Test different layouts to find what works best for your system.")
contents.append("")
+1 -2
View File
@@ -3,7 +3,6 @@ from Scripts import kext_maestro
from Scripts import resource_fetcher
from Scripts import utils
import os
import tempfile
import shutil
import subprocess
import platform
@@ -21,7 +20,7 @@ class gatheringFiles:
self.amd_vanilla_patches_url = "https://raw.githubusercontent.com/AMD-OSX/AMD_Vanilla/beta/patches.plist"
self.aquantia_macos_patches_url = "https://raw.githubusercontent.com/CaseySJ/Aquantia-macOS-Patches/refs/heads/main/CaseySJ-Aquantia-Patch-Sets-1-and-2.plist"
self.hyper_threading_patches_url = "https://github.com/b00t0x/CpuTopologyRebuild/raw/refs/heads/master/patches_ht.plist"
self.temporary_dir = tempfile.mkdtemp()
self.temporary_dir = self.utils.get_temporary_dir()
self.ock_files_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "OCK_Files")
self.bootloader_kexts_data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "bootloader_kexts_data.json")
self.download_history_file = os.path.join(self.ock_files_dir, "history.json")
+18 -18
View File
@@ -122,7 +122,7 @@ class KextMaestro:
for codec_properties in hardware_report.get("Sound", {}).values():
if codec_properties.get("Device ID") in codec_layouts.data:
if self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version("25.0.0"):
print("\n\033[93mNote:\033[0m Since macOS Tahoe 26 DP2, Apple has removed AppleHDA kext and uses the Apple T2 chip for audio management.")
print("\n\033[1;93mNote:\033[0m Since macOS Tahoe 26 DP2, Apple has removed AppleHDA kext and uses the Apple T2 chip for audio management.")
print("To use AppleALC, you must rollback AppleHDA. Alternatively, you can use VoodooHDA.")
print("")
print("1. \033[1mAppleALC\033[0m - Requires AppleHDA rollback with \033[1;93mOpenCore Legacy Patcher\033[0m")
@@ -179,8 +179,8 @@ class KextMaestro:
recommended_option = 1
recommended_name = "NootRX"
max_option = 3
print("\033[93mNote:\033[0m - Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD {} GPUs.".format(gpu_props.get("Codename")))
print(" - To avoid this, you can use NootRX or choose not to install a GPU kext.")
print("\033[1;93mNote:\033[0m Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD {} GPUs.".format(gpu_props.get("Codename")))
print("To avoid this, you can use NootRX or choose not to install a GPU kext.")
print("")
print("1. \033[1mNootRX\033[0m - Uses latest GPU firmware")
print("2. \033[1mWhateverGreen\033[0m - Uses original Apple firmware")
@@ -189,16 +189,17 @@ class KextMaestro:
recommended_option = 2
recommended_name = "WhateverGreen"
max_option = 2
print("\033[93mNote:\033[0m - AMD {} GPUs have two available kext options:".format(gpu_props.get("Codename")))
print(" - You can try different kexts after installation to find the best one for your system")
print("\033[1;93mNote:\033[0m")
print("- AMD {} GPUs have two available kext options:".format(gpu_props.get("Codename")))
print("- You can try different kexts after installation to find the best one for your system")
print("")
print("1. \033[1mNootRX\033[0m - Uses latest GPU firmware")
print("2. \033[1mWhateverGreen\033[0m - Uses original Apple firmware")
print("")
if any(other_gpu_props.get("Manufacturer") == "Intel" for other_gpu_props in hardware_report.get("GPU", {}).values()):
print("\033[91mImportant:\033[0m - NootRX kext is not compatible with Intel GPUs")
print(" - Automatically selecting WhateverGreen kext due to Intel GPU compatibility")
print("\033[91mImportant:\033[0m NootRX kext is not compatible with Intel GPUs")
print("Automatically selecting WhateverGreen kext due to Intel GPU compatibility")
print("")
self.utils.request_input("Press Enter to continue...")
continue
@@ -221,9 +222,9 @@ class KextMaestro:
if self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version("25.0.0"):
print("\n*** Found {} is AMD {} GPU.".format(gpu_name, gpu_props.get("Codename")))
print("")
print("\033[93mNote:\033[0m - Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD GPUs.")
print(" - The current recommendation is to not use WhateverGreen.")
print(" - However, you can still try adding it to see if it works on your system.")
print("\033[1;93mNote:\033[0m Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD GPUs.")
print("The current recommendation is to not use WhateverGreen.")
print("However, you can still try adding it to see if it works on your system.")
print("")
self.utils.request_input("Press Enter to continue...")
break
@@ -254,7 +255,7 @@ class KextMaestro:
elif device_id in pci_data.IntelWiFiIDs:
print("\n*** Found {} is Intel WiFi device.".format(network_name))
print("")
print("\033[93mNote:\033[0m Intel WiFi devices have two available kext options:")
print("\033[1;93mNote:\033[0m Intel WiFi devices have two available kext options:")
print("")
print("1. \033[1mAirportItlwm\033[0m - Uses native WiFi settings menu")
print(" • Provides Handoff, Universal Clipboard, Location Services, Instant Hotspot support")
@@ -303,7 +304,7 @@ class KextMaestro:
selected_kexts.append("IOSkywalkFamily")
elif self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version("23.0.0"):
print("")
print("\033[93mNote:\033[0m Since macOS Sonoma 14, iServices won't work with AirportItlwm without patches")
print("\033[1;93mNote:\033[0m Since macOS Sonoma 14, iServices won't work with AirportItlwm without patches")
print("")
while True:
option = self.utils.request_input("Apply OCLP root patch to fix iServices? (yes/No): ").strip().lower()
@@ -651,11 +652,10 @@ class KextMaestro:
for index, (kext_name, is_lilu_dependent) in enumerate(incompatible_kexts, start=1):
print("{:2}. {:25}{}".format(index, kext_name, " - Lilu Plugin" if is_lilu_dependent else ""))
print("\n\033[1;36m")
print("Note:")
print("\n\033[1;93mNote:\033[0m")
print("- With Lilu plugins, using the \"-lilubetaall\" boot argument will force them to load.")
print("- Forcing unsupported kexts can cause system instability. \033[0;31mProceed with caution.\033[0m")
print("\033[0m")
print("")
option = self.utils.request_input("Do you want to force load {} on the unsupported macOS version? (yes/No): ".format("these kexts" if len(incompatible_kexts) > 1 else "this kext"))
@@ -684,12 +684,12 @@ class KextMaestro:
elif not self.utils.parse_darwin_version(kext.min_darwin_version) <= self.utils.parse_darwin_version(macos_version) <= self.utils.parse_darwin_version(kext.max_darwin_version):
line = "\033[90m{}\033[0m".format(line)
contents.append(line)
contents.append("\033[1;36m")
contents.append("Note:")
contents.append("")
contents.append("\033[1;93mNote:\033[0m")
contents.append("- Lines in gray indicate kexts that are not supported by the current macOS version ({}).".format(macos_version))
contents.append("- When a plugin of a kext is selected, the entire kext will be automatically selected.")
contents.append("- You can select multiple kexts by entering their indices separated by commas (e.g., '1, 2, 3').")
contents.append("\033[0m")
contents.append("")
contents.append("B. Back")
contents.append("Q. Quit")
contents.append("")
+63 -36
View File
@@ -8,10 +8,29 @@ import binascii
import subprocess
import pathlib
import zipfile
import tempfile
class Utils:
def __init__(self, script_name = "OpCore Simplify"):
self.script_name = script_name
self.clean_temporary_dir()
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:
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]
@@ -78,18 +97,13 @@ class Utils:
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
return binascii.unhexlify(hex_string)
except binascii.Error:
# Handle invalid hex string
return string
def int_to_hex(self, number):
@@ -98,9 +112,7 @@ class Utils:
def to_little_endian_hex(self, hex_string):
hex_string = hex_string.lower().lstrip("0x")
little_endian_hex = ''.join(reversed([hex_string[i:i+2] for i in range(0, len(hex_string), 2)]))
return little_endian_hex.upper()
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)
@@ -118,29 +130,20 @@ class Utils:
return next((item for item in data[start:end] if item.lower() in search_item.lower()), None)
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
if os.name == 'nt':
path = path.replace('\\', '/')
# Remove redundant slashes
path = re.sub(r'/+', '/', path)
else:
# Remove backslashes
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 parse_darwin_version(self, darwin_version):
@@ -155,36 +158,47 @@ class Utils:
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:
if sys.version_info[0] < 3:
user_response = raw_input(prompt)
else:
user_response = 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 progress_bar(self, title, steps, current_step_index, done=False):
self.head(title)
print("")
if done:
for step in steps:
print(" [\033[92m✓\033[0m] {}".format(step))
else:
for i, step in enumerate(steps):
if i < current_step_index:
print(" [\033[92m✓\033[0m] {}".format(step))
elif i == current_step_index:
print(" [\033[1;93m>\033[0m] {}...".format(step))
else:
print(" [ ] {}".format(step))
print("")
def head(self, text = None, width = 68, resize=True):
if resize:
self.adjust_window_size()
self.clear_screen()
os.system('cls' if os.name=='nt' else 'clear')
if text == None:
text = self.script_name
separator = "#" * width
separator = "" * (width - 2)
title = " {} ".format(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
title = title.center(width - 2)
print("{}\n#{}#\n{}".format(separator, title, separator))
print("{}\n{}\n{}".format(separator, title, separator))
def adjust_window_size(self, content=""):
lines = content.splitlines()
@@ -194,14 +208,27 @@ class Utils:
def exit_program(self):
self.head()
width = 68
print("")
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("For more information, to report errors, or to contribute to the product:".center(width))
print("")
print("Thank you for using our program!")
separator = "" * (width - 4)
print(f"{separator}")
contacts = {
"Facebook": "https://www.facebook.com/macforce2601",
"Telegram": "https://t.me/lzhoang2601",
"GitHub": "https://github.com/lzhoang2801/OpCore-Simplify"
}
for platform, link in contacts.items():
line = f" * {platform}: {link}"
print(f"{line.ljust(width - 4)}")
print(f"{separator}")
print("")
self.request_input("Press Enter to exit.")
print("Thank you for using our program!".center(width))
print("")
self.request_input("Press Enter to exit.".center(width))
sys.exit(0)
+1 -1
View File
@@ -226,7 +226,7 @@ class WifiProfileExtractor:
self.utils.head("WiFi Profile Extractor")
print("")
print("\033[93mNote:\033[0m")
print("\033[1;93mNote:\033[0m")
print("- When using itlwm kext, WiFi appears as Ethernet in macOS")
print("- You'll need Heliport app to manage WiFi connections in macOS")
print("- This step will enable auto WiFi connections at boot time")