diff --git a/client/ayon_nuke/api/lib.py b/client/ayon_nuke/api/lib.py index 49db43a56f..4e9d946e70 100644 --- a/client/ayon_nuke/api/lib.py +++ b/client/ayon_nuke/api/lib.py @@ -14,7 +14,6 @@ import ayon_api from ayon_core.host import HostDirmap -from ayon_core.tools.utils import host_tools from ayon_core.pipeline.workfile.workfile_template_builder import ( TemplateProfileNotFound ) @@ -1561,7 +1560,7 @@ def set_viewers_colorspace(self, imageio_nuke): if erased_viewers: log.warning( - "Attention! Viewer nodes {} were erased." + "Attention! Viewer nodes {} were erased. " "It had wrong color profile".format(erased_viewers)) # TODO: move into ./colorspace.py @@ -2469,6 +2468,9 @@ def launch_workfiles_app(): def _launch_workfile_app(): # Safeguard to not show window when application is still starting up # or is already closing down. + if not nuke.GUI: + raise RuntimeError("Invalid in non-GUI mode.") + closing_down = QtWidgets.QApplication.closingDown() starting_up = QtWidgets.QApplication.startingUp() @@ -2486,6 +2488,7 @@ def _launch_workfile_app(): # - this happened on Centos 7 and it is because the focus of nuke # changes to the main window after showing because of initialization # which moves workfiles tool under it + from ayon_core.tools.utils import host_tools host_tools.show_workfiles(parent=None, on_top=True) diff --git a/client/ayon_nuke/api/pipeline.py b/client/ayon_nuke/api/pipeline.py index ce815f1bdf..dec42e71de 100644 --- a/client/ayon_nuke/api/pipeline.py +++ b/client/ayon_nuke/api/pipeline.py @@ -27,9 +27,7 @@ registered_host, ) from ayon_core.pipeline.workfile import BuildWorkfile -from ayon_core.tools.utils import host_tools from ayon_nuke import NUKE_ROOT_DIR -from ayon_core.tools.workfile_template_build import open_template_ui # Function 'get_current_project_settings' was moved in ayon-core 1.5.1 try: @@ -142,16 +140,18 @@ def install(self): # Register AYON event for workfiles loading. register_event_callback("workio.open_file", check_inventory_versions) register_event_callback("taskChanged", change_context_label) - project_settings = get_current_project_settings() - if nuke.GUI: - _install_menu(project_settings) - # add script menu - add_scripts_menu() - add_scripts_gizmo() + def setup_ui_callbacks_and_menu(self): + """Setup AYON menus.""" + if not nuke.GUI: + raise RuntimeError("Cannot set up in non-GUI mode.") + project_settings = get_current_project_settings() add_nuke_callbacks(project_settings) + _install_menu(project_settings) + add_scripts_menu() + add_scripts_gizmo() launch_workfiles_app() def get_context_data(self): @@ -224,14 +224,6 @@ def reload_config(): reload(module) -def _show_workfiles(): - # Make sure parent is not set - # - this makes Workfiles tool as separated window which - # avoid issues with reopening - # - it is possible to explicitly change on top flag of the tool - host_tools.show_workfiles(parent=None, on_top=False) - - def get_context_label(): return "{0}, {1}".format( get_current_folder_path(), @@ -241,6 +233,9 @@ def get_context_label(): def _install_menu(project_settings: dict): """Install AYON menu into Nuke's main menu bar.""" + # local imports, modules not available in non-GUI mode + from ayon_core.tools.utils import host_tools + from ayon_core.tools.workfile_template_build import open_template_ui # uninstall original AYON menu main_window = get_main_window() @@ -274,6 +269,13 @@ def _install_menu(project_settings: dict): shortcut_str ) + def _show_workfiles(): + # Make sure parent is not set + # - this makes Workfiles tool as separated window which + # avoid issues with reopening + # - it is possible to explicitly change on top flag of the tool + host_tools.show_workfiles(parent=None, on_top=False) + menu.addCommand( "Work Files...", _show_workfiles diff --git a/client/ayon_nuke/api/push_to_project.py b/client/ayon_nuke/api/push_to_project.py index b907c8f24d..63d0e5c102 100644 --- a/client/ayon_nuke/api/push_to_project.py +++ b/client/ayon_nuke/api/push_to_project.py @@ -7,7 +7,6 @@ from ayon_core.pipeline import Anatomy, registered_host from ayon_core.pipeline.template_data import get_template_data from ayon_core.pipeline.workfile import get_workdir_with_workdir_data -from ayon_core.tools import context_dialog from .utils import bake_gizmos_recursively from .lib import MENU_LABEL @@ -46,6 +45,10 @@ def bake_container(container): def main(): + if not nuke.GUI: + raise RuntimeError("Invalid in non-GUI mode.") + + from ayon_core.tools import context_dialog context = context_dialog.ask_for_context() if context is None: diff --git a/client/ayon_nuke/api/utils.py b/client/ayon_nuke/api/utils.py index 2d0f766bb8..5ddebd1971 100644 --- a/client/ayon_nuke/api/utils.py +++ b/client/ayon_nuke/api/utils.py @@ -8,7 +8,6 @@ from ayon_core import resources from ayon_core.pipeline import registered_host -from ayon_core.tools.utils import show_message_dialog from ayon_core.pipeline.create import CreateContext @@ -109,7 +108,7 @@ def submit_render_on_farm(node): _submit_render_on_farm(node) -def _submit_render_on_farm(node): +def _submit_render_on_farm(node) -> bool: """Render on farm submission This function prepares the context for farm submission, validates it, @@ -118,6 +117,9 @@ def _submit_render_on_farm(node): Args: node (Node): The node for which the farm submission is being made. + + Returns: + bool: Did the submission succeed? """ host = registered_host() @@ -161,12 +163,17 @@ def _submit_render_on_farm(node): error_message += "\n" error_message += err.formatted_traceback - if not success: - show_message_dialog( - "Publish Errors", error_message, level="critical" - ) - return - - show_message_dialog( - "Submission Successful", "Submission to the farm was successful." - ) + if nuke.GUI: + from ayon_core.tools.utils import show_message_dialog + if success: + show_message_dialog( + "Submission Successful", + "Submission to the farm was successful." + ) + else: + show_message_dialog( + "Publish Errors", + error_message, level="critical" + ) + + return success diff --git a/client/ayon_nuke/api/workfile_template_builder.py b/client/ayon_nuke/api/workfile_template_builder.py index 766c9d64d4..3307881f5f 100644 --- a/client/ayon_nuke/api/workfile_template_builder.py +++ b/client/ayon_nuke/api/workfile_template_builder.py @@ -7,9 +7,7 @@ AbstractTemplateBuilder, PlaceholderPlugin, ) -from ayon_core.tools.workfile_template_build import ( - WorkfileBuildPlaceholderDialog, -) + from .lib import ( imprint, reset_selection, @@ -147,6 +145,13 @@ def update_workfile_template(*args): def create_placeholder(*args): + if not nuke.GUI: + raise RuntimeError("Invalid in non-GUI mode.") + + from ayon_core.tools.workfile_template_build import ( + WorkfileBuildPlaceholderDialog, + ) + host = registered_host() builder = NukeTemplateBuilder(host) window = WorkfileBuildPlaceholderDialog(host, builder, @@ -155,6 +160,13 @@ def create_placeholder(*args): def update_placeholder(*args): + if not nuke.GUI: + raise RuntimeError("Invalid in non-GUI mode.") + + from ayon_core.tools.workfile_template_build import ( + WorkfileBuildPlaceholderDialog, + ) + host = registered_host() builder = NukeTemplateBuilder(host) placeholder_items_by_id = { diff --git a/client/ayon_nuke/startup/init.py b/client/ayon_nuke/startup/init.py new file mode 100644 index 0000000000..86396c30c0 --- /dev/null +++ b/client/ayon_nuke/startup/init.py @@ -0,0 +1,19 @@ +from ayon_core.pipeline import install_host +from ayon_nuke.api import NukeHost + +# Attempt to register host. +try: + host = NukeHost() + install_host(host) + +# Current environment might not be 100% fully AYON compatible. +# e.g. on farm, using Deadline or RoyalRender native Nuke plugin. +# If an incomplete AYON environment is provided, the host +# will not be able to install. +# We still allow Nuke to start as-is, might be enough for rendering. +# Otherwise it'll raise on AYON dependency with more meaningful error. +except Exception as error: + print( + f"Cannot initialize AYON Nuke host: {error}. " + "This might result in unexpected results." + ) diff --git a/client/ayon_nuke/startup/menu.py b/client/ayon_nuke/startup/menu.py index c3dd8cda8f..53e89d68b5 100644 --- a/client/ayon_nuke/startup/menu.py +++ b/client/ayon_nuke/startup/menu.py @@ -1,5 +1,11 @@ -from ayon_core.pipeline import install_host -from ayon_nuke.api import NukeHost +from ayon_core.pipeline import registered_host -host = NukeHost() -install_host(host) + +# This code gets only called from GUI mode. +# Unlike the non-GUI mode (e.g. farm), +# we do expect a valid host at this time. +nuke_host = registered_host() +if nuke_host is None: + raise RuntimeError("Cannot find expected registered Nuke host.") + +nuke_host.setup_ui_callbacks_and_menu()