From a7b379059fdba2282ce1c9ccec50c98078f1bc23 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:43:59 +0200 Subject: [PATCH] allow to pass data into action items --- client/ayon_core/pipeline/actions/loader.py | 30 +++++++++---------- client/ayon_core/plugins/loader/copy_file.py | 12 ++++---- .../plugins/loader/delete_old_versions.py | 12 ++++---- client/ayon_core/plugins/loader/delivery.py | 8 ++--- .../ayon_core/plugins/loader/export_otio.py | 11 ++++--- client/ayon_core/plugins/loader/open_file.py | 9 +++--- .../plugins/loader/push_to_project.py | 11 ++++--- 7 files changed, 42 insertions(+), 51 deletions(-) diff --git a/client/ayon_core/pipeline/actions/loader.py b/client/ayon_core/pipeline/actions/loader.py index 2c3ad39c48..94e30c5114 100644 --- a/client/ayon_core/pipeline/actions/loader.py +++ b/client/ayon_core/pipeline/actions/loader.py @@ -5,6 +5,7 @@ import collections import copy import logging from abc import ABC, abstractmethod +import typing from typing import Optional, Any, Callable from dataclasses import dataclass @@ -23,6 +24,12 @@ from ayon_core.settings import get_studio_settings, get_project_settings from ayon_core.pipeline import Anatomy from ayon_core.pipeline.plugin_discover import discover_plugins +if typing.TYPE_CHECKING: + from typing import Union + + DataBaseType = Union[str, int, float, bool] + DataType = dict[str, Union[DataBaseType, list[DataBaseType]]] + _PLACEHOLDER = object() @@ -383,25 +390,23 @@ class LoaderActionItem: Attributes: identifier (str): Unique action identifier. What is sent to action plugin when the action is executed. - entity_type (str): Entity type to which the action belongs. - entity_ids (set[str]): Entity ids to which the action belongs. label (str): Text shown in UI. order (int): Order of the action in UI. group_label (Optional[str]): Label of the group to which the action belongs. - icon (Optional[dict[str, Any]]): Icon definition. + icon (Optional[dict[str, Any]): Icon definition. + data (Optional[DataType]): Action item data. plugin_identifier (Optional[str]): Identifier of the plugin which created the action item. Is filled automatically. Is not changed if is filled -> can lead to different plugin. """ identifier: str - entity_type: str - entity_ids: set[str] label: str order: int = 0 group_label: Optional[str] = None icon: Optional[dict[str, Any]] = None + data: Optional[DataType] = None # Is filled automatically plugin_identifier: str = None @@ -555,19 +560,17 @@ class LoaderActionPlugin(ABC): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: Optional[DataType], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: """Execute an action. Args: identifier (str): Action identifier. - entity_ids: (set[str]): Entity ids stored on action item. - entity_type: (str): Entity type stored on action item. selection (LoaderActionSelection): Selection wrapper. Can be used to get entities or get context of original selection. + data (Optional[DataType]): Additional action item data. form_values (dict[str, Any]): Attribute values. Returns: @@ -676,9 +679,8 @@ class LoaderActionsContext: self, plugin_identifier: str, action_identifier: str, - entity_type: str, - entity_ids: set[str], selection: LoaderActionSelection, + data: Optional[DataType], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: """Trigger action execution. @@ -686,11 +688,10 @@ class LoaderActionsContext: Args: plugin_identifier (str): Identifier of the plugin. action_identifier (str): Identifier of the action. - entity_type (str): Entity type defined on the action item. - entity_ids (set[str]): Entity ids defined on the action item. selection (LoaderActionSelection): Selection wrapper. Can be used to get what is selected in UI and to get access to entity cache. + data (Optional[DataType]): Additional action item data. form_values (dict[str, Any]): Form values related to action. Usually filled if action returned response with form. @@ -699,9 +700,8 @@ class LoaderActionsContext: plugin = plugins_by_id[plugin_identifier] return plugin.execute_action( action_identifier, - entity_ids, - entity_type, selection, + data, form_values, ) diff --git a/client/ayon_core/plugins/loader/copy_file.py b/client/ayon_core/plugins/loader/copy_file.py index 09875698bd..8253a772eb 100644 --- a/client/ayon_core/plugins/loader/copy_file.py +++ b/client/ayon_core/plugins/loader/copy_file.py @@ -44,8 +44,7 @@ class CopyFileActionPlugin(LoaderActionPlugin): identifier="copy-path", label=repre_name, group_label="Copy file path", - entity_ids=repre_ids, - entity_type="representation", + data={"representation_ids": list(repre_ids)}, icon={ "type": "material-symbols", "name": "content_copy", @@ -58,8 +57,7 @@ class CopyFileActionPlugin(LoaderActionPlugin): identifier="copy-file", label=repre_name, group_label="Copy file", - entity_ids=repre_ids, - entity_type="representation", + data={"representation_ids": list(repre_ids)}, icon={ "type": "material-symbols", "name": "file_copy", @@ -72,14 +70,14 @@ class CopyFileActionPlugin(LoaderActionPlugin): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: dict, form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: from qtpy import QtWidgets, QtCore - repre = next(iter(selection.entities.get_representations(entity_ids))) + repre_ids = data["representation_ids"] + repre = next(iter(selection.entities.get_representations(repre_ids))) path = get_representation_path_with_anatomy( repre, selection.get_project_anatomy() ) diff --git a/client/ayon_core/plugins/loader/delete_old_versions.py b/client/ayon_core/plugins/loader/delete_old_versions.py index 69b93cbb32..cc7d4d3fa6 100644 --- a/client/ayon_core/plugins/loader/delete_old_versions.py +++ b/client/ayon_core/plugins/loader/delete_old_versions.py @@ -61,8 +61,7 @@ class DeleteOldVersions(LoaderActionPlugin): identifier="delete-versions", label="Delete Versions", order=35, - entity_ids=product_ids, - entity_type="product", + data={"product_ids": list(product_ids)}, icon={ "type": "material-symbols", "name": "delete", @@ -73,8 +72,7 @@ class DeleteOldVersions(LoaderActionPlugin): identifier="calculate-versions-size", label="Calculate Versions size", order=30, - entity_ids=product_ids, - entity_type="product", + data={"product_ids": list(product_ids)}, icon={ "type": "material-symbols", "name": "auto_delete", @@ -86,9 +84,8 @@ class DeleteOldVersions(LoaderActionPlugin): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: dict[str, Any], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: step = form_values.get("step") @@ -106,12 +103,13 @@ class DeleteOldVersions(LoaderActionPlugin): if remove_publish_folder is None: remove_publish_folder = False + product_ids = data["product_ids"] if step == "prepare-data": return self._prepare_data_step( identifier, versions_to_keep, remove_publish_folder, - entity_ids, + product_ids, selection, ) diff --git a/client/ayon_core/plugins/loader/delivery.py b/client/ayon_core/plugins/loader/delivery.py index d1fbb20afc..538bdec414 100644 --- a/client/ayon_core/plugins/loader/delivery.py +++ b/client/ayon_core/plugins/loader/delivery.py @@ -54,8 +54,7 @@ class DeliveryAction(LoaderActionPlugin): identifier="deliver-versions", label="Deliver Versions", order=35, - entity_ids=version_ids, - entity_type="version", + data={"version_ids": list(version_ids)}, icon={ "type": "material-symbols", "name": "upload", @@ -67,15 +66,14 @@ class DeliveryAction(LoaderActionPlugin): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: dict[str, Any], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: try: # TODO run the tool in subprocess dialog = DeliveryOptionsDialog( - selection.project_name, entity_ids, self.log + selection.project_name, data["version_ids"], self.log ) dialog.exec_() except Exception: diff --git a/client/ayon_core/plugins/loader/export_otio.py b/client/ayon_core/plugins/loader/export_otio.py index 8a142afdb5..1ad9038c5e 100644 --- a/client/ayon_core/plugins/loader/export_otio.py +++ b/client/ayon_core/plugins/loader/export_otio.py @@ -59,8 +59,7 @@ class ExportOTIO(LoaderActionPlugin): label="Export OTIO", group_label=None, order=35, - entity_ids=version_ids, - entity_type="version", + data={"version_ids": list(version_ids)}, icon={ "type": "material-symbols", "name": "save", @@ -73,16 +72,16 @@ class ExportOTIO(LoaderActionPlugin): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: dict[str, Any], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: _import_otio() + version_ids = data["version_ids"] versions_by_id = { version["id"]: version - for version in selection.entities.get_versions(entity_ids) + for version in selection.entities.get_versions(version_ids) } product_ids = { version["productId"] @@ -101,7 +100,7 @@ class ExportOTIO(LoaderActionPlugin): for folder in selection.entities.get_folders(folder_ids) } repre_entities = selection.entities.get_versions_representations( - entity_ids + version_ids ) version_path_by_id = {} diff --git a/client/ayon_core/plugins/loader/open_file.py b/client/ayon_core/plugins/loader/open_file.py index f7a7167c9a..1ed470c06e 100644 --- a/client/ayon_core/plugins/loader/open_file.py +++ b/client/ayon_core/plugins/loader/open_file.py @@ -84,8 +84,7 @@ class OpenFileAction(LoaderActionPlugin): label=repre_name, group_label="Open file", order=-10, - entity_ids=repre_ids, - entity_type="representation", + data={"representation_ids": list(repre_ids)}, icon={ "type": "material-symbols", "name": "play_circle", @@ -98,14 +97,14 @@ class OpenFileAction(LoaderActionPlugin): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: dict[str, Any], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: path = None repre_path = None - for repre in selection.entities.get_representations(entity_ids): + repre_ids = data["representation_ids"] + for repre in selection.entities.get_representations(repre_ids): repre_path = get_representation_path_with_anatomy( repre, selection.get_project_anatomy() ) diff --git a/client/ayon_core/plugins/loader/push_to_project.py b/client/ayon_core/plugins/loader/push_to_project.py index bd0da71c0e..275f5de88d 100644 --- a/client/ayon_core/plugins/loader/push_to_project.py +++ b/client/ayon_core/plugins/loader/push_to_project.py @@ -42,8 +42,7 @@ class PushToProject(LoaderActionPlugin): identifier="core.push-to-project", label="Push to project", order=35, - entity_ids=version_ids, - entity_type="version", + data={"version_ids": list(version_ids)}, icon={ "type": "material-symbols", "name": "send", @@ -56,12 +55,12 @@ class PushToProject(LoaderActionPlugin): def execute_action( self, identifier: str, - entity_ids: set[str], - entity_type: str, selection: LoaderActionSelection, + data: dict[str, Any], form_values: dict[str, Any], ) -> Optional[LoaderActionResult]: - if len(entity_ids) > 1: + version_ids = data["version_ids"] + if len(version_ids) > 1: return LoaderActionResult( message="Please select only one version", success=False, @@ -77,7 +76,7 @@ class PushToProject(LoaderActionPlugin): args = get_ayon_launcher_args( push_tool_script_path, "--project", selection.project_name, - "--versions", ",".join(entity_ids) + "--versions", ",".join(version_ids) ) run_detached_process(args) return LoaderActionResult(