Add import error handling and clean CLI menu

This commit is contained in:
Mykola Grymalyuk
2021-09-04 22:31:20 -06:00
parent 077af5afb3
commit d4836514fd
8 changed files with 278 additions and 182 deletions
+1
View File
@@ -21,6 +21,7 @@
- FeatureUnlock 1.0.3 release - FeatureUnlock 1.0.3 release
- Allow iGPU/dGPU switching in Windows - Allow iGPU/dGPU switching in Windows
- Applicable to MacBook Pros with Intel iGPU and Nvidia/AMD dGPU - Applicable to MacBook Pros with Intel iGPU and Nvidia/AMD dGPU
- Clean up Patcher Settings
## 0.2.4 ## 0.2.4
+4 -4
View File
@@ -117,7 +117,7 @@ class OpenCoreLegacyPatcher:
self.constants.nvme_boot = True self.constants.nvme_boot = True
if args.disable_amfi: if args.disable_amfi:
print("- Set Disable AMFI configuration") print("- Set Disable AMFI configuration")
self.constants.disable_amfi = True self.constants.amfi_status = False
if args.wlan: if args.wlan:
print("- Set Wake on WLAN configuration") print("- Set Wake on WLAN configuration")
self.constants.enable_wake_on_wlan = True self.constants.enable_wake_on_wlan = True
@@ -211,11 +211,11 @@ If you plan to create the USB for another machine, please select the "Change Mod
# Building on device and we have a native, supported GPU # Building on device and we have a native, supported GPU
self.constants.sip_status = True self.constants.sip_status = True
# self.constants.secure_status = True # Monterey # self.constants.secure_status = True # Monterey
self.constants.disable_amfi = False self.constants.amfi_status = True
elif host_is_target: elif host_is_target:
self.constants.sip_status = False # Unsigned kexts self.constants.sip_status = False # Unsigned kexts
self.constants.secure_status = False # Root volume modified self.constants.secure_status = False # Root volume modified
self.constants.disable_amfi = True # Unsigned binaries self.constants.amfi_status = False # Unsigned binaries
if model in ModelArray.ModernGPU: if model in ModelArray.ModernGPU:
if host_is_target and model in ["iMac13,1", "iMac13,3"] and self.computer.dgpu: if host_is_target and model in ["iMac13,1", "iMac13,3"] and self.computer.dgpu:
# Some models have a supported dGPU, others don't # Some models have a supported dGPU, others don't
@@ -224,7 +224,7 @@ If you plan to create the USB for another machine, please select the "Change Mod
elif host_is_target: elif host_is_target:
self.constants.sip_status = False # Unsigned kexts self.constants.sip_status = False # Unsigned kexts
self.constants.secure_status = False # Modified root volume self.constants.secure_status = False # Modified root volume
# self.constants.disable_amfi = False # Signed bundles, Don't need to explicitly set currently # self.constants.amfi_status = True # Signed bundles, Don't need to explicitly set currently
if model == "MacBook8,1" and host_is_target: if model == "MacBook8,1" and host_is_target:
# MacBook8,1 has an odd bug where it cannot install Monterey with Minimal spoofing # MacBook8,1 has an odd bug where it cannot install Monterey with Minimal spoofing
self.constants.serial_settings == "Moderate" self.constants.serial_settings == "Moderate"
+117 -28
View File
@@ -24,7 +24,7 @@ class OpenCoreLegacyPatcher:
# Defaults # Defaults
self.constants.sip_status = True self.constants.sip_status = True
self.constants.secure_status = False # Default false for Monterey self.constants.secure_status = False # Default false for Monterey
self.constants.disable_amfi = False self.constants.amfi_status = True
if model in ModelArray.LegacyGPU: if model in ModelArray.LegacyGPU:
if ( if (
@@ -42,21 +42,21 @@ class OpenCoreLegacyPatcher:
# Building on device and we have a native, supported GPU # Building on device and we have a native, supported GPU
self.constants.sip_status = True self.constants.sip_status = True
# self.constants.secure_status = True # Monterey # self.constants.secure_status = True # Monterey
self.constants.disable_amfi = False self.constants.amfi_status = True
else: else:
self.constants.sip_status = False # Unsigned kexts self.constants.sip_status = False # Unsigned kexts
self.constants.secure_status = False # Root volume modified self.constants.secure_status = False # Root volume modified
self.constants.disable_amfi = True # Unsigned binaries self.constants.amfi_status = False # Unsigned binaries
if model in ModelArray.ModernGPU: if model in ModelArray.ModernGPU:
if host_is_target and model in ["iMac13,1", "iMac13,3"] and self.computer.dgpu: if host_is_target and model in ["iMac13,1", "iMac13,3"] and self.computer.dgpu:
# Some models have a supported dGPU, others don't # Some models have a supported dGPU, others don't
self.constants.sip_status = True self.constants.sip_status = True
# self.constants.secure_status = True # Monterey # self.constants.secure_status = True # Monterey
# self.constants.disable_amfi = False # Signed bundles, Don't need to explicitly set currently # self.constants.amfi_status = True # Signed bundles, Don't need to explicitly set currently
else: else:
self.constants.sip_status = False # Unsigned kexts self.constants.sip_status = False # Unsigned kexts
self.constants.secure_status = False # Modified root volume self.constants.secure_status = False # Modified root volume
# self.constants.disable_amfi = False # Signed bundles, Don't need to explicitly set currently # self.constants.amfi_status = True # Signed bundles, Don't need to explicitly set currently
if model == "MacBook8,1": if model == "MacBook8,1":
# MacBook8,1 has an odd bug where it cannot install Monterey with Minimal spoofing # MacBook8,1 has an odd bug where it cannot install Monterey with Minimal spoofing
self.constants.serial_settings = "Moderate" self.constants.serial_settings = "Moderate"
@@ -71,7 +71,7 @@ class OpenCoreLegacyPatcher:
self.constants.verbose_debug = True self.constants.verbose_debug = True
if Utilities.amfi_status() is False: if Utilities.amfi_status() is False:
self.constants.disable_amfi = True self.constants.amfi_status = False
self.constants.latebloom_delay, self.constants.latebloom_range, self.constants.latebloom_debug = Utilities.latebloom_detection(model) self.constants.latebloom_delay, self.constants.latebloom_range, self.constants.latebloom_debug = Utilities.latebloom_detection(model)
@@ -114,31 +114,122 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
title = ["Adjust Patcher Settings"] title = ["Adjust Patcher Settings"]
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [ options = [
[f"Enable Verbose Mode:\t\tCurrently {self.constants.verbose_debug}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_verbose], ["Debug Settings", self.patcher_setting_debug],
[f"Enable OpenCore DEBUG:\t\tCurrently {self.constants.opencore_debug}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_oc], ["Security Settings", self.patcher_settings_security],
[f"Enable Kext DEBUG:\t\t\tCurrently {self.constants.kext_debug}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_kext], ["SMBIOS Settings", self.patcher_settings_smbios],
[f"Set ShowPicker Mode:\t\tCurrently {self.constants.showpicker}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_showpicker], ["Boot Volume Settings", self.patcher_settings_boot],
[f"Set Vault Mode:\t\t\tCurrently {self.constants.vault}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_vault], ["Miscellaneous Settings", self.patcher_settings_misc],
[f"Allow FireWire Boot:\t\tCurrently {self.constants.firewire_boot}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_firewire],
[f"Allow NVMe Boot:\t\t\tCurrently {self.constants.nvme_boot}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_nvme],
[f"Allow Wake on WLAN:\t\t\tCurrently {self.constants.enable_wake_on_wlan}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_wowl],
[f"Allow Ivy iMac iGPU:\t\tCurrently {self.constants.allow_ivy_igpu}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_ivy],
[f"Allow Accel on Mojave/Catalina:\tCurrently {self.constants.moj_cat_accel}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_moj_cat_patch],
[f"Disable Thunderbolt:\t\tCurrently {self.constants.disable_thunderbolt}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).disable_thunderbolt],
[f"Disable AMFI:\t\t\tCurrently {self.constants.disable_amfi}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).set_amfi],
[ [
f"Set SIP and SecureBootModel:\tSIP: {self.constants.sip_status} SBM: {self.constants.secure_status}", f"Allow Accel on Mojave/Catalina:\tCurrently {self.constants.moj_cat_accel}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_sip, CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_moj_cat_patch,
], ],
[ [
f"Allow OpenCore on native Models:\tCurrently {self.constants.allow_oc_everywhere}", f"Allow OpenCore on native Models:\tCurrently {self.constants.allow_oc_everywhere}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_native_models, CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_native_models,
], ],
["Advanced Settings, for developers only", self.advanced_patcher_settings],
]
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
def patcher_setting_debug(self):
response = None
while not (response and response == -1):
title = ["Adjust Debug Settings"]
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [
[f"Enable Verbose Mode:\tCurrently {self.constants.verbose_debug}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_verbose],
[f"Enable OpenCore DEBUG:\tCurrently {self.constants.opencore_debug}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_oc],
[f"Enable Kext DEBUG:\t\tCurrently {self.constants.kext_debug}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_kext],
] + (
[ [
f"Latebloom settings:\t\tDelay {self.constants.latebloom_delay}, Range {self.constants.latebloom_range}, Debug {self.constants.latebloom_debug}", [
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).latebloom_settings, f"Set Latebloom args:\t\tDelay {self.constants.latebloom_delay}, Range {self.constants.latebloom_range}, Debug {self.constants.latebloom_debug}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).latebloom_settings,
]
]
if ((self.constants.custom_model or self.computer.real_model) in ModelArray.PCIRaceCondition)
else []
)
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
def patcher_settings_security(self):
response = None
while not (response and response == -1):
title = ["Adjust Security Settings"]
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [
[
f"Set Apple Mobile File Integrity (AMFI):\tCurrently {self.constants.amfi_status}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).set_amfi,
],
[
f"Set System Intrgity Protection (SIP):\tCurrently {self.constants.sip_status}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_sip,
],
[
f"Set Secure Boot Model (SBM):\t\tCurrently {self.constants.secure_status}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_sbm,
],
[f"Set Vault Mode:\t\t\t\tCurrently {self.constants.vault}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_vault],
]
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
def patcher_settings_smbios(self):
response = None
while not (response and response == -1):
title = ["Adjust SMBIOS Settings"]
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [
[f"Set SMBIOS Spoof Level:\tCurrently {self.constants.serial_settings}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_serial],
[f"Set SMBIOS Spoof Model:\tCurrently {self.constants.override_smbios}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).set_smbios],
[f"Set Custom name {self.constants.custom_cpu_model_value}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).custom_cpu],
]
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
def patcher_settings_boot(self):
response = None
while not (response and response == -1):
title = ["Adjust Bootable Volume Settings"]
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [
[f"Allow FireWire Boot:\tCurrently {self.constants.firewire_boot}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_firewire],
[f"Allow NVMe Boot:\t\tCurrently {self.constants.nvme_boot}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_nvme],
]
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
def patcher_settings_misc(self):
response = None
while not (response and response == -1):
title = ["Adjust Miscellaneous Settings"]
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [
[f"Set ShowPicker Mode:\tCurrently {self.constants.showpicker}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_showpicker],
[f"Allow Wake on WLAN:\t\tCurrently {self.constants.enable_wake_on_wlan}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_wowl],
[f"Allow Ivy iMac iGPU:\tCurrently {self.constants.allow_ivy_igpu}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).allow_ivy],
[
f"Disable Thunderbolt:\tCurrently {self.constants.disable_thunderbolt}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).disable_thunderbolt,
], ],
["Advanced Patch Settings, for developers only", self.advanced_patcher_settings],
] ]
for option in options: for option in options:
@@ -153,16 +244,12 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [ options = [
[f"Assume Metal GPU Always:\t\tCurrently {self.constants.imac_vendor}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_metal], [f"Assume Metal GPU Always:\t\tCurrently {self.constants.imac_vendor}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_metal],
[f"Set SMBIOS Mode:\t\t\tCurrently {self.constants.serial_settings}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_serial],
[f"DRM Preferences:\t\t\tCurrently {self.constants.drm_support}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).drm_setting], [f"DRM Preferences:\t\t\tCurrently {self.constants.drm_support}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).drm_setting],
[f"Set Generic Bootstrap:\t\tCurrently {self.constants.boot_efi}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).bootstrap_setting], [f"Set Generic Bootstrap:\t\tCurrently {self.constants.boot_efi}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).bootstrap_setting],
[ [
f"Disable CPU Friend:\t\t\tCurrently {self.constants.disallow_cpufriend}", f"Disable CPU Friend:\t\t\tCurrently {self.constants.disallow_cpufriend}",
CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).disable_cpufriend, CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).disable_cpufriend,
], ],
[f"Override SMBIOS Spoof:\t\tCurrently {self.constants.override_smbios}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).set_smbios],
[f"Set Custom name {self.constants.custom_cpu_model_value}", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).custom_cpu],
["Set SeedUtil Status", CliMenu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).set_seedutil],
] ]
for option in options: for option in options:
@@ -288,7 +375,9 @@ B. Exit
in_between = [ in_between = [
"Your model is not supported by this patcher for running unsupported OSes!", "Your model is not supported by this patcher for running unsupported OSes!",
"", "",
'If you plan to create the USB for another machine, please select the "Change Model" option in the menu.', 'If you plan to create the USB for another machine, please select the \n"Change Model" option in the menu.',
"",
'If you want to run OCLP on a native Mac, please toggle \n"Allow OpenCore on native Models" in settings',
] ]
elif not self.constants.custom_model and self.computer.real_model == "iMac7,1" and "SSE4.1" not in self.computer.cpu.flags: elif not self.constants.custom_model and self.computer.real_model == "iMac7,1" and "SSE4.1" not in self.computer.cpu.flags:
in_between = [ in_between = [
+1 -1
View File
@@ -656,7 +656,7 @@ class BuildOpenCore:
print("- Disabling SIP") print("- Disabling SIP")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = binascii.unhexlify("EF0F0000") self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = binascii.unhexlify("EF0F0000")
self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["csr-active-config"] self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["csr-active-config"]
if self.constants.disable_amfi is True: if self.constants.amfi_status is False:
print("- Disabling AMFI") print("- Disabling AMFI")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " amfi_get_out_of_my_way=1" self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " amfi_get_out_of_my_way=1"
if self.constants.secure_status is False: if self.constants.secure_status is False:
+130 -146
View File
@@ -14,37 +14,43 @@ class MenuOptions:
def change_verbose(self): def change_verbose(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Set Verbose mode"]) Utilities.header(["Set Verbose mode"])
change_menu = input("Enable Verbose mode(y/n): ") change_menu = input("Enable Verbose mode(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.verbose_debug = True self.constants.verbose_debug = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.verbose_debug = False self.constants.verbose_debug = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_verbose()
def change_oc(self): def change_oc(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Set OpenCore DEBUG mode"]) Utilities.header(["Set OpenCore DEBUG mode"])
change_menu = input("Enable OpenCore DEBUG mode(y/n): ") change_menu = input("Enable OpenCore DEBUG mode(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.opencore_debug = True self.constants.opencore_debug = True
self.constants.opencore_build = "DEBUG" self.constants.opencore_build = "DEBUG"
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.opencore_debug = False self.constants.opencore_debug = False
self.constants.opencore_build = "RELEASE" self.constants.opencore_build = "RELEASE"
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_oc()
def change_kext(self): def change_kext(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Set Kext DEBUG mode"]) Utilities.header(["Set Kext DEBUG mode"])
change_menu = input("Enable Kext DEBUG mode(y/n): ") change_menu = input("Enable Kext DEBUG mode(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.kext_debug = True self.constants.kext_debug = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.kext_debug = False self.constants.kext_debug = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_kext()
def change_metal(self): def change_metal(self):
Utilities.cls() Utilities.cls()
@@ -58,6 +64,7 @@ Valid Options:
1. None(stock GPU) 1. None(stock GPU)
2. Nvidia GPU 2. Nvidia GPU
3. AMD GPU 3. AMD GPU
Q. Return to previous menu
Note: Patcher will detect whether hardware has been upgraded regardless, this Note: Patcher will detect whether hardware has been upgraded regardless, this
option is for those patching on a different machine or OCLP cannot detect. option is for those patching on a different machine or OCLP cannot detect.
@@ -73,12 +80,14 @@ option is for those patching on a different machine or OCLP cannot detect.
elif change_menu == "3": elif change_menu == "3":
self.constants.metal_build = True self.constants.metal_build = True
self.constants.imac_vendor = "AMD" self.constants.imac_vendor = "AMD"
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_metal()
def change_serial(self): def change_serial(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Set SMBIOS Mode"]) Utilities.header(["Set SMBIOS Spoof Level"])
print( print(
"""This section is for setting how OpenCore generates the SMBIOS """This section is for setting how OpenCore generates the SMBIOS
Recommended for adanced users who want control how serials are handled Recommended for adanced users who want control how serials are handled
@@ -88,19 +97,22 @@ Valid options:
1. Minimal:\tUse original serials and minimally update SMBIOS 1. Minimal:\tUse original serials and minimally update SMBIOS
2. Moderate:\tReplace entire SMBIOS but keep original serials 2. Moderate:\tReplace entire SMBIOS but keep original serials
3. Advanced:\tReplace entire SMBIOS and generate new serials 3. Advanced:\tReplace entire SMBIOS and generate new serials
Q. Return to previous menu
Note: For new users we recommend leaving as default(1. Minimal) Note: For new users we recommend leaving as default(1. Minimal)
""" """
) )
change_menu = input("Set SMBIOS Mode(ie. 1): ") change_menu = input("Set SMBIOS Spoof Level(ie. 1): ")
if change_menu == "1": if change_menu == "1":
self.constants.serial_settings = "Minimal" self.constants.serial_settings = "Minimal"
elif change_menu == "2": elif change_menu == "2":
self.constants.serial_settings = "Moderate" self.constants.serial_settings = "Moderate"
elif change_menu == "3": elif change_menu == "3":
self.constants.serial_settings = "Advanced" self.constants.serial_settings = "Advanced"
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_serial()
def change_showpicker(self): def change_showpicker(self):
Utilities.cls() Utilities.cls()
@@ -111,13 +123,15 @@ however this can be disabled by default and be shown on command by repeatedly
pressing the "Esc" key pressing the "Esc" key
""" """
) )
change_menu = input("Show OpenCore Picker by default(y/n): ") change_menu = input("Show OpenCore Picker by default(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.showpicker = True self.constants.showpicker = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.showpicker = False self.constants.showpicker = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_showpicker()
def change_vault(self): def change_vault(self):
Utilities.cls() Utilities.cls()
@@ -131,63 +145,86 @@ Note: For security reasons, OpenShell will be disabled when Vault is set.
""" """
) )
change_menu = input("Enable Vault(y/n): ") change_menu = input("Enable Vault(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.vault = True self.constants.vault = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.vault = False self.constants.vault = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.change_vault()
def change_sip(self): def change_sip(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Set SIP and SecureBootModel"]) Utilities.header(["Set System Integrity protection"])
print( print(
"""SIP and SecureBootModel are used to ensure proper OTA functionality, """SIP is used to ensure proper secuirty measures are set,
however to patch the root volume both of these must be disabled. however to patch the root volume this must be disabled.
Only disable is absolutely necessary. SIP value = 0xFEF Only disable is absolutely necessary. SIP value = 0xFEF
Valid options: Valid options:
1. Enable Both 1. Enable SIP
2. Disable SIP only 2. Disable SIP
3. Disable SecureBootModel Only Q. Return to previous menu
4. Disable Both
""" """
) )
change_menu = input("Set SIP and SecureBootModel(ie. 1): ") change_menu = input("Set SIP: ")
if change_menu == "1": if change_menu == "1":
self.constants.sip_status = True self.constants.sip_status = True
self.constants.secure_status = True
elif change_menu == "2": elif change_menu == "2":
self.constants.sip_status = False self.constants.sip_status = False
self.constants.secure_status = True elif change_menu in {"q", "Q", "Quit", "quit"}:
elif change_menu == "3": print("Returning to previous menu")
self.constants.sip_status = True
self.constants.secure_status = False
elif change_menu == "4":
self.constants.sip_status = False
self.constants.secure_status = False
else: else:
print("Invalid option") self.change_sip()
def change_sbm(self):
Utilities.cls()
Utilities.header(["Set SecureBootModel"])
print(
"""SecureBootModel is used to ensure best firmware security,
however to patch the root volume this must be disabled.
Only disable is absolutely necessary. SIP value = 0xFEF
Valid options:
1. Enable SecureBootModel
2. Disable SecureBootModel
Q. Return to previous menu
"""
)
change_menu = input("Set SecureBootModel: ")
if change_menu == "1":
self.constants.secure_status = True
elif change_menu == "2":
self.constants.secure_status = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else:
self.change_sbm()
def set_amfi(self): def set_amfi(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Disable AMFI"]) Utilities.header(["Set AMFI"])
print( print(
"""Required for Root Patching non-Metal GPUs """Required for Root Patching non-Metal GPUs
in macOS Big Sur. Without this, will receive kernel panic once in macOS Big Sur. Without this, will receive kernel panic once
Patcher finishes installing legacy acceleration patches. Patcher finishes installing legacy acceleration patches.
""" """
) )
change_menu = input("Disable AMFI(y/n): ") change_menu = input("Disable AMFI(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.disable_amfi = True self.constants.amfi_status = False
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.disable_amfi = False self.constants.amfi_status = True
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.set_amfi()
def bootstrap_setting(self): def bootstrap_setting(self):
Utilities.cls() Utilities.cls()
@@ -200,7 +237,7 @@ Valid options:
1. System/Library/CoreServices/boot.efi (default) 1. System/Library/CoreServices/boot.efi (default)
2. EFI/BOOT/BOOTx64.efi 2. EFI/BOOT/BOOTx64.efi
3. Exit Q. Return to previous menu
Note: S*/L*/C*/boot.efi method is only installed to the EFI partition only Note: S*/L*/C*/boot.efi method is only installed to the EFI partition only
and not to macOS itself. and not to macOS itself.
@@ -215,8 +252,10 @@ see the EFI Boot entry in the boot picker.
self.constants.boot_efi = False self.constants.boot_efi = False
elif change_menu == "2": elif change_menu == "2":
self.constants.boot_efi = True self.constants.boot_efi = True
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.bootstrap_setting()
def drm_setting(self): def drm_setting(self):
Utilities.cls() Utilities.cls()
@@ -234,13 +273,15 @@ other programs relying on such features.
Recommend only disabling if absolutely required. Recommend only disabling if absolutely required.
""" """
) )
change_menu = input("Enable Nvidia's Software DRM rendering(y/n): ") change_menu = input("Enable Nvidia's Software DRM rendering(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.drm_support = True self.constants.drm_support = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.drm_support = False self.constants.drm_support = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.drm_setting()
def allow_native_models(self): def allow_native_models(self):
Utilities.cls() Utilities.cls()
@@ -252,15 +293,17 @@ power usage.
""" """
) )
change_menu = input("Allow OpenCore on all Models(y/n): ") change_menu = input("Allow OpenCore on all Models(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.allow_oc_everywhere = True self.constants.allow_oc_everywhere = True
self.constants.serial_settings = "None" self.constants.serial_settings = "None"
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.allow_oc_everywhere = False self.constants.allow_oc_everywhere = False
self.constants.serial_settings = "Minimal" self.constants.serial_settings = "Minimal"
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.allow_native_models()
def custom_cpu(self): def custom_cpu(self):
Utilities.cls() Utilities.cls()
@@ -272,6 +315,7 @@ Custom names will report as follows:
1: Original Name: 2.5 Ghz Dual-Core Intel Core i5 1: Original Name: 2.5 Ghz Dual-Core Intel Core i5
2. CPU name: Intel(R) Core(TM) i5-3210M CPU @ 2.50Ghz 2. CPU name: Intel(R) Core(TM) i5-3210M CPU @ 2.50Ghz
3. Custom Name: 2.5Ghz Cotton Candy (example) 3. Custom Name: 2.5Ghz Cotton Candy (example)
Q. Return to previous menu
""" """
) )
if self.constants.custom_cpu_model_value == "": if self.constants.custom_cpu_model_value == "":
@@ -291,31 +335,10 @@ Custom names will report as follows:
elif change_menu == "3": elif change_menu == "3":
self.constants.custom_cpu_model = 1 self.constants.custom_cpu_model = 1
self.constants.custom_cpu_model_value = input("Enter new CPU Name: ") self.constants.custom_cpu_model_value = input("Enter new CPU Name: ")
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.custom_cpu()
def custom_color_thing(self):
Utilities.cls()
Utilities.header(["Set custom CPU Model Name"])
print(
"""Change reported CPU Model name in About This Mac
Custom names will report as follows:
1: Custom Color
2. Reset
"""
)
change_menu = input("Set custom CPU Name(1,2,3): ")
if change_menu == "1":
print("")
# temp_tk_root = tk.Tk()
# temp_tk_root.wm_withdraw()
# self.constants.custom_color = colorchooser.askcolor(title="Choose color")
# temp_tk_root.destroy()
elif change_menu == "2":
self.constants.custom_color = ""
else:
print("Invalid option")
def disable_cpufriend(self): def disable_cpufriend(self):
Utilities.cls() Utilities.cls()
@@ -327,53 +350,19 @@ Mac's power profile for CPUs and GPUs, which can harm the
hardware hardware
""" """
) )
change_menu = input("Disable CPU Friend?(y/n): ") change_menu = input("Disable CPU Friend?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.disallow_cpufriend = True self.constants.disallow_cpufriend = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.disallow_cpufriend = False self.constants.disallow_cpufriend = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.disable_cpufriend()
def set_seedutil(self):
Utilities.cls()
Utilities.header(["Set SeedUtil Status"])
print(
"""Used for setting OS Update Preferences
Valid options:
1. Public Release Seed (Default)
2. Public Beta Seed
3. Developer Beta Seed
4. Check SeedUtil's current status
"""
)
change_menu = input("Set update status(Press [ENTER] to exit): ")
if change_menu == "1":
subprocess.run(["sudo", "/System/Library/PrivateFrameworks/Seeding.framework/Versions/A/Resources/seedutil", "unenroll"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
elif change_menu == "2":
subprocess.run(["sudo", "/System/Library/PrivateFrameworks/Seeding.framework/Versions/A/Resources/seedutil", "unenroll"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
subprocess.run(
["sudo", "/System/Library/PrivateFrameworks/Seeding.framework/Versions/A/Resources/seedutil", "enroll", "PublicSeed"], stdout=subprocess.PIPE
).stdout.decode().strip().encode()
elif change_menu == "3":
subprocess.run(["sudo", "/System/Library/PrivateFrameworks/Seeding.framework/Versions/A/Resources/seedutil", "unenroll"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
subprocess.run(
["sudo", "/System/Library/PrivateFrameworks/Seeding.framework/Versions/A/Resources/seedutil", "enroll", "DeveloperSeed"], stdout=subprocess.PIPE
).stdout.decode().strip().encode()
elif change_menu == "4":
result = subprocess.run(["sudo", "/System/Library/PrivateFrameworks/Seeding.framework/Versions/A/Resources/seedutil", "current"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
result = [i.partition(":")[2] for i in result.stdout.decode().split("\n") if "Currently enrolled in" in i][0]
print(f"SeedUtil Current Status: {result}")
input("\nPress [ENTER] to continue")
self.set_seedutil()
else:
print("Returning to main menu")
def set_smbios(self): def set_smbios(self):
Utilities.cls() Utilities.cls()
Utilities.header(["Override SMBIOS Spoof"]) Utilities.header(["Set SMBIOS Spoof Model"])
print( print(
"""Change model OpenCore spoofs Mac too """Change model OpenCore spoofs Mac too
@@ -381,10 +370,11 @@ Valid options:
1. Default set by OpenCore (Default) 1. Default set by OpenCore (Default)
2. User Override 2. User Override
3. Disable all spoofing (unsupported configuration) 3. Disable all spoofing (unsupported configuration)
Q. Return to previous menu
""" """
) )
change_menu = input("Set SMBIOS status: ") change_menu = input("Set SMBIOS Spoof Model: ")
if change_menu == "1": if change_menu == "1":
print("Setting SMBIOS spoof to default mode") print("Setting SMBIOS spoof to default mode")
self.constants.override_smbios = "Default" self.constants.override_smbios = "Default"
@@ -399,8 +389,10 @@ Valid options:
elif change_menu == "3": elif change_menu == "3":
print("Disabling SMBIOS spoof") print("Disabling SMBIOS spoof")
self.constants.override_smbios = self.model self.constants.override_smbios = self.model
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Returning to main menu") self.set_smbios()
def allow_firewire(self): def allow_firewire(self):
Utilities.cls() Utilities.cls()
@@ -419,13 +411,15 @@ Note: MacBook5,x-7,1 don't support FireWire boot
""" """
) )
change_menu = input("Enable FireWire Boot support?(y/n): ") change_menu = input("Enable FireWire Boot support?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.firewire_boot = True self.constants.firewire_boot = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.firewire_boot = False self.constants.firewire_boot = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.allow_firewire()
def allow_nvme(self): def allow_nvme(self):
Utilities.cls() Utilities.cls()
@@ -444,39 +438,15 @@ OpenCore will enable NVMe support in it's picker
""" """
) )
change_menu = input("Enable NVMe Boot support?(y/n): ") change_menu = input("Enable NVMe Boot support?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.nvme_boot = True self.constants.nvme_boot = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.nvme_boot = False self.constants.nvme_boot = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.allow_nvme()
def enable_terascale(self):
Utilities.cls()
Utilities.header(["Enable TeraScale 2 Acceleration"])
print(
"""
Currently TeraScale 2 graphics acceleration is in beta with
some unfortunate bugs on login including strobing colours
until the user forces Million Colours on the Display with
SwitchResX or resXtreme
Users sensitive to seizures should avoid using TeraScale 2
patches or ask someone to handle inital setup to ensure
no issues
Note: Acceleration only applies to macOS Big Sur
"""
)
change_menu = input("Enable TS2 Acceleration?(y/n): ")
if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.terascale_2_patch = True
elif change_menu in {"n", "N", "no", "No"}:
self.constants.terascale_2_patch = False
else:
print("Invalid option")
def allow_wowl(self): def allow_wowl(self):
Utilities.cls() Utilities.cls()
@@ -492,13 +462,15 @@ be prepared if enabling.
""" """
) )
change_menu = input("Allow Wake on WLAN?(y/n): ") change_menu = input("Allow Wake on WLAN?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.enable_wake_on_wlan = True self.constants.enable_wake_on_wlan = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.enable_wake_on_wlan = False self.constants.enable_wake_on_wlan = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.allow_wowl()
def allow_ivy(self): def allow_ivy(self):
Utilities.cls() Utilities.cls()
@@ -518,13 +490,15 @@ Note 2: This setting only affects iMac13,x with dGPUs
""" """
) )
change_menu = input("Allow Ivy iMac iGPU?(y/n): ") change_menu = input("Allow Ivy iMac iGPU?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.allow_ivy_igpu = True self.constants.allow_ivy_igpu = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.allow_ivy_igpu = False self.constants.allow_ivy_igpu = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.allow_ivy()
def latebloom_settings(self): def latebloom_settings(self):
Utilities.cls() Utilities.cls()
@@ -539,6 +513,7 @@ Valid options:
1. Set delay (currently: {self.constants.latebloom_delay}ms) 1. Set delay (currently: {self.constants.latebloom_delay}ms)
2. Set range (currently: {self.constants.latebloom_range}ms) 2. Set range (currently: {self.constants.latebloom_range}ms)
3. Set debug (currently: {bool(self.constants.latebloom_debug)}) 3. Set debug (currently: {bool(self.constants.latebloom_debug)})
Q. Return to previous menu
""" """
) )
@@ -548,11 +523,13 @@ Valid options:
self.constants.latebloom_delay = int(input("Set delay: ")) self.constants.latebloom_delay = int(input("Set delay: "))
except ValueError: except ValueError:
input("Invalid value, press [ENTER] to continue") input("Invalid value, press [ENTER] to continue")
self.latebloom_settings()
elif change_menu == "2": elif change_menu == "2":
try: try:
self.constants.latebloom_range = int(input("Set range: ")) self.constants.latebloom_range = int(input("Set range: "))
except ValueError: except ValueError:
input("Invalid value, press [ENTER] to continue") input("Invalid value, press [ENTER] to continue")
self.latebloom_settings()
elif change_menu == "3": elif change_menu == "3":
try: try:
print("Currently supports either 0(False) or 1(True)") print("Currently supports either 0(False) or 1(True)")
@@ -563,8 +540,11 @@ Valid options:
self.constants.latebloom_debug = latebloom_debug self.constants.latebloom_debug = latebloom_debug
except ValueError: except ValueError:
input("Invalid value, press [ENTER] to continue") input("Invalid value, press [ENTER] to continue")
self.latebloom_settings()
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.latebloom_settings()
def allow_moj_cat_patch(self): def allow_moj_cat_patch(self):
@@ -585,13 +565,15 @@ Note: for the average user, we recommend using dosdude1's legacy patcher:
""" """
) )
change_menu = input("Allow Root Patching on Mojave/Catalina?(y/n): ") change_menu = input("Allow Root Patching on Mojave/Catalina?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.moj_cat_accel = True self.constants.moj_cat_accel = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.moj_cat_accel = False self.constants.moj_cat_accel = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.allow_moj_cat_patch()
def disable_thunderbolt(self): def disable_thunderbolt(self):
Utilities.cls() Utilities.cls()
@@ -609,10 +591,12 @@ other devices that benefit from this fix.
""" """
) )
change_menu = input("Disable Thunderbolt?(y/n): ") change_menu = input("Disable Thunderbolt?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}: if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.disable_thunderbolt = True self.constants.disable_thunderbolt = True
elif change_menu in {"n", "N", "no", "No"}: elif change_menu in {"n", "N", "no", "No"}:
self.constants.disable_thunderbolt = False self.constants.disable_thunderbolt = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else: else:
print("Invalid option") self.disable_thunderbolt()
+1 -1
View File
@@ -86,7 +86,7 @@ class Constants:
self.apecid_support = False self.apecid_support = False
self.firewire_boot = False self.firewire_boot = False
self.nvme_boot = False self.nvme_boot = False
self.disable_amfi = False self.amfi_status = True
self.terascale_2_patch = False self.terascale_2_patch = False
self.enable_wake_on_wlan = False self.enable_wake_on_wlan = False
self.allow_ivy_igpu = False self.allow_ivy_igpu = False
+14 -1
View File
@@ -9,7 +9,15 @@ import subprocess
from pathlib import Path from pathlib import Path
import re import re
import os import os
import requests
try:
import requests
except ImportError:
subprocess.run(["pip3", "install", "requests"], stdout=subprocess.PIPE)
try:
import requests
except ImportError:
raise Exception("Missing requests library!\nPlease run the following before starting OCLP:\npip3 install requests")
from Resources import Constants, ioreg from Resources import Constants, ioreg
@@ -225,6 +233,11 @@ def download_file(link, location):
chunk = file.read(1024 * 1024 * 16) chunk = file.read(1024 * 1024 * 16)
return checksum return checksum
def enable_apfs(fw_feature, fw_mask):
fw_feature |= 2**19
fw_mask |= 2**19
# def menu(title, prompt, menu_options, add_quit=True, auto_number=False, in_between=[], top_level=False): # def menu(title, prompt, menu_options, add_quit=True, auto_number=False, in_between=[], top_level=False):
# return_option = ["Q", "Quit", None] if top_level else ["B", "Back", None] # return_option = ["Q", "Quit", None] if top_level else ["B", "Back", None]
+10 -1
View File
@@ -4,8 +4,17 @@
from __future__ import annotations from __future__ import annotations
from typing import NewType, Union from typing import NewType, Union
import subprocess
try:
import objc
except ImportError:
subprocess.run(["pip3", "install", "pyobjc"], stdout=subprocess.PIPE)
try:
import objc
except ImportError:
raise Exception("Missing PyObjc library!\nPlease run the following before starting OCLP:\npip3 install pyobjc")
import objc
from CoreFoundation import CFRelease, kCFAllocatorDefault # type: ignore # pylint: disable=no-name-in-module from CoreFoundation import CFRelease, kCFAllocatorDefault # type: ignore # pylint: disable=no-name-in-module
from Foundation import NSBundle # type: ignore # pylint: disable=no-name-in-module from Foundation import NSBundle # type: ignore # pylint: disable=no-name-in-module
from PyObjCTools import Conversion from PyObjCTools import Conversion