allow to pass data into action items

This commit is contained in:
Jakub Trllo 2025-09-18 15:43:59 +02:00
parent 8bbd15c482
commit a7b379059f
7 changed files with 42 additions and 51 deletions

View file

@ -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,
)

View file

@ -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()
)

View file

@ -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,
)

View file

@ -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:

View file

@ -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 = {}

View file

@ -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()
)

View file

@ -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(