mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
Add ability to ignore system builds
This commit is contained in:
@@ -34,7 +34,7 @@ class EngineManager:
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def get_engines(cls, filter_name=None, include_corrupt=False):
|
||||
def get_engines(cls, filter_name=None, include_corrupt=False, ignore_system=False):
|
||||
|
||||
if not cls.engines_path:
|
||||
raise FileNotFoundError("Engine path is not set")
|
||||
@@ -96,46 +96,47 @@ class EngineManager:
|
||||
'type': 'system'
|
||||
}
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
futures = {
|
||||
executor.submit(fetch_engine_details, eng, include_corrupt): eng.name()
|
||||
for eng in cls.supported_engines()
|
||||
if eng.default_renderer_path() and (not filter_name or filter_name == eng.name())
|
||||
}
|
||||
if not ignore_system:
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
futures = {
|
||||
executor.submit(fetch_engine_details, eng, include_corrupt): eng.name()
|
||||
for eng in cls.supported_engines()
|
||||
if eng.default_renderer_path() and (not filter_name or filter_name == eng.name())
|
||||
}
|
||||
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
result = future.result()
|
||||
if result:
|
||||
results.append(result)
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
result = future.result()
|
||||
if result:
|
||||
results.append(result)
|
||||
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def all_versions_for_engine(cls, engine_name, include_corrupt=False):
|
||||
versions = cls.get_engines(filter_name=engine_name, include_corrupt=include_corrupt)
|
||||
def all_versions_for_engine(cls, engine_name, include_corrupt=False, ignore_system=False):
|
||||
versions = cls.get_engines(filter_name=engine_name, include_corrupt=include_corrupt, ignore_system=ignore_system)
|
||||
sorted_versions = sorted(versions, key=lambda x: x['version'], reverse=True)
|
||||
return sorted_versions
|
||||
|
||||
@classmethod
|
||||
def newest_engine_version(cls, engine, system_os=None, cpu=None):
|
||||
def newest_engine_version(cls, engine, system_os=None, cpu=None, ignore_system=None):
|
||||
system_os = system_os or current_system_os()
|
||||
cpu = cpu or current_system_cpu()
|
||||
|
||||
try:
|
||||
filtered = [x for x in cls.all_versions_for_engine(engine) if x['system_os'] == system_os and
|
||||
x['cpu'] == cpu]
|
||||
filtered = [x for x in cls.all_versions_for_engine(engine, ignore_system=ignore_system)
|
||||
if x['system_os'] == system_os and x['cpu'] == cpu]
|
||||
return filtered[0]
|
||||
except IndexError:
|
||||
logger.error(f"Cannot find newest engine version for {engine}-{system_os}-{cpu}")
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def is_version_downloaded(cls, engine, version, system_os=None, cpu=None):
|
||||
def is_version_downloaded(cls, engine, version, system_os=None, cpu=None, ignore_system=False):
|
||||
system_os = system_os or current_system_os()
|
||||
cpu = cpu or current_system_cpu()
|
||||
|
||||
filtered = [x for x in cls.get_engines(filter_name=engine) if x['system_os'] == system_os and
|
||||
x['cpu'] == cpu and x['version'] == version]
|
||||
filtered = [x for x in cls.get_engines(filter_name=engine, ignore_system=ignore_system) if
|
||||
x['system_os'] == system_os and x['cpu'] == cpu and x['version'] == version]
|
||||
return filtered[0] if filtered else False
|
||||
|
||||
@classmethod
|
||||
@@ -168,7 +169,7 @@ class EngineManager:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def download_engine(cls, engine, version, system_os=None, cpu=None, background=False):
|
||||
def download_engine(cls, engine, version, system_os=None, cpu=None, background=False, ignore_system=False):
|
||||
|
||||
engine_to_download = cls.engine_with_name(engine)
|
||||
existing_task = cls.get_existing_download_task(engine, version, system_os, cpu)
|
||||
@@ -191,7 +192,7 @@ class EngineManager:
|
||||
return thread
|
||||
|
||||
thread.join()
|
||||
found_engine = cls.is_version_downloaded(engine, version, system_os, cpu) # Check that engine downloaded
|
||||
found_engine = cls.is_version_downloaded(engine, version, system_os, cpu, ignore_system) # Check that engine downloaded
|
||||
if not found_engine:
|
||||
logger.error(f"Error downloading {engine}")
|
||||
return found_engine
|
||||
@@ -217,34 +218,7 @@ class EngineManager:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def update_all_engines(cls):
|
||||
def engine_update_task(engine_class):
|
||||
logger.debug(f"Checking for updates to {engine_class.name()}")
|
||||
latest_version = engine_class.downloader().find_most_recent_version()
|
||||
|
||||
if not latest_version:
|
||||
logger.warning(f"Could not find most recent version of {engine.name()} to download")
|
||||
return
|
||||
|
||||
version_num = latest_version.get('version')
|
||||
if cls.is_version_downloaded(engine_class.name(), version_num):
|
||||
logger.debug(f"Latest version of {engine_class.name()} ({version_num}) already downloaded")
|
||||
return
|
||||
|
||||
# download the engine
|
||||
logger.info(f"Downloading latest version of {engine_class.name()} ({version_num})...")
|
||||
cls.download_engine(engine=engine_class.name(), version=version_num, background=True)
|
||||
|
||||
logger.info(f"Checking for updates for render engines...")
|
||||
threads = []
|
||||
for engine in cls.supported_engines():
|
||||
if engine.downloader():
|
||||
thread = threading.Thread(target=engine_update_task, args=(engine,))
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
|
||||
@classmethod
|
||||
def update_engine(cls, engine_class):
|
||||
def is_engine_update_available(cls, engine_class, ignore_system_installs=False):
|
||||
logger.debug(f"Checking for updates to {engine_class.name()}")
|
||||
latest_version = engine_class.downloader().find_most_recent_version()
|
||||
|
||||
@@ -253,15 +227,11 @@ class EngineManager:
|
||||
return
|
||||
|
||||
version_num = latest_version.get('version')
|
||||
if cls.is_version_downloaded(engine_class.name(), version_num):
|
||||
if cls.is_version_downloaded(engine_class.name(), version_num, ignore_system=ignore_system_installs):
|
||||
logger.debug(f"Latest version of {engine_class.name()} ({version_num}) already downloaded")
|
||||
return
|
||||
|
||||
# download the engine
|
||||
logger.info(f"Downloading latest version of {engine_class.name()} ({version_num})...")
|
||||
download_job = cls.download_engine(engine=engine_class.name(), version=version_num, background=True)
|
||||
|
||||
return {"latest": latest_version, "thread": download_job, "name": engine_class.name()}
|
||||
return latest_version
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -330,7 +300,8 @@ class EngineDownloadWorker(threading.Thread):
|
||||
self.cpu = cpu
|
||||
|
||||
def run(self):
|
||||
existing_download = EngineManager.is_version_downloaded(self.engine, self.version, self.system_os, self.cpu)
|
||||
existing_download = EngineManager.is_version_downloaded(self.engine, self.version, self.system_os, self.cpu,
|
||||
ignore_system=True)
|
||||
if existing_download:
|
||||
logger.info(f"Requested download of {self.engine} {self.version}, but local copy already exists")
|
||||
return existing_download
|
||||
|
||||
20
src/init.py
20
src/init.py
@@ -5,6 +5,9 @@ import socket
|
||||
import sys
|
||||
import threading
|
||||
from collections import deque
|
||||
from datetime import datetime
|
||||
|
||||
from PyQt6.QtCore import QSettings
|
||||
|
||||
from src.api.api_server import start_server
|
||||
from src.api.preview_manager import PreviewManager
|
||||
@@ -16,7 +19,7 @@ from src.utilities.config import Config
|
||||
from src.utilities.misc_helper import (system_safe_path, current_system_cpu, current_system_os,
|
||||
current_system_os_version, check_for_updates)
|
||||
from src.utilities.zeroconf_server import ZeroconfServer
|
||||
from version import APP_NAME, APP_VERSION, APP_REPO_NAME, APP_REPO_OWNER
|
||||
from version import APP_NAME, APP_VERSION, APP_REPO_NAME, APP_REPO_OWNER, APP_AUTHOR
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
@@ -66,6 +69,8 @@ def run(server_only=False) -> int:
|
||||
APP_VERSION))
|
||||
update_thread.start()
|
||||
|
||||
settings = QSettings(APP_AUTHOR, APP_NAME)
|
||||
|
||||
# main start
|
||||
logger.info(f"Starting {APP_NAME} Render Server")
|
||||
return_code = 0
|
||||
@@ -92,9 +97,16 @@ def run(server_only=False) -> int:
|
||||
ServerProxyManager.subscribe_to_listener()
|
||||
DistributedJobManager.subscribe_to_listener()
|
||||
|
||||
# check for updates for render engines if configured or on first launch
|
||||
if Config.update_engines_on_launch or not EngineManager.get_engines():
|
||||
EngineManager.update_all_engines()
|
||||
# check for updates for render engines if configured
|
||||
ignore_system = settings.value("engines_ignore_system_installs", False)
|
||||
if settings.value('check_for_engine_updates_on_launch', False):
|
||||
for engine in EngineManager.downloadable_engines():
|
||||
if settings.value(f'engine_download-{engine.name()}', False):
|
||||
update_result = EngineManager.is_engine_update_available(engine, ignore_system_installs=ignore_system)
|
||||
EngineManager.download_engine(engine=engine.name(), version=update_result['version'],
|
||||
background=True,
|
||||
ignore_system=ignore_system)
|
||||
settings.setValue("engines_last_update_time", datetime.now().isoformat())
|
||||
|
||||
# get hostname
|
||||
local_hostname = socket.gethostname()
|
||||
|
||||
@@ -184,6 +184,12 @@ class SettingsWindow(QMainWindow):
|
||||
installed_layout = QVBoxLayout()
|
||||
self.installed_engines_table = EngineTableWidget()
|
||||
installed_layout.addWidget(self.installed_engines_table)
|
||||
|
||||
engine_ignore_system_installs_checkbox = QCheckBox("Ignore system installs")
|
||||
engine_ignore_system_installs_checkbox.setChecked(settings.value("engines_ignore_system_installs", False))
|
||||
engine_ignore_system_installs_checkbox.stateChanged.connect(self.change_ignore_system_installs)
|
||||
installed_layout.addWidget(engine_ignore_system_installs_checkbox)
|
||||
|
||||
installed_buttons_layout = QHBoxLayout()
|
||||
launch_engine_button = QPushButton("Launch")
|
||||
launch_engine_button.clicked.connect(self.launch_selected_engine)
|
||||
@@ -226,7 +232,7 @@ class SettingsWindow(QMainWindow):
|
||||
self.update_last_checked_label()
|
||||
self.engines_last_update_label.setEnabled(at_least_one_downloadable)
|
||||
engine_updates_layout.addWidget(self.engines_last_update_label)
|
||||
self.check_for_new_engines_button = QPushButton("Check for New Versions")
|
||||
self.check_for_new_engines_button = QPushButton("Check for New Versions...")
|
||||
self.check_for_new_engines_button.setEnabled(at_least_one_downloadable)
|
||||
self.check_for_new_engines_button.clicked.connect(self.check_for_new_engines)
|
||||
engine_updates_layout.addWidget(self.check_for_new_engines_button)
|
||||
@@ -239,6 +245,11 @@ class SettingsWindow(QMainWindow):
|
||||
page.setLayout(layout)
|
||||
return page
|
||||
|
||||
def change_ignore_system_installs(self, value):
|
||||
settings.setValue("engines_ignore_system_installs", bool(value))
|
||||
self.installed_engines_table.update_table()
|
||||
|
||||
|
||||
def update_last_checked_label(self):
|
||||
"""Retrieve the last check timestamp and return a human-friendly string."""
|
||||
last_checked_str = settings.value("engines_last_update_time", None)
|
||||
@@ -275,22 +286,27 @@ class SettingsWindow(QMainWindow):
|
||||
os.path.join(os.path.join(os.path.expanduser(Config.upload_folder),
|
||||
'engines')))
|
||||
|
||||
results = []
|
||||
ignore_system = settings.value("engines_ignore_system_installs", False)
|
||||
messagebox_shown = False
|
||||
for engine in EngineManager.downloadable_engines():
|
||||
if settings.value(f'engine_download-{engine.name()}', False):
|
||||
update_result = EngineManager.update_engine(engine)
|
||||
if update_result:
|
||||
results.append(update_result)
|
||||
result = EngineManager.is_engine_update_available(engine, ignore_system_installs=ignore_system)
|
||||
if result:
|
||||
result['name'] = engine.name()
|
||||
msg_box = QMessageBox()
|
||||
msg_box.setWindowTitle(f"{result['name']} ({result['version']}) Available")
|
||||
msg_box.setText(f"A new version of {result['name']} is available ({result['version']}).\n\n"
|
||||
f"Would you like to download it now?")
|
||||
msg_box.setIcon(QMessageBox.Icon.Information)
|
||||
msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
|
||||
msg_result = msg_box.exec()
|
||||
messagebox_shown = True
|
||||
if msg_result == QMessageBox.StandardButton.Yes:
|
||||
EngineManager.download_engine(engine=engine.name(), version=result['version'], background=True,
|
||||
ignore_system=ignore_system)
|
||||
self.update_engine_download_status()
|
||||
|
||||
if results:
|
||||
for result in results:
|
||||
msg_box = QMessageBox()
|
||||
msg_box.setWindowTitle(f"{result['name']} {result['version']} Available")
|
||||
msg_box.setText(f"A new version of {result['name']} is available ({result['version']}). It will begin downloading now.")
|
||||
msg_box.setIcon(QMessageBox.Icon.Information)
|
||||
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
||||
msg_box.exec()
|
||||
else:
|
||||
if not messagebox_shown:
|
||||
msg_box = QMessageBox()
|
||||
msg_box.setWindowTitle("No Updates Available")
|
||||
msg_box.setText("All your render engines are up-to-date.")
|
||||
@@ -299,7 +315,16 @@ class SettingsWindow(QMainWindow):
|
||||
msg_box.exec()
|
||||
|
||||
settings.setValue("engines_last_update_time", datetime.now().isoformat())
|
||||
self.update_last_checked_label()
|
||||
self.update_engine_download_status()
|
||||
|
||||
def update_engine_download_status(self):
|
||||
running_tasks = [x for x in EngineManager.download_tasks if x.is_alive()]
|
||||
if not running_tasks:
|
||||
self.update_last_checked_label()
|
||||
return
|
||||
|
||||
self.engines_last_update_label.setText(f"Downloading {running_tasks[0].engine} ({running_tasks[0].version})...")
|
||||
|
||||
|
||||
class EngineTableWidget(QWidget):
|
||||
def __init__(self):
|
||||
@@ -315,20 +340,26 @@ class EngineTableWidget(QWidget):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.addWidget(self.table)
|
||||
|
||||
self.raw_server_data = None
|
||||
|
||||
def showEvent(self, event):
|
||||
"""Runs when the widget is about to be shown."""
|
||||
self.update_table()
|
||||
super().showEvent(event) # Ensure normal event processing
|
||||
|
||||
def update_table(self):
|
||||
raw_server_data = RenderServerProxy(socket.gethostname()).get_renderer_info()
|
||||
if not raw_server_data:
|
||||
def update_table(self, use_cached=True):
|
||||
if not self.raw_server_data or not use_cached:
|
||||
self.raw_server_data = RenderServerProxy(socket.gethostname()).get_renderer_info()
|
||||
if not self.raw_server_data:
|
||||
return
|
||||
|
||||
table_data = [] # convert the data into a flat list
|
||||
for _, engine_data in raw_server_data.items():
|
||||
for _, engine_data in self.raw_server_data.items():
|
||||
table_data.extend(engine_data['versions'])
|
||||
|
||||
if settings.value("engines_ignore_system_installs", False):
|
||||
table_data = [x for x in table_data if x['type'] != 'system']
|
||||
|
||||
self.table.clear()
|
||||
self.table.setRowCount(len(table_data))
|
||||
self.table.setColumnCount(4)
|
||||
@@ -364,6 +395,7 @@ class EngineTableWidget(QWidget):
|
||||
return data
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication([])
|
||||
window = SettingsWindow()
|
||||
|
||||
Reference in New Issue
Block a user