From 2e43232f2f3b4e3e08bd93024340e802fb813241 Mon Sep 17 00:00:00 2001 From: Hoang Hong Quan Date: Sun, 28 Jul 2024 06:04:17 +0700 Subject: [PATCH] Add the automatic script update feature --- OpCore-Simplify.py | 35 +++++++----------------- Scripts/utils.py | 17 ------------ updater.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 42 deletions(-) create mode 100644 updater.py diff --git a/OpCore-Simplify.py b/OpCore-Simplify.py index b60ba47..d561d50 100755 --- a/OpCore-Simplify.py +++ b/OpCore-Simplify.py @@ -3,7 +3,9 @@ from Scripts import compatibility_checker from Scripts import efi_builder from Scripts import gathering_files from Scripts import utils +import updater import os +import sys class OCPE: def __init__(self): @@ -13,8 +15,6 @@ class OCPE: self.c = compatibility_checker.CompatibilityChecker() self.b = efi_builder.builder() self.u = utils.Utils() - self.version_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "version.json") - self.current_version = self.u.read_file(self.version_path).get("version") self.hardware = None self.compatibility = None self.macos_version = None @@ -30,22 +30,6 @@ class OCPE: } self.result_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "Results") - def check_for_update(self): - self.u.head("Check for update") - print("") - print(f"Current script version: {self.current_version}") - latest_version = self.u.check_latest_version() - print(f"Latest script version: {latest_version}") - print("") - if latest_version and latest_version > self.current_version: - print(self.u.message("An update is available at \"https://github.com/lzhoang2801/OpCore-Simplify\"", "reminder")) - print(self.u.message("Please download the latest version to ensure the best experience.", "reminder")) - print("") - self.u.request_input() - else: - return - self.u.exit_program() - def gathering_files(self): self.u.head("Gathering Files") print("") @@ -90,7 +74,7 @@ class OCPE: self.select_aida64_report() self.u.head("Review the hardware information") - contents = ["\n"] + contents = [] for index, device_type in enumerate(self.hardware, start=1): contents.append("{}. {}{}".format(index, device_type, "" if device_type == "Intel MEI" else ":")) @@ -107,8 +91,8 @@ class OCPE: else: contents.append("{}* {}{}".format(" "*4, device_name, f": {device_props}" if isinstance(device_props, str) else "")) content = "\n".join(contents) + "\n" - print(content, end="") self.u.adjust_window_size(content) + print(content) self.u.request_input() return @@ -212,7 +196,6 @@ class OCPE: return def main(self): - self.check_for_update() self.gathering_files() self.select_aida64_report() self.hardware_report() @@ -226,8 +209,10 @@ class OCPE: if __name__ == '__main__': o = OCPE() try: - o.main() - except SystemExit: - raise - except BaseException as e: + update_flag = updater.Updater().run_update() + if update_flag: + os.execv(sys.executable, ['python3'] + sys.argv) + else: + o.main() + except Exception as e: o.u.exit_program(o.u.message("\nAn error occurred: {}\n".format(e))) diff --git a/Scripts/utils.py b/Scripts/utils.py index 152a0e5..07cf1fb 100755 --- a/Scripts/utils.py +++ b/Scripts/utils.py @@ -1,4 +1,3 @@ -from Scripts import resource_fetcher import os import json import plistlib @@ -11,11 +10,6 @@ import pathlib class Utils: def __init__(self, script_name = "OpCore Simplify"): self.script_name = script_name - self.fetcher = resource_fetcher.ResourceFetcher({ - "Accept": "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28", - }) - self.repo_url = "https://raw.githubusercontent.com/lzhoang2801/OpCore-Simplify/main/version.json" def write_file(self, file_path, data): file_extension = os.path.splitext(file_path)[1] @@ -130,17 +124,6 @@ class Utils: def contains_any(self, data, search_item, start=0, end=None): return next((item for item in data[start:end] if item.lower() in search_item.lower()), None) - def check_latest_version(self): - response = self.fetcher.fetch_and_parse_content(self.repo_url, "json") - - latest_version = response.get('version') - - if not latest_version: - print("Version information is missing in the JSON file.") - return None - - return latest_version - def normalize_path(self, path): # Remove all surrounding quotes if present path = re.sub(r'^[\'"]+|[\'"]+$', '', path) diff --git a/updater.py b/updater.py new file mode 100644 index 0000000..ad842ee --- /dev/null +++ b/updater.py @@ -0,0 +1,67 @@ +from Scripts import resource_fetcher +from Scripts import utils +import os +import tempfile +import shutil + +class Updater: + def __init__(self): + self.fetcher = resource_fetcher.ResourceFetcher({ + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }) + self.utils = utils.Utils() + self.verion_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "version.json") + self.download_repo_url = "https://github.com/lzhoang2801/OpCore-Simplify/archive/refs/heads/main.zip" + self.version_url = "https://raw.githubusercontent.com/lzhoang2801/OpCore-Simplify/main/version.json" + self.temporary_dir = tempfile.mkdtemp() + + def get_current_version(self): + version_data = self.utils.read_file(self.verion_file) + + if not version_data or not isinstance(version_data, dict): + print("Version information is missing in the version.json file.\n") + return "0.0.0" + + return version_data.get("version", "0.0.0") + + def get_latest_version(self): + response = self.fetcher.fetch_and_parse_content(self.version_url, "json") + + latest_version = response.get('version') + + return latest_version or "0.0.0" + + def download_update(self): + self.utils.mkdirs(self.temporary_dir) + self.fetcher.download_and_save_file(self.download_repo_url, os.path.join(self.temporary_dir, os.path.basename(self.download_repo_url))) + + def update_files(self): + target_dir = os.path.join(self.temporary_dir, "main", "OpCore-Simplify-main") + for root, dirs, files in os.walk(target_dir): + for file in files: + source = os.path.join(root, file) + destination = source.replace(target_dir, os.path.dirname(os.path.realpath(__file__))) + if "OCK_Files" not in destination and "updater" not in destination: + shutil.move(source, destination) + shutil.rmtree(self.temporary_dir) + + def run_update(self): + self.utils.head("Check for update") + print("") + current_version = self.get_current_version() + latest_version = self.get_latest_version() + print(f"Current script version: {current_version}") + print(f"Latest script version: {latest_version}") + print("") + if latest_version > current_version: + print(f"Updating from version {current_version} to {latest_version}\n") + self.download_update() + self.update_files() + print("\n\n{}\n".format(self.utils.message("The program needs to restart to complete the update process.", "reminder"))) + self.utils.request_input("Press Enter to restart...") + return True + else: + print("You are already using the latest version") + return False +