mirror of
https://github.com/blw1138/Zordon.git
synced 2026-02-05 05:36:09 +00:00
Performance improvements / API refactoring
This commit is contained in:
@@ -380,6 +380,16 @@ def delete_job(job_id):
|
|||||||
# Engine Info and Management:
|
# Engine Info and Management:
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
|
|
||||||
|
@server.get('/api/engine_for_filename')
|
||||||
|
def get_engine_for_filename():
|
||||||
|
filename = request.args.get("filename")
|
||||||
|
if not filename:
|
||||||
|
return "Error: filename is required", 400
|
||||||
|
found_engine = EngineManager.engine_class_for_project_path(filename)
|
||||||
|
if not found_engine:
|
||||||
|
return f"Error: cannot find a suitable engine for '{filename}'", 400
|
||||||
|
return found_engine.name()
|
||||||
|
|
||||||
@server.get('/api/installed_engines')
|
@server.get('/api/installed_engines')
|
||||||
def get_installed_engines():
|
def get_installed_engines():
|
||||||
result = {}
|
result = {}
|
||||||
@@ -464,7 +474,8 @@ def get_engine_info(engine_name):
|
|||||||
future_results = {
|
future_results = {
|
||||||
'supported_extensions': executor.submit(en.supported_extensions),
|
'supported_extensions': executor.submit(en.supported_extensions),
|
||||||
'supported_export_formats': executor.submit(en.get_output_formats),
|
'supported_export_formats': executor.submit(en.get_output_formats),
|
||||||
'system_info': executor.submit(en.system_info)
|
'system_info': executor.submit(en.system_info),
|
||||||
|
'options': executor.submit(en.ui_options)
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, future in future_results.items():
|
for key, future in future_results.items():
|
||||||
@@ -620,6 +631,15 @@ def handle_detached_instance(_):
|
|||||||
return "Unavailable", 503
|
return "Unavailable", 503
|
||||||
|
|
||||||
|
|
||||||
|
@server.errorhandler(404)
|
||||||
|
def handle_404(error):
|
||||||
|
url = request.url
|
||||||
|
err_msg = f"404 Not Found: {url}"
|
||||||
|
if 'favicon' not in url:
|
||||||
|
logger.warning(err_msg)
|
||||||
|
return err_msg, 404
|
||||||
|
|
||||||
|
|
||||||
@server.errorhandler(Exception)
|
@server.errorhandler(Exception)
|
||||||
def handle_general_error(general_error):
|
def handle_general_error(general_error):
|
||||||
err_msg = f"Server error: {general_error}"
|
err_msg = f"Server error: {general_error}"
|
||||||
|
|||||||
@@ -247,6 +247,10 @@ class RenderServerProxy:
|
|||||||
# Engines:
|
# Engines:
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
|
|
||||||
|
def get_engine_for_filename(self, filename, timeout=5):
|
||||||
|
response = self.request(f'engine_for_filename?filename={os.path.basename(filename)}', timeout)
|
||||||
|
return response.text
|
||||||
|
|
||||||
def get_installed_engines(self, timeout=5):
|
def get_installed_engines(self, timeout=5):
|
||||||
return self.request_data(f'installed_engines', timeout)
|
return self.request_data(f'installed_engines', timeout)
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,12 @@ class Blender(BaseRenderEngine):
|
|||||||
from src.engines.blender.blender_worker import BlenderRenderWorker
|
from src.engines.blender.blender_worker import BlenderRenderWorker
|
||||||
return BlenderRenderWorker
|
return BlenderRenderWorker
|
||||||
|
|
||||||
@staticmethod
|
def ui_options(self):
|
||||||
def ui_options(system_info):
|
options = [
|
||||||
from src.engines.blender.blender_ui import BlenderUI
|
{'name': 'engine', 'options': self.supported_render_engines()},
|
||||||
return BlenderUI.get_options(system_info)
|
{'name': 'render_device', 'options': ['Any', 'GPU', 'CPU']},
|
||||||
|
]
|
||||||
|
return options
|
||||||
|
|
||||||
def supported_extensions(self):
|
def supported_extensions(self):
|
||||||
return ['blend']
|
return ['blend']
|
||||||
@@ -180,7 +182,7 @@ class Blender(BaseRenderEngine):
|
|||||||
logger.error("GPU data not found in the output.")
|
logger.error("GPU data not found in the output.")
|
||||||
|
|
||||||
def supported_render_engines(self):
|
def supported_render_engines(self):
|
||||||
engine_output = subprocess.run([self.engine_path(), '-E', 'help'], timeout=SUBPROCESS_TIMEOUT,
|
engine_output = subprocess.run([self.engine_path(), '-b', '-E', 'help'], timeout=SUBPROCESS_TIMEOUT,
|
||||||
capture_output=True, creationflags=_creationflags).stdout.decode('utf-8').strip()
|
capture_output=True, creationflags=_creationflags).stdout.decode('utf-8').strip()
|
||||||
render_engines = [x.strip() for x in engine_output.split('Blender Engine Listing:')[-1].strip().splitlines()]
|
render_engines = [x.strip() for x in engine_output.split('Blender Engine Listing:')[-1].strip().splitlines()]
|
||||||
return render_engines
|
return render_engines
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
class BlenderUI:
|
|
||||||
@staticmethod
|
|
||||||
def get_options(system_info):
|
|
||||||
options = [
|
|
||||||
{'name': 'engine', 'options': system_info.get('engines', [])},
|
|
||||||
{'name': 'render_device', 'options': ['Any', 'GPU', 'CPU']},
|
|
||||||
]
|
|
||||||
return options
|
|
||||||
@@ -133,8 +133,7 @@ class BaseRenderEngine(object):
|
|||||||
def downloader(): # override when subclassing if using a downloader class
|
def downloader(): # override when subclassing if using a downloader class
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
def ui_options(self): # override to return options for ui
|
||||||
def ui_options(system_info): # override to return options for ui
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ class FFMPEG(BaseRenderEngine):
|
|||||||
from src.engines.ffmpeg.ffmpeg_worker import FFMPEGRenderWorker
|
from src.engines.ffmpeg.ffmpeg_worker import FFMPEGRenderWorker
|
||||||
return FFMPEGRenderWorker
|
return FFMPEGRenderWorker
|
||||||
|
|
||||||
@staticmethod
|
def ui_options(self):
|
||||||
def ui_options(system_info):
|
return []
|
||||||
from src.engines.ffmpeg.ffmpeg_ui import FFMPEGUI
|
|
||||||
return FFMPEGUI.get_options(system_info)
|
|
||||||
|
|
||||||
def supported_extensions(self):
|
def supported_extensions(self):
|
||||||
help_text = (subprocess.check_output([self.engine_path(), '-h', 'full'], stderr=subprocess.STDOUT,
|
help_text = (subprocess.check_output([self.engine_path(), '-h', 'full'], stderr=subprocess.STDOUT,
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
class FFMPEGUI:
|
|
||||||
@staticmethod
|
|
||||||
def get_options(system_info):
|
|
||||||
options = []
|
|
||||||
return options
|
|
||||||
@@ -68,7 +68,6 @@ class NewRenderJobForm(QWidget):
|
|||||||
# Setup
|
# Setup
|
||||||
self.setWindowTitle("New Job")
|
self.setWindowTitle("New Job")
|
||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
self.update_engine_info()
|
|
||||||
self.setup_project()
|
self.setup_project()
|
||||||
|
|
||||||
# get renderer info in bg thread
|
# get renderer info in bg thread
|
||||||
@@ -325,11 +324,11 @@ class NewRenderJobForm(QWidget):
|
|||||||
|
|
||||||
def update_engine_info(self):
|
def update_engine_info(self):
|
||||||
# get the engine info and add them all to the ui
|
# get the engine info and add them all to the ui
|
||||||
engine = EngineManager.engine_class_for_project_path(self.project_path)
|
|
||||||
installed_engines = self.server_proxy.get_installed_engines()
|
installed_engines = self.server_proxy.get_installed_engines()
|
||||||
self.engine_type.addItems(installed_engines.keys())
|
self.engine_type.addItems(installed_engines.keys())
|
||||||
# select the best engine for the file type
|
# select the best engine for the file type
|
||||||
self.engine_type.setCurrentText(engine.name().lower())
|
engine_name = self.server_proxy.get_engine_for_filename(self.project_path)
|
||||||
|
self.engine_type.setCurrentText(engine_name)
|
||||||
# refresh ui
|
# refresh ui
|
||||||
self.engine_changed()
|
self.engine_changed()
|
||||||
|
|
||||||
@@ -341,6 +340,7 @@ class NewRenderJobForm(QWidget):
|
|||||||
self.file_format_combo.clear()
|
self.file_format_combo.clear()
|
||||||
if current_engine:
|
if current_engine:
|
||||||
engine_info = self.server_proxy.get_engine_info(current_engine, 'full', timeout=10)
|
engine_info = self.server_proxy.get_engine_info(current_engine, 'full', timeout=10)
|
||||||
|
self.current_engine_options = engine_info.get('options', [])
|
||||||
if not engine_info:
|
if not engine_info:
|
||||||
raise FileNotFoundError(f"Cannot get information about engine '{current_engine}'")
|
raise FileNotFoundError(f"Cannot get information about engine '{current_engine}'")
|
||||||
engine_vers = [v['version'] for v in engine_info['versions']]
|
engine_vers = [v['version'] for v in engine_info['versions']]
|
||||||
@@ -442,7 +442,6 @@ class NewRenderJobForm(QWidget):
|
|||||||
# Dynamic Engine Options
|
# Dynamic Engine Options
|
||||||
clear_layout(self.engine_options_layout) # clear old options
|
clear_layout(self.engine_options_layout) # clear old options
|
||||||
# dynamically populate option list
|
# dynamically populate option list
|
||||||
self.current_engine_options = {} #todo: fix this
|
|
||||||
for option in self.current_engine_options:
|
for option in self.current_engine_options:
|
||||||
h_layout = QHBoxLayout()
|
h_layout = QHBoxLayout()
|
||||||
label = QLabel(option['name'].replace('_', ' ').capitalize() + ':')
|
label = QLabel(option['name'].replace('_', ' ').capitalize() + ':')
|
||||||
@@ -592,7 +591,7 @@ class SubmitWorker(QThread):
|
|||||||
children_jobs.append(child_job_data)
|
children_jobs.append(child_job_data)
|
||||||
job_json['child_jobs'] = children_jobs
|
job_json['child_jobs'] = children_jobs
|
||||||
|
|
||||||
# presubmission tasks
|
# presubmission tasks - use local installs
|
||||||
engine_class = EngineManager.engine_class_with_name(self.window.engine_type.currentText().lower())
|
engine_class = EngineManager.engine_class_with_name(self.window.engine_type.currentText().lower())
|
||||||
latest_engine = EngineManager.get_latest_engine_instance(engine_class)
|
latest_engine = EngineManager.get_latest_engine_instance(engine_class)
|
||||||
input_path = latest_engine.perform_presubmission_tasks(input_path)
|
input_path = latest_engine.perform_presubmission_tasks(input_path)
|
||||||
@@ -623,6 +622,7 @@ class GetProjectInfoWorker(QThread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
self.window.update_engine_info()
|
self.window.update_engine_info()
|
||||||
|
# this should be the only time we use a local engine instead of using the proxy besides submitting
|
||||||
engine_class = EngineManager.engine_class_for_project_path(self.project_path)
|
engine_class = EngineManager.engine_class_for_project_path(self.project_path)
|
||||||
engine = EngineManager.get_latest_engine_instance(engine_class)
|
engine = EngineManager.get_latest_engine_instance(engine_class)
|
||||||
self.window.project_info = engine.get_project_info(self.project_path)
|
self.window.project_info = engine.get_project_info(self.project_path)
|
||||||
|
|||||||
Reference in New Issue
Block a user