From c99805bee5cc066481b93796402569792704e21b Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Sun, 20 Nov 2022 16:36:57 -0700 Subject: [PATCH] gui_main: Move OCLP app to Support folder --- CHANGELOG.md | 1 + gui/gui_main.py | 96 +++++++++++++++++++++++++++++++++++++++++++- resources/updates.py | 23 ++++++----- 3 files changed, 110 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef1f033c9..0a8722134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Add support for AMD GOP injection (AMDGOP.efi) - For MXM iMacs and Mac Pros with GPU VBIOS lacking GOP support (ie. no UEFI output even after OC loads) - Hide OpenCore Boot Picker when waking from hibernation +- Automatically move newer builds of OpenCore-Patcher.app to `/Library/Application Support/Dortania` if previously installed - Increment Binaries: - AirPortBrcmFixup 2.1.6 - release - AppleALC 1.7.6 - release diff --git a/gui/gui_main.py b/gui/gui_main.py index ecb44129f..13ebbfad5 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -15,9 +15,10 @@ import threading from pathlib import Path import binascii import hashlib +from datetime import datetime from resources import constants, defaults, install, installer, utilities, run, generate_smbios, updates, integrity_verification, global_settings, kdk_handler -from resources.sys_patch import sys_patch_download, sys_patch_detect, sys_patch +from resources.sys_patch import sys_patch_download, sys_patch_detect, sys_patch, sys_patch_auto from resources.build import build from data import model_array, os_data, smbios_data, sip_data from gui import menu_redirect, gui_help @@ -182,8 +183,101 @@ class wx_python_gui: self.popup.ShowModal() else: # Spawn thread to check for updates + self.check_for_local_installs() threading.Thread(target=self.check_for_updates).start() + def check_for_local_installs(self, event=None): + # Update app in '/Library/Application Support/Dortania' folder + + # Skip if we're running from source + if self.constants.launcher_script: + return + + # Only performed if application is already installed (ie. we're updating) + application_path = Path("/Library/Application Support/Dortania/OpenCore-Patcher.app") + if not application_path.exists(): + return + + # Check application version + # If we're older than the installed version, skip + application_plist_path = application_path / "Contents/Info.plist" + if not application_plist_path.exists(): + return + + application_plist = plistlib.load(application_plist_path.open("rb")) + if not "CFBundleShortVersionString" in application_plist: + return + + application_version = application_plist["CFBundleShortVersionString"].split(".") + local_version = self.constants.patcher_version.split(".") + + if application_version == local_version: + if "Build Date" not in application_plist: + return + + # Check build date of installed version + plist_path = self.constants.launcher_binary.replace("MacOS/OpenCore-Patcher", "Info.plist") + if not Path(plist_path).exists(): + return + + plist = plistlib.load(Path(plist_path).open("rb")) + if "Build Date" not in plist: + return + + if plist["Build Date"] == application_plist["Build Date"]: + return + + local_build_date = datetime.strptime(plist["Build Date"], "%Y-%m-%d %H:%M:%S") + installed_build_date = datetime.strptime(application_plist["Build Date"], "%Y-%m-%d %H:%M:%S") + + if local_build_date <= installed_build_date: + return + + elif updates.check_binary_updates(self.constants).check_if_build_newer(local_version, application_version) is False: + return + + # Ask user if they want to move the application to the Applications folder + self.popup = wx.MessageDialog( + self.frame, + f"We've detected an old version of OpenCore-Patcher.app installed in the Application Support folder.\n\nWould you like to replace it with this version?", + "Move to Applications?", + wx.YES_NO | wx.ICON_INFORMATION + ) + self.popup.SetYesNoLabels("Move", "Ignore") + answer = self.popup.ShowModal() + if answer != wx.ID_YES: + return + + path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0] + + args = [ + "osascript", + "-e", + f'''do shell script "ditto {path} '/Library/Application Support/Dortania/OpenCore-Patcher.app'"''' + ' with prompt "OpenCore Legacy Patcher needs administrator privileges to copy in."' + " with administrator privileges" + " without altering line endings", + ] + + result = subprocess.run(args,stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if result.returncode != 0: + print("- Failed to move application into /Library/Application Support/Dortania/OpenCore-Patcher.app") + # Notify user we failed to move the application + self.popup = wx.MessageDialog( + self.frame, + f"Failed to move the application to the Applications folder.\n\nThis is likely due to permission errors, you can copy the app manually into '/Library/Application Support/Dortania/OpenCore-Patcher.app' if you continue to see this error.", + "Failed to Move!", + style = wx.OK | wx.ICON_EXCLAMATION + ) + self.popup.ShowModal() + return + + subprocess.run(["xattr", "-cr", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + subprocess.run(["open", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + subprocess.run(["rm", "-R", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.OnCloseFrame(event) + def check_for_updates(self, event=None): if self.constants.has_checked_updates is True: return diff --git a/resources/updates.py b/resources/updates.py index e8d9210a2..1a3281925 100644 --- a/resources/updates.py +++ b/resources/updates.py @@ -27,17 +27,22 @@ class check_binary_updates: return False return False - def check_if_build_newer(self): - # Pad version numbers to match length (ie. 0.1.0 vs 0.1.0.1) - while len(self.remote_version_array) > len(self.binary_version_array): - self.binary_version_array.append(0) - while len(self.remote_version_array) < len(self.binary_version_array): - self.remote_version_array.append(0) + def check_if_build_newer(self, remote_version=None, local_version=None): + if remote_version is None: + remote_version = self.remote_version_array + if local_version is None: + local_version = self.binary_version_array - for i in range(0, len(self.remote_version_array)): - if int(self.remote_version_array[i]) < int(self.binary_version_array[i]): + # Pad version numbers to match length (ie. 0.1.0 vs 0.1.0.1) + while len(remote_version) > len(local_version): + local_version.append(0) + while len(remote_version) < len(local_version): + remote_version.append(0) + + for i in range(0, len(remote_version)): + if int(remote_version[i]) < int(local_version[i]): break - elif int(self.remote_version_array[i]) > int(self.binary_version_array[i]): + elif int(remote_version[i]) > int(local_version[i]): return True return False