From ed987073478f9f3ba53c393edcd33711a0e9d1a0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 10 Sep 2024 21:41:00 +0200 Subject: [PATCH 1/8] Add missing space in log message --- client/ayon_core/plugins/publish/extract_burnin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 58a032a030..a25b7244d4 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -198,7 +198,7 @@ class ExtractBurnin(publish.Extractor): ) if not burnins_per_repres: self.log.debug( - "Skipped instance. No representations found matching a burnin" + "Skipped instance. No representations found matching a burnin " "definition in: %s", burnin_defs ) return From 264ff3f217c974fb36d1c070fec27dd761e37c4c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 10 Sep 2024 21:58:52 +0200 Subject: [PATCH 2/8] Cosmetics --- .../ayon_core/plugins/publish/extract_burnin.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index a25b7244d4..12cc9fbc71 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -399,7 +399,7 @@ class ExtractBurnin(publish.Extractor): add_repre_files_for_cleanup(instance, new_repre) - # Cleanup temp staging dir after procesisng of output definitions + # Cleanup temp staging dir after processing of output definitions if do_convert: temp_dir = repre["stagingDir"] shutil.rmtree(temp_dir) @@ -420,6 +420,11 @@ class ExtractBurnin(publish.Extractor): self.log.debug("Removed: \"{}\"".format(filepath)) def _get_burnin_options(self): + """Get the burnin options from `ExtractBurnin` settings. + + Returns: + dict[str, Any]: Burnin options. + """ # Prepare burnin options burnin_options = copy.deepcopy(self.default_options) if self.options: @@ -696,7 +701,7 @@ class ExtractBurnin(publish.Extractor): """Prepare data for representation. Args: - instance (Instance): Currently processed Instance. + instance (pyblish.api.Instance): Currently processed Instance. repre (dict): Currently processed representation. burnin_data (dict): Copy of basic burnin data based on instance data. @@ -752,9 +757,10 @@ class ExtractBurnin(publish.Extractor): Args: profile (dict): Profile from presets matching current context. + instance (pyblish.api.Instance): Publish instance. Returns: - list: Contain all valid output definitions. + list[dict[str, Any]]: Contain all valid output definitions. """ filtered_burnin_defs = [] @@ -774,8 +780,8 @@ class ExtractBurnin(publish.Extractor): families, families_filters ): self.log.debug(( - "Skipped burnin definition \"{}\". Family" - " filters ({}) does not match current instance families: {}" + "Skipped burnin definition \"{}\". Family filters ({}) " + "does not match current instance families: {}" ).format( filename_suffix, str(families_filters), str(families) )) From b55a3e5974f76690cfad853d3b4354a27e6c3baf Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 10 Sep 2024 23:10:28 +0200 Subject: [PATCH 3/8] Get context attributes from current task entity (if current task is set) instead of from folder entity --- .../plugins/publish/collect_context_entities.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_context_entities.py b/client/ayon_core/plugins/publish/collect_context_entities.py index c8d25bc3e6..4de83f0d53 100644 --- a/client/ayon_core/plugins/publish/collect_context_entities.py +++ b/client/ayon_core/plugins/publish/collect_context_entities.py @@ -53,8 +53,9 @@ class CollectContextEntities(pyblish.api.ContextPlugin): context.data["folderEntity"] = folder_entity context.data["taskEntity"] = task_entity - - folder_attributes = folder_entity["attrib"] + context_attributes = ( + task_entity["attrib"] if task_entity else folder_entity["attrib"] + ) # Task type task_type = None @@ -63,12 +64,12 @@ class CollectContextEntities(pyblish.api.ContextPlugin): context.data["taskType"] = task_type - frame_start = folder_attributes.get("frameStart") + frame_start = context_attributes.get("frameStart") if frame_start is None: frame_start = 1 self.log.warning("Missing frame start. Defaulting to 1.") - frame_end = folder_attributes.get("frameEnd") + frame_end = context_attributes.get("frameEnd") if frame_end is None: frame_end = 2 self.log.warning("Missing frame end. Defaulting to 2.") @@ -76,8 +77,8 @@ class CollectContextEntities(pyblish.api.ContextPlugin): context.data["frameStart"] = frame_start context.data["frameEnd"] = frame_end - handle_start = folder_attributes.get("handleStart") or 0 - handle_end = folder_attributes.get("handleEnd") or 0 + handle_start = context_attributes.get("handleStart") or 0 + handle_end = context_attributes.get("handleEnd") or 0 context.data["handleStart"] = int(handle_start) context.data["handleEnd"] = int(handle_end) @@ -87,7 +88,7 @@ class CollectContextEntities(pyblish.api.ContextPlugin): context.data["frameStartHandle"] = frame_start_h context.data["frameEndHandle"] = frame_end_h - context.data["fps"] = folder_attributes["fps"] + context.data["fps"] = context_attributes["fps"] def _get_folder_entity(self, project_name, folder_path): if not folder_path: From 484bd4455ce5a01f8c68f18e744f405bd7a2b4e0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:08:07 +0200 Subject: [PATCH 4/8] use transient data for promised context --- client/ayon_core/pipeline/create/structures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/create/structures.py b/client/ayon_core/pipeline/create/structures.py index 311d382ac9..9019b05b21 100644 --- a/client/ayon_core/pipeline/create/structures.py +++ b/client/ayon_core/pipeline/create/structures.py @@ -724,7 +724,7 @@ class CreatedInstance: value when set to True. """ - return self._data.get("has_promised_context", False) + return self._transient_data.get("has_promised_context", False) def data_to_store(self): """Collect data that contain json parsable types. From 15c7256901575c86fed29951bc78a217e9d78c35 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 17 Sep 2024 20:30:11 +0200 Subject: [PATCH 5/8] Add "Show in AYON" launcher action --- .../ayon_core/plugins/actions/show_in_ayon.py | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 client/ayon_core/plugins/actions/show_in_ayon.py diff --git a/client/ayon_core/plugins/actions/show_in_ayon.py b/client/ayon_core/plugins/actions/show_in_ayon.py new file mode 100644 index 0000000000..8859f79171 --- /dev/null +++ b/client/ayon_core/plugins/actions/show_in_ayon.py @@ -0,0 +1,91 @@ +import os +import urllib.parse +import webbrowser + +from ayon_core.pipeline import LauncherAction +from ayon_core.resources import get_ayon_icon_filepath +import ayon_api + + +def get_ayon_entity_uri( + project_name, + entity_id, + entity_type, +) -> str: + """Resolve AYON Entity URI from representation context. + + Note: + The representation context is the `get_representation_context` dict + containing the `project`, `folder, `representation` and so forth. + It is not the representation entity `context` key. + + Arguments: + project_name (str): The project name. + entity_id (str): The entity UUID. + entity_type (str): The entity type, like "folder" or"task". + + Raises: + RuntimeError: Unable to resolve to a single valid URI. + + Returns: + str: The AYON entity URI. + + """ + response = ayon_api.post( + f"projects/{project_name}/uris", + entityType=entity_type, + ids=[entity_id]) + if response.status_code != 200: + raise RuntimeError( + f"Unable to resolve AYON entity URI for '{project_name}' " + f"{entity_type} id '{entity_id}': {response.text}" + ) + uris = response.data["uris"] + if len(uris) != 1: + raise RuntimeError( + f"Unable to resolve AYON entity URI for '{project_name}' " + f"{entity_type} id '{entity_id}' to single URI. " + f"Received data: {response.data}" + ) + return uris[0]["uri"] + + +class ShowInAyon(LauncherAction): + """Open AYON browser page to the current context.""" + name = "showinayon" + label = "Show in AYON" + icon = get_ayon_icon_filepath() + color = "#e0e1e1" + order = 999 + + def process(self, selection, **kwargs): + + url = os.environ["AYON_SERVER_URL"] + if selection.is_project_selected: + project_name = selection.project_name + url += f"/projects/{project_name}/browser" + + # Specify entity URI if task or folder is select + entity = None + entity_type = None + if selection.is_task_selected: + entity = selection.get_task_entity() + entity_type = "task" + elif selection.is_folder_selected: + entity = selection.get_folder_entity() + entity_type = "folder" + + if entity and entity_type: + uri = get_ayon_entity_uri( + project_name, + entity_id=entity["id"], + entity_type=entity_type + ) + uri_encoded = urllib.parse.quote_plus(uri) + url += f"?uri={uri_encoded}" + + # Open URL in webbrowser + self.log.info(f"Opening URL: {url}") + webbrowser.open(url, + # Try in new tab + new=2) From c2cfef7703d7ee9bb8ddd77b18d848ef4efdbdd5 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 18 Sep 2024 00:48:44 +0200 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/plugins/publish/extract_burnin.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 12cc9fbc71..00f49a55b9 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -198,8 +198,8 @@ class ExtractBurnin(publish.Extractor): ) if not burnins_per_repres: self.log.debug( - "Skipped instance. No representations found matching a burnin " - "definition in: %s", burnin_defs + "Skipped instance. No representations found matching a burnin" + " definition in: %s", burnin_defs ) return @@ -424,6 +424,7 @@ class ExtractBurnin(publish.Extractor): Returns: dict[str, Any]: Burnin options. + """ # Prepare burnin options burnin_options = copy.deepcopy(self.default_options) @@ -761,6 +762,7 @@ class ExtractBurnin(publish.Extractor): Returns: list[dict[str, Any]]: Contain all valid output definitions. + """ filtered_burnin_defs = [] From 086b452a02e4c94bf4457c13271019de2908dadf Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 18 Sep 2024 00:51:19 +0200 Subject: [PATCH 7/8] Reformat based on code review --- client/ayon_core/plugins/publish/extract_burnin.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 12cc9fbc71..dff82f3a80 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -779,12 +779,11 @@ class ExtractBurnin(publish.Extractor): if not self.families_filter_validation( families, families_filters ): - self.log.debug(( - "Skipped burnin definition \"{}\". Family filters ({}) " - "does not match current instance families: {}" - ).format( - filename_suffix, str(families_filters), str(families) - )) + self.log.debug( + f"Skipped burnin definition \"{filename_suffix}\"." + f" Family filters ({families_filters}) does not match" + f" current instance families: {families}" + ) continue # Burnin values From 5090732cf8c6d0b104eeed4fbcd57bb3b93d2ebc Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 18 Sep 2024 12:02:25 +0200 Subject: [PATCH 8/8] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/plugins/actions/show_in_ayon.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/plugins/actions/show_in_ayon.py b/client/ayon_core/plugins/actions/show_in_ayon.py index 8859f79171..e30eaa2bc9 100644 --- a/client/ayon_core/plugins/actions/show_in_ayon.py +++ b/client/ayon_core/plugins/actions/show_in_ayon.py @@ -50,16 +50,14 @@ def get_ayon_entity_uri( return uris[0]["uri"] -class ShowInAyon(LauncherAction): +class ShowInAYON(LauncherAction): """Open AYON browser page to the current context.""" name = "showinayon" label = "Show in AYON" icon = get_ayon_icon_filepath() - color = "#e0e1e1" order = 999 def process(self, selection, **kwargs): - url = os.environ["AYON_SERVER_URL"] if selection.is_project_selected: project_name = selection.project_name @@ -86,6 +84,4 @@ class ShowInAyon(LauncherAction): # Open URL in webbrowser self.log.info(f"Opening URL: {url}") - webbrowser.open(url, - # Try in new tab - new=2) + webbrowser.open_new_tab(url)