mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-06-20 14:10:51 +10:00
Add App Update checks to GUI
This commit is contained in:
@@ -26,6 +26,9 @@
|
|||||||
- Disable AirPlay to Mac/Sidecar patch set by default
|
- Disable AirPlay to Mac/Sidecar patch set by default
|
||||||
- Work-around some older systems with memory instability
|
- Work-around some older systems with memory instability
|
||||||
- Configurable by end user to re-enable (via FeatureUnlock setting)
|
- Configurable by end user to re-enable (via FeatureUnlock setting)
|
||||||
|
- Add App Update checks to GUI
|
||||||
|
- If new version available, app will prompt on launch.
|
||||||
|
- Configurable in Developer Settings
|
||||||
|
|
||||||
## 0.3.3
|
## 0.3.3
|
||||||
- Disable Asset Caching support with spoofless approach
|
- Disable Asset Caching support with spoofless approach
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ exe = EXE(pyz,
|
|||||||
app = BUNDLE(exe,
|
app = BUNDLE(exe,
|
||||||
name='OpenCore-Patcher.app',
|
name='OpenCore-Patcher.app',
|
||||||
icon="payloads/OC-Patcher.icns",
|
icon="payloads/OC-Patcher.icns",
|
||||||
bundle_identifier=None,
|
bundle_identifier="com.dortania.opencore-legacy-patcher-wxpython",
|
||||||
info_plist={
|
info_plist={
|
||||||
"CFBundleShortVersionString": constants.Constants().patcher_version,
|
"CFBundleShortVersionString": constants.Constants().patcher_version,
|
||||||
"NSHumanReadableCopyright": "Copyright 2020-2022 Dortania",
|
"NSHumanReadableCopyright": "Copyright 2020-2022 Dortania",
|
||||||
|
|||||||
+52
-3
@@ -10,8 +10,9 @@ import time
|
|||||||
import os
|
import os
|
||||||
import wx.adv
|
import wx.adv
|
||||||
from wx.lib.agw import hyperlink
|
from wx.lib.agw import hyperlink
|
||||||
|
import threading
|
||||||
|
|
||||||
from resources import constants, defaults, build, install, installer, utilities, sys_patch_detect, sys_patch, run, generate_smbios
|
from resources import constants, defaults, build, install, installer, utilities, sys_patch_detect, sys_patch, run, generate_smbios, updates
|
||||||
from data import model_array, os_data, smbios_data, sip_data
|
from data import model_array, os_data, smbios_data, sip_data
|
||||||
from gui import menu_redirect
|
from gui import menu_redirect
|
||||||
|
|
||||||
@@ -60,6 +61,8 @@ class wx_python_gui:
|
|||||||
if current_uid == 0:
|
if current_uid == 0:
|
||||||
self.file_menu.Enable(wx.ID_REDO, False)
|
self.file_menu.Enable(wx.ID_REDO, False)
|
||||||
|
|
||||||
|
# Spawn thread to check for updates
|
||||||
|
threading.Thread(target=self.check_for_updates).start()
|
||||||
self.main_menu(None)
|
self.main_menu(None)
|
||||||
|
|
||||||
wx.CallAfter(self.frame.Close)
|
wx.CallAfter(self.frame.Close)
|
||||||
@@ -76,6 +79,36 @@ class wx_python_gui:
|
|||||||
sys.stdout = self.stock_stdout
|
sys.stdout = self.stock_stdout
|
||||||
sys.stderr = self.stock_stderr
|
sys.stderr = self.stock_stderr
|
||||||
|
|
||||||
|
def check_for_updates(self, event=None):
|
||||||
|
ignore_updates = subprocess.run(["defaults", "read", "com.dortania.opencore-legacy-patcher-wxpython", "IgnoreAppUpdates"], capture_output=True).stdout.decode("utf-8").strip()
|
||||||
|
if ignore_updates not in ["1", "True", "TRUE"]:
|
||||||
|
self.constants.ignore_updates = False
|
||||||
|
dict = updates.check_binary_updates(self.constants).check_binary_updates()
|
||||||
|
if dict:
|
||||||
|
for entry in dict:
|
||||||
|
version = dict[entry]["Version"]
|
||||||
|
github_link = dict[entry]["Github Link"]
|
||||||
|
print(f"New version: {version}")
|
||||||
|
self.dialog = wx.MessageDialog(
|
||||||
|
parent=self.frame,
|
||||||
|
message=f"Current Version: {self.constants.patcher_version}\nNew version: {version}\nWould you like to view?",
|
||||||
|
caption="Update Available for OpenCore Legacy Patcher!",
|
||||||
|
style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION
|
||||||
|
)
|
||||||
|
self.dialog.SetYesNoCancelLabels("View on Github", "Ignore Always", "Ignore Once")
|
||||||
|
responce = self.dialog.ShowModal()
|
||||||
|
if responce == wx.ID_YES:
|
||||||
|
webbrowser.open(github_link)
|
||||||
|
elif responce == wx.ID_NO:
|
||||||
|
print("- Setting IgnoreAppUpdates to True")
|
||||||
|
self.constants.ignore_updates = True
|
||||||
|
subprocess.run(["defaults", "write", "com.dortania.opencore-legacy-patcher-wxpython", "IgnoreAppUpdates", "-bool", "TRUE"])
|
||||||
|
else:
|
||||||
|
print("No updates available")
|
||||||
|
else:
|
||||||
|
self.constants.ignore_updates = True
|
||||||
|
print("- Ignoring App Updates due to defaults")
|
||||||
|
|
||||||
def relaunch_as_root(self, event=None):
|
def relaunch_as_root(self, event=None):
|
||||||
|
|
||||||
# Add Dialog Box asking if it's ok to relaunch as root
|
# Add Dialog Box asking if it's ok to relaunch as root
|
||||||
@@ -1650,13 +1683,22 @@ class wx_python_gui:
|
|||||||
if self.computer.third_party_sata_ssd is False and not self.constants.custom_model:
|
if self.computer.third_party_sata_ssd is False and not self.constants.custom_model:
|
||||||
self.set_enhanced_3rd_party_ssd_checkbox.Disable()
|
self.set_enhanced_3rd_party_ssd_checkbox.Disable()
|
||||||
|
|
||||||
|
# Set Ignore App Updates
|
||||||
|
self.set_ignore_app_updates_checkbox = wx.CheckBox(self.frame, label="Ignore App Updates")
|
||||||
|
self.set_ignore_app_updates_checkbox.SetValue(self.constants.ignore_updates)
|
||||||
|
self.set_ignore_app_updates_checkbox.Bind(wx.EVT_CHECKBOX, self.set_ignore_app_updates_click)
|
||||||
|
self.set_ignore_app_updates_checkbox.SetPosition(wx.Point(
|
||||||
|
self.set_enhanced_3rd_party_ssd_checkbox.GetPosition().x,
|
||||||
|
self.set_enhanced_3rd_party_ssd_checkbox.GetPosition().y + self.set_enhanced_3rd_party_ssd_checkbox.GetSize().height))
|
||||||
|
self.set_ignore_app_updates_checkbox.SetToolTip(wx.ToolTip("This will set whether OpenCore will ignore App Updates on launch.\nEnable this option if you do not want to be prompted for App Updates"))
|
||||||
|
|
||||||
|
|
||||||
# Button: Developer Debug Info
|
# Button: Developer Debug Info
|
||||||
self.debug_button = wx.Button(self.frame, label="Developer Debug Info")
|
self.debug_button = wx.Button(self.frame, label="Developer Debug Info")
|
||||||
self.debug_button.Bind(wx.EVT_BUTTON, self.additional_info_menu)
|
self.debug_button.Bind(wx.EVT_BUTTON, self.additional_info_menu)
|
||||||
self.debug_button.SetPosition(wx.Point(
|
self.debug_button.SetPosition(wx.Point(
|
||||||
self.set_enhanced_3rd_party_ssd_checkbox.GetPosition().x,
|
self.set_ignore_app_updates_checkbox.GetPosition().x,
|
||||||
self.set_enhanced_3rd_party_ssd_checkbox.GetPosition().y + self.set_enhanced_3rd_party_ssd_checkbox.GetSize().height + 5))
|
self.set_ignore_app_updates_checkbox.GetPosition().y + self.set_ignore_app_updates_checkbox.GetSize().height + 5))
|
||||||
self.debug_button.Center(wx.HORIZONTAL)
|
self.debug_button.Center(wx.HORIZONTAL)
|
||||||
|
|
||||||
# Button: return to main menu
|
# Button: return to main menu
|
||||||
@@ -1670,6 +1712,13 @@ class wx_python_gui:
|
|||||||
# set frame size below return to main menu button
|
# set frame size below return to main menu button
|
||||||
self.frame.SetSize(wx.Size(-1, self.return_to_main_menu_button.GetPosition().y + self.return_to_main_menu_button.GetSize().height + 40))
|
self.frame.SetSize(wx.Size(-1, self.return_to_main_menu_button.GetPosition().y + self.return_to_main_menu_button.GetSize().height + 40))
|
||||||
|
|
||||||
|
def set_ignore_app_updates_click(self, event):
|
||||||
|
self.constants.ignore_updates = self.set_ignore_app_updates_checkbox.GetValue()
|
||||||
|
if self.constants.ignore_updates is True:
|
||||||
|
subprocess.run(["defaults", "write", "com.dortania.opencore-legacy-patcher-wxpython", "IgnoreAppUpdates", "-bool", "TRUE"])
|
||||||
|
else:
|
||||||
|
subprocess.run(["defaults", "write", "com.dortania.opencore-legacy-patcher-wxpython", "IgnoreAppUpdates", "-bool", "FALSE"])
|
||||||
|
|
||||||
def firewire_click(self, event=None):
|
def firewire_click(self, event=None):
|
||||||
if self.firewire_boot_checkbox.GetValue():
|
if self.firewire_boot_checkbox.GetValue():
|
||||||
print("Firewire Enabled")
|
print("Firewire Enabled")
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ class Constants:
|
|||||||
self.recovery_status = False # Detect if booted into RecoveryOS
|
self.recovery_status = False # Detect if booted into RecoveryOS
|
||||||
self.launcher_binary = None # Determine launch binary (ie. Python vs PyInstaller)
|
self.launcher_binary = None # Determine launch binary (ie. Python vs PyInstaller)
|
||||||
self.launcher_script = None # Determine launch file (if run via Python)
|
self.launcher_script = None # Determine launch file (if run via Python)
|
||||||
|
self.ignore_updates = False # Ignore OCLP updates
|
||||||
|
|
||||||
## Hardware
|
## Hardware
|
||||||
self.computer: device_probe.Computer = None # type: ignore
|
self.computer: device_probe.Computer = None # type: ignore
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# Copyright (C) 2022, Mykola Grymalyuk
|
||||||
|
# Check whether new updates are available for OpenCore Legacy Patcher binary
|
||||||
|
# Call check_binary_updates() to determine if any updates are available
|
||||||
|
# Returns dict with Link and Version of the latest binary update if available
|
||||||
|
import requests
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class check_binary_updates:
|
||||||
|
def __init__(self, constants):
|
||||||
|
self.constants = constants
|
||||||
|
self.binary_version = self.constants.patcher_version
|
||||||
|
self.binary_version_array = self.binary_version.split(".")
|
||||||
|
self.binary_version_array = [int(x) for x in self.binary_version_array]
|
||||||
|
self.binary_url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
||||||
|
|
||||||
|
self.available_binaries = {}
|
||||||
|
|
||||||
|
def verify_network_connection(self, url):
|
||||||
|
try:
|
||||||
|
response = requests.head(url, timeout=5)
|
||||||
|
if response:
|
||||||
|
return True
|
||||||
|
except (requests.exceptions.Timeout,
|
||||||
|
requests.exceptions.TooManyRedirects,
|
||||||
|
requests.exceptions.ConnectionError,
|
||||||
|
requests.exceptions.HTTPError):
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_if_build_newer(self):
|
||||||
|
for i in range(0, 3):
|
||||||
|
if self.remote_version_array[i] > self.binary_version_array[i]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def determine_local_build_type(self):
|
||||||
|
if self.constants.gui_mode is True:
|
||||||
|
return "GUI"
|
||||||
|
else:
|
||||||
|
return "TUI"
|
||||||
|
|
||||||
|
def determine_local_build_type_offline(self):
|
||||||
|
if (Path(self.constants.payload_path) / f"12-Monterey.zip").exists():
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def determine_remote_type(self, remote_name):
|
||||||
|
if "TUI" in remote_name:
|
||||||
|
return "TUI"
|
||||||
|
elif "GUI" in remote_name:
|
||||||
|
return "GUI"
|
||||||
|
else:
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
def determine_remote_offline_type(self, remote_name):
|
||||||
|
if "Offline" in remote_name:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_binary_updates(self):
|
||||||
|
print("- Checking for updates...")
|
||||||
|
if self.verify_network_connection(self.binary_url):
|
||||||
|
print("- Network connection functional")
|
||||||
|
response = requests.get(self.binary_url)
|
||||||
|
data_set = response.json()
|
||||||
|
print("- Retrived latest version data")
|
||||||
|
self.remote_version = data_set["tag_name"]
|
||||||
|
print(f"- Latest version: {self.remote_version}")
|
||||||
|
self.remote_version_array = self.remote_version.split(".")
|
||||||
|
self.remote_version_array = [
|
||||||
|
int(x) for x in self.remote_version_array
|
||||||
|
]
|
||||||
|
if self.check_if_build_newer() is True:
|
||||||
|
print("- Remote version is newer")
|
||||||
|
for asset in data_set["assets"]:
|
||||||
|
print(f"- Found asset: {asset['name']}")
|
||||||
|
if self.determine_remote_type(
|
||||||
|
asset["name"]) == self.determine_local_build_type(
|
||||||
|
) and self.determine_remote_offline_type(
|
||||||
|
asset["name"]
|
||||||
|
) == self.determine_local_build_type_offline():
|
||||||
|
print(f"- Found matching asset: {asset['name']}")
|
||||||
|
self.available_binaries.update({
|
||||||
|
asset['name']: {
|
||||||
|
"Name":
|
||||||
|
asset["name"],
|
||||||
|
"Version":
|
||||||
|
self.remote_version,
|
||||||
|
"Link":
|
||||||
|
asset["browser_download_url"],
|
||||||
|
"Type":
|
||||||
|
self.determine_remote_type(asset["name"]),
|
||||||
|
"Offline":
|
||||||
|
self.determine_remote_offline_type(
|
||||||
|
asset["name"]),
|
||||||
|
"Github Link":
|
||||||
|
f"https://github.com/dortania/OpenCore-Legacy-Patcher/releases/{self.remote_version}"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
if self.available_binaries:
|
||||||
|
return self.available_binaries
|
||||||
|
else:
|
||||||
|
print("- No matching binaries available")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print("- Failed to connect to GitHub API")
|
||||||
|
return None
|
||||||
Reference in New Issue
Block a user