From 820729de660ce7a0ea7ca8ba1c15cdf66724d012 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 17 Dec 2024 00:55:44 +0100 Subject: [PATCH 1/4] Initial work to use `HarmonyHost` implementation and restructure AYON menu to match other integrations with new publisher - Menu entries will now also open the new publisher, however new publisher context data methods and creators are not implemented yet. --- client/ayon_harmony/api/TB_sceneOpened.js | 37 +++----- client/ayon_harmony/api/__init__.py | 4 +- client/ayon_harmony/api/lib.py | 9 +- client/ayon_harmony/api/pipeline.py | 103 ++++++++++++++-------- client/ayon_harmony/api/plugin.py | 1 + 5 files changed, 84 insertions(+), 70 deletions(-) diff --git a/client/ayon_harmony/api/TB_sceneOpened.js b/client/ayon_harmony/api/TB_sceneOpened.js index 630df59..03d8944 100644 --- a/client/ayon_harmony/api/TB_sceneOpened.js +++ b/client/ayon_harmony/api/TB_sceneOpened.js @@ -380,7 +380,6 @@ function start() { if (app.ayonMenu == null) { menu = menuBar.addMenu(System.getenv('AYON_MENU_LABEL')); } - // menu = menuBar.addMenu('Avalon'); /** * Show creator @@ -396,22 +395,6 @@ function start() { var action = menu.addAction('Create...'); action.triggered.connect(self.onCreator); - - /** - * Show Workfiles - */ - self.onWorkfiles = function() { - app.ayonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['workfiles'] - }, false); - }; - if (app.ayonMenu == null) { - action = menu.addAction('Workfiles...'); - action.triggered.connect(self.onWorkfiles); - } - /** * Show Loader */ @@ -435,7 +418,7 @@ function start() { app.ayonClient.send({ 'module': 'ayon_harmony.api.lib', 'method': 'show', - 'args': ['publish'] + 'args': ['publisher'] }, false); }; // add Publisher item to menu @@ -461,19 +444,19 @@ function start() { } /** - * Show Subset Manager - */ - self.onSubsetManage = function() { + * Show Workfiles + */ + self.onWorkfiles = function() { app.ayonClient.send({ 'module': 'ayon_harmony.api.lib', 'method': 'show', - 'args': ['subsetmanager'] + 'args': ['workfiles'] }, false); }; - // add Subset Manager item to menu if (app.ayonMenu == null) { - action = menu.addAction('Subset Manager...'); - action.triggered.connect(self.onSubsetManage); + menu.addSeparator(); + action = menu.addAction('Workfiles...'); + action.triggered.connect(self.onWorkfiles); } /** @@ -489,8 +472,10 @@ function start() { false ); }; + // add Set Scene Settings if (app.ayonMenu == null) { + menu.addSeparator(); action = menu.addAction('Set Scene Settings...'); action.triggered.connect(self.onSetSceneSettings); } @@ -505,8 +490,8 @@ function start() { 'args': ['experimental_tools'] }, false); }; - // add Subset Manager item to menu if (app.ayonMenu == null) { + menu.addSeparator(); action = menu.addAction('Experimental Tools...'); action.triggered.connect(self.onExperimentalTools); } diff --git a/client/ayon_harmony/api/__init__.py b/client/ayon_harmony/api/__init__.py index a901eba..5ecf870 100644 --- a/client/ayon_harmony/api/__init__.py +++ b/client/ayon_harmony/api/__init__.py @@ -5,7 +5,7 @@ """ from .pipeline import ( ls, - install, + HarmonyHost, list_instances, remove_instance, select_instance, @@ -16,7 +16,6 @@ check_inventory, application_launch, export_template, - on_pyblish_instance_toggled, inject_ayon_js, ) @@ -60,7 +59,6 @@ "check_inventory", "application_launch", "export_template", - "on_pyblish_instance_toggled", "inject_ayon_js", # lib diff --git a/client/ayon_harmony/api/lib.py b/client/ayon_harmony/api/lib.py index 337de51..1bdefc7 100644 --- a/client/ayon_harmony/api/lib.py +++ b/client/ayon_harmony/api/lib.py @@ -186,9 +186,9 @@ def launch(application_path, *args): """ from ayon_core.pipeline import install_host - from ayon_harmony import api as harmony + from ayon_harmony.api import HarmonyHost - install_host(harmony) + install_host(HarmonyHost()) ProcessContext.port = random.randrange(49152, 65535) os.environ["AYON_HARMONY_PORT"] = str(ProcessContext.port) @@ -401,6 +401,11 @@ def show(tool_name): kwargs = {} if tool_name == "loader": kwargs["use_context"] = True + elif tool_name == "publisher": + kwargs["tab"] = "publish" + elif tool_name == "creator": + tool_name = "publisher" + kwargs["tab"] = "create" ProcessContext.execute_in_main_thread( lambda: host_tools.show_tool_by_name(tool_name, **kwargs) diff --git a/client/ayon_harmony/api/pipeline.py b/client/ayon_harmony/api/pipeline.py index 5b07ab9..28cdfe4 100644 --- a/client/ayon_harmony/api/pipeline.py +++ b/client/ayon_harmony/api/pipeline.py @@ -5,6 +5,12 @@ import pyblish.api from ayon_core.lib import register_event_callback +from ayon_core.host import ( + HostBase, + IWorkfileHost, + ILoadHost, + IPublishHost, +) from ayon_core.pipeline import ( register_loader_plugin_path, register_creator_plugin_path, @@ -18,6 +24,14 @@ from ayon_harmony import HARMONY_ADDON_ROOT import ayon_harmony.api as harmony +from .workio import ( + open_file, + save_file, + current_file, + has_unsaved_changes, + file_extensions, + work_root +) log = logging.getLogger("ayon_harmony") @@ -28,6 +42,53 @@ INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") +class HarmonyHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): + name = "harmony" + + def install(self): + """Install Pype as host config.""" + print("Installing AYON Harmony Host ...") + + pyblish.api.register_host("harmony") + pyblish.api.register_plugin_path(PUBLISH_PATH) + register_loader_plugin_path(LOAD_PATH) + register_creator_plugin_path(CREATE_PATH) + + register_event_callback("application.launched", application_launch) + + def uninstall(self): + pyblish.api.deregister_plugin_path(PUBLISH_PATH) + deregister_loader_plugin_path(LOAD_PATH) + deregister_creator_plugin_path(CREATE_PATH) + + def open_workfile(self, filepath): + return open_file(filepath) + + def save_workfile(self, filepath=None): + return save_file(filepath) + + def work_root(self, session): + return work_root(session) + + def get_current_workfile(self): + return current_file() + + def workfile_has_unsaved_changes(self): + return has_unsaved_changes() + + def get_workfile_extensions(self): + return file_extensions() + + def get_containers(self): + return ls() + + def get_context_data(self): + raise NotImplementedError() + + def update_context_data(self, data, changes): + raise NotImplementedError() + + def set_scene_settings(settings): """Set correct scene settings in Harmony. @@ -167,45 +228,6 @@ def export_template(backdrops, nodes, filepath): }) -def install(): - """Install Pype as host config.""" - print("Installing Pype config ...") - - pyblish.api.register_host("harmony") - pyblish.api.register_plugin_path(PUBLISH_PATH) - register_loader_plugin_path(LOAD_PATH) - register_creator_plugin_path(CREATE_PATH) - log.info(PUBLISH_PATH) - - # Register callbacks. - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled - ) - - register_event_callback("application.launched", application_launch) - - -def uninstall(): - pyblish.api.deregister_plugin_path(PUBLISH_PATH) - deregister_loader_plugin_path(LOAD_PATH) - deregister_creator_plugin_path(CREATE_PATH) - - -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle node enabling on instance toggles.""" - node = None - if instance.data.get("setMembers"): - node = instance.data["setMembers"][0] - - if node: - harmony.send( - { - "function": "AyonHarmony.toggleInstance", - "args": [node, new_value] - } - ) - - def inject_ayon_js(): """Inject AyonHarmonyAPI.js into Harmony.""" ayon_harmony_js = Path(__file__).parent.joinpath("js/AyonHarmonyAPI.js") @@ -248,6 +270,7 @@ def list_instances(remove_orphaned=True): Returns: (list) of dictionaries matching instances format """ + # TODO: Remove this, refactor to new style Creators instead objects = harmony.get_scene_data() or {} instances = [] for key, data in objects.items(): @@ -286,6 +309,7 @@ def remove_instance(instance): Args: instance (dict): instance representation from subsetmanager model """ + # TODO: Remove this, refactor to new style Creators instead node = instance.get("uuid") harmony.remove(node) harmony.delete_node(node) @@ -298,6 +322,7 @@ def select_instance(instance): Args: instance (dict): instance representation from subsetmanager model """ + # TODO: Remove this, refactor to new style Creators instead harmony.select_nodes([instance.get("uuid")]) diff --git a/client/ayon_harmony/api/plugin.py b/client/ayon_harmony/api/plugin.py index 9e1319f..9d39593 100644 --- a/client/ayon_harmony/api/plugin.py +++ b/client/ayon_harmony/api/plugin.py @@ -10,6 +10,7 @@ class Creator(LegacyCreator): If the selection is used, the selected nodes will be connected to the created node. """ + # TODO: Refactor to the new creator API defaults = ["Main"] node_type = "COMPOSITE" From 19f9e661db0969daeabaa2d6adc64e11a17892b4 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 19 Dec 2024 15:08:14 +0100 Subject: [PATCH 2/4] Remove IPublishHost to use Pyblish and Publisher combo --- client/ayon_harmony/api/pipeline.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ayon_harmony/api/pipeline.py b/client/ayon_harmony/api/pipeline.py index 3a67745..d9cf8bb 100644 --- a/client/ayon_harmony/api/pipeline.py +++ b/client/ayon_harmony/api/pipeline.py @@ -42,7 +42,7 @@ INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") -class HarmonyHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): +class HarmonyHost(HostBase, IWorkfileHost, ILoadHost): name = "harmony" def install(self): @@ -82,11 +82,11 @@ def get_workfile_extensions(self): def get_containers(self): return ls() - def get_context_data(self): - raise NotImplementedError() - - def update_context_data(self, data, changes): - raise NotImplementedError() + # def get_context_data(self): + # raise NotImplementedError() + # + # def update_context_data(self, data, changes): + # raise NotImplementedError() def set_scene_settings(settings): From b7210554a5ddad9cc6e7048c12b40ad5a47bf4e1 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 19 Dec 2024 15:48:47 +0100 Subject: [PATCH 3/4] Use Pyblish for Create --- client/ayon_harmony/api/lib.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/ayon_harmony/api/lib.py b/client/ayon_harmony/api/lib.py index 6d14f3c..336986c 100644 --- a/client/ayon_harmony/api/lib.py +++ b/client/ayon_harmony/api/lib.py @@ -403,9 +403,6 @@ def show(tool_name): kwargs["use_context"] = True elif tool_name == "publisher": kwargs["tab"] = "publish" - elif tool_name == "creator": - tool_name = "publisher" - kwargs["tab"] = "create" ProcessContext.execute_in_main_thread( lambda: host_tools.show_tool_by_name(tool_name, **kwargs) From 19cad28888908da002d97b54dcd4aef619bf04d3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 20 Dec 2024 18:57:45 +0100 Subject: [PATCH 4/4] Ruff --- client/ayon_harmony/api/__init__.py | 2 +- client/ayon_harmony/api/pipeline.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_harmony/api/__init__.py b/client/ayon_harmony/api/__init__.py index 5ecf870..dca8edd 100644 --- a/client/ayon_harmony/api/__init__.py +++ b/client/ayon_harmony/api/__init__.py @@ -48,7 +48,7 @@ __all__ = [ # pipeline "ls", - "install", + "HarmonyHost", "list_instances", "remove_instance", "select_instance", diff --git a/client/ayon_harmony/api/pipeline.py b/client/ayon_harmony/api/pipeline.py index 648c4df..86524f1 100644 --- a/client/ayon_harmony/api/pipeline.py +++ b/client/ayon_harmony/api/pipeline.py @@ -9,7 +9,6 @@ HostBase, IWorkfileHost, ILoadHost, - IPublishHost, ) from ayon_core.pipeline import ( register_loader_plugin_path,