Swtich to py-applescript library

This commit is contained in:
Mykola Grymalyuk
2023-05-17 12:45:24 -06:00
parent 96fcba8391
commit 7417fc4180
4 changed files with 85 additions and 102 deletions

View File

@@ -33,6 +33,8 @@
- Implement proper UI call backs on long processes - Implement proper UI call backs on long processes
- ex. Root patching - ex. Root patching
- Implement default selections for disks and installers - Implement default selections for disks and installers
- Utilize `py-applescript` for authorization prompts
- Avoids displaying prompts with `osascript` in the title
- Increment Binaries: - Increment Binaries:
- PatcherSupportPkg 1.0.1 - release - PatcherSupportPkg 1.0.1 - release
- OpenCorePkg 0.9.2 - release - OpenCorePkg 0.9.2 - release

View File

@@ -4,3 +4,4 @@ wxpython
pyinstaller pyinstaller
packaging packaging
py_sip_xnu py_sip_xnu
py-applescript

View File

@@ -2,15 +2,17 @@
# Usage solely for TUI # Usage solely for TUI
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
import logging
import plistlib import plistlib
import subprocess import subprocess
import shutil import applescript
import os
import logging
from pathlib import Path from pathlib import Path
from resources import utilities, constants from resources import utilities, constants
from data import os_data from data import os_data
class tui_disk_installation: class tui_disk_installation:
def __init__(self, versions): def __init__(self, versions):
self.constants: constants.Constants = versions self.constants: constants.Constants = versions
@@ -91,36 +93,26 @@ class tui_disk_installation:
return False return False
# TODO: Apple Script fails in Yosemite(?) and older # TODO: Apple Script fails in Yosemite(?) and older
args = [
"osascript",
"-e",
f'''do shell script "diskutil mount {full_disk_identifier}"'''
' with prompt "OpenCore Legacy Patcher needs administrator privileges to mount your EFI."'
" with administrator privileges"
" without altering line endings",
]
logging.info(f"- Mounting partition: {full_disk_identifier}") logging.info(f"- Mounting partition: {full_disk_identifier}")
if self.constants.detected_os >= os_data.os_data.el_capitan and not self.constants.recovery_status: if self.constants.detected_os >= os_data.os_data.el_capitan and not self.constants.recovery_status:
result = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try:
else: applescript.AppleScript(f'''do shell script "diskutil mount {full_disk_identifier}" with prompt "OpenCore Legacy Patcher needs administrator privileges to mount your EFI." with administrator privileges without altering line endings''').run()
result = subprocess.run(f"diskutil mount {full_disk_identifier}".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) except applescript.ScriptError as e:
if "User canceled" in str(e):
if result.returncode != 0:
if "execution error" in result.stderr.decode() and result.stderr.decode().strip()[-5:-1] == "-128":
# cancelled prompt
logging.info("- Mount cancelled by user") logging.info("- Mount cancelled by user")
return return
else: logging.info(f"An error occurred: {e}")
logging.info("An error occurred!")
logging.info(result.stderr.decode())
# Check if we're in Safe Mode, and if so, tell user FAT32 is unsupported
if utilities.check_boot_mode() == "safe_boot": if utilities.check_boot_mode() == "safe_boot":
logging.info("\nSafe Mode detected. FAT32 is unsupported by macOS in this mode.") logging.info("\nSafe Mode detected. FAT32 is unsupported by macOS in this mode.")
logging.info("Please disable Safe Mode and try again.") logging.info("Please disable Safe Mode and try again.")
return return
else:
result = subprocess.run(f"diskutil mount {full_disk_identifier}".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
logging.info("- Mount failed")
logging.info(result.stderr.decode())
return
partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {full_disk_identifier}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()) partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {full_disk_identifier}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
parent_disk = partition_info["ParentWholeDisk"] parent_disk = partition_info["ParentWholeDisk"]
drive_host_info = plistlib.loads(subprocess.run(f"diskutil info -plist {parent_disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()) drive_host_info = plistlib.loads(subprocess.run(f"diskutil info -plist {parent_disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
@@ -132,68 +124,58 @@ class tui_disk_installation:
mount_path = Path(partition_info["MountPoint"]) mount_path = Path(partition_info["MountPoint"])
disk_type = partition_info["BusProtocol"] disk_type = partition_info["BusProtocol"]
if mount_path.exists(): if not mount_path.exists():
if (mount_path / Path("EFI/Microsoft")).exists() and self.constants.gui_mode is False: logging.info("EFI failed to mount!")
logging.info("- Found Windows Boot Loader")
logging.info("\nWould you like to continue installing OpenCore?")
logging.info("Installing OpenCore onto this drive may make Windows unbootable until OpenCore")
logging.info("is removed from the partition")
logging.info("We highly recommend users partition 200MB off their drive with Disk Utility")
logging.info(" Name:\t\t OPENCORE")
logging.info(" Format:\t\t FAT32")
logging.info(" Size:\t\t 200MB")
choice = input("\nWould you like to still install OpenCore to this drive?(y/n): ")
if not choice in ["y", "Y", "Yes", "yes"]:
subprocess.run(["diskutil", "umount", mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
return False return False
if (mount_path / Path("EFI/OC")).exists(): if (mount_path / Path("EFI/OC")).exists():
logging.info("- Removing preexisting EFI/OC folder") logging.info("- Removing preexisting EFI/OC folder")
shutil.rmtree(mount_path / Path("EFI/OC"), onerror=rmtree_handler) subprocess.run(["rm", "-rf", mount_path / Path("EFI/OC")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if (mount_path / Path("System")).exists(): if (mount_path / Path("System")).exists():
logging.info("- Removing preexisting System folder") logging.info("- Removing preexisting System folder")
shutil.rmtree(mount_path / Path("System"), onerror=rmtree_handler) subprocess.run(["rm", "-rf", mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if (mount_path / Path("boot.efi")).exists(): if (mount_path / Path("boot.efi")).exists():
logging.info("- Removing preexisting boot.efi") logging.info("- Removing preexisting boot.efi")
os.remove(mount_path / Path("boot.efi")) subprocess.run(["rm", mount_path / Path("boot.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logging.info("- Copying OpenCore onto EFI partition") logging.info("- Copying OpenCore onto EFI partition")
shutil.copytree(self.constants.opencore_release_folder / Path("EFI/OC"), mount_path / Path("EFI/OC")) subprocess.run(["cp", "-r", self.constants.opencore_release_folder / Path("EFI/OC"), mount_path / Path("EFI/OC")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
shutil.copytree(self.constants.opencore_release_folder / Path("System"), mount_path / Path("System")) subprocess.run(["cp", "-r", self.constants.opencore_release_folder / Path("System"), mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if Path(self.constants.opencore_release_folder / Path("boot.efi")).exists(): if Path(self.constants.opencore_release_folder / Path("boot.efi")).exists():
shutil.copy(self.constants.opencore_release_folder / Path("boot.efi"), mount_path / Path("boot.efi")) subprocess.run(["cp", self.constants.opencore_release_folder / Path("boot.efi"), mount_path / Path("boot.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if self.constants.boot_efi is True: if self.constants.boot_efi is True:
logging.info("- Converting Bootstrap to BOOTx64.efi") logging.info("- Converting Bootstrap to BOOTx64.efi")
if (mount_path / Path("EFI/BOOT")).exists(): if (mount_path / Path("EFI/BOOT")).exists():
shutil.rmtree(mount_path / Path("EFI/BOOT"), onerror=rmtree_handler) subprocess.run(["rm", "-rf", mount_path / Path("EFI/BOOT")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Path(mount_path / Path("EFI/BOOT")).mkdir() Path(mount_path / Path("EFI/BOOT")).mkdir()
shutil.move(mount_path / Path("System/Library/CoreServices/boot.efi"), mount_path / Path("EFI/BOOT/BOOTx64.efi")) subprocess.run(["mv", mount_path / Path("System/Library/CoreServices/boot.efi"), mount_path / Path("EFI/BOOT/BOOTx64.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
shutil.rmtree(mount_path / Path("System"), onerror=rmtree_handler) subprocess.run(["rm", "-rf", mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if determine_sd_card(sd_type) is True: if determine_sd_card(sd_type) is True:
logging.info("- Adding SD Card icon") logging.info("- Adding SD Card icon")
shutil.copy(self.constants.icon_path_sd, mount_path) subprocess.run(["cp", self.constants.icon_path_sd, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
elif ssd_type is True: elif ssd_type is True:
logging.info("- Adding SSD icon") logging.info("- Adding SSD icon")
shutil.copy(self.constants.icon_path_ssd, mount_path) subprocess.run(["cp", self.constants.icon_path_ssd, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
elif disk_type == "USB": elif disk_type == "USB":
logging.info("- Adding External USB Drive icon") logging.info("- Adding External USB Drive icon")
shutil.copy(self.constants.icon_path_external, mount_path) subprocess.run(["cp", self.constants.icon_path_external, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else: else:
logging.info("- Adding Internal Drive icon") logging.info("- Adding Internal Drive icon")
shutil.copy(self.constants.icon_path_internal, mount_path) subprocess.run(["cp", self.constants.icon_path_internal, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logging.info("- Cleaning install location") logging.info("- Cleaning install location")
if not self.constants.recovery_status: if not self.constants.recovery_status:
logging.info("- Unmounting EFI partition") logging.info("- Unmounting EFI partition")
subprocess.run(["diskutil", "umount", mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() subprocess.run(["diskutil", "umount", mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
logging.info("- OpenCore transfer complete") logging.info("- OpenCore transfer complete")
if self.constants.gui_mode is False: if self.constants.gui_mode is False:
logging.info("\nPress [Enter] to continue.\n") logging.info("\nPress [Enter] to continue.\n")
input() input()
else:
logging.info("EFI failed to mount!")
return False
return True
def rmtree_handler(func, path, exc_info): return True
if exc_info[0] == FileNotFoundError:
return
raise # pylint: disable=misplaced-bare-raise

View File

@@ -6,6 +6,7 @@ import subprocess
import tempfile import tempfile
import enum import enum
import logging import logging
import applescript
from data import os_data from data import os_data
from resources import network_handler, utilities from resources import network_handler, utilities
@@ -53,19 +54,16 @@ class InstallerCreation():
""" """
logging.info("- Extracting macOS installer from InstallAssistant.pkg\n This may take some time") logging.info("- Extracting macOS installer from InstallAssistant.pkg\n This may take some time")
args = [ try:
"osascript", applescript.AppleScript(
"-e",
f'''do shell script "installer -pkg {Path(download_path)}/InstallAssistant.pkg -target /"''' f'''do shell script "installer -pkg {Path(download_path)}/InstallAssistant.pkg -target /"'''
' with prompt "OpenCore Legacy Patcher needs administrator privileges to add InstallAssistant."' ' with prompt "OpenCore Legacy Patcher needs administrator privileges to add InstallAssistant."'
" with administrator privileges" " with administrator privileges"
" without altering line endings", " without altering line endings",
] ).run()
except Exception as e:
result = subprocess.run(args,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
logging.info("- Failed to install InstallAssistant") logging.info("- Failed to install InstallAssistant")
logging.info(f" Error Code: {result.returncode}") logging.info(f" Error Code: {e}")
return False return False
logging.info("- InstallAssistant installed") logging.info("- InstallAssistant installed")