Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions client/ayon_applications/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from ayon_core.lib import (
run_ayon_launcher_process,
get_settings_variant,
is_headless_mode_enabled,
env_value_to_bool,
)
Expand Down Expand Up @@ -228,6 +229,109 @@ def get_app_icon_url(
server_url, "addons", self.name, "icons", icon_name
])

def get_application_items(
self,
project_name: str,
task_id: str | None = None,
*,
variant: str | None = None,
version: str | None = None,
) -> list[dict[str, Any]]:
"""Get application items.

This is meant as api for other addons to get application items for
a given context. Can also filter applications for a specific task.

It does handle project bundles and settings variant automatically.

Args:
project_name (str): Project name.
task_id (str | None): Task id for which applications are fitlered.
variant (str | None): Settings variant. Current settings variant
is used if not passed in.
version (str | None): Specific version of applications addon
to get items for. If None, it will use the version
resolved for current context (variant and project).

Example application dict (may vary based on applications
addon version):
{
"host_name": str
"full_name": str
"full_label": str
"group_label": str
"variant_label": str
"icon": dict[str, str] | None
"show_grouped": bool
}

Returns:
list[dict]: Application items.

"""
if variant is None:
variant = get_settings_variant()

query = f"?variant={variant}"
if version is not None:
query += f"&version={version}"
task_path = ""
if task_id:
task_path = f"/task/{task_id}"
response = ayon_api.get(
f"addons/{self.name}/{self.version}/"
f"apps/{project_name}{task_path}{query}"
)
return response.data["applications"]

def get_tool_items(
self,
project_name: str,
*,
variant: str | None = None,
version: str | None = None,
) -> list[dict[str, Any]]:
"""Get tool items.

This is meant as api for other addons to get tools items for a given
context.

It does handle project bundles and settings variant automatically.

Args:
project_name (str): Project name.
variant (str | None): Settings variant. Current settings variant
is used if not passed in.
version (str | None): Specific version of applications addon
to get items for. If None, it will use the version
resolved for current context (variant and project).

Example tool dict (may vary based on applications addon version):
{
"full_name": str,
"full_label": str,
"group_label": str,
"variant_label": str,
"host_names": list[str],
"app_variants": list[str],
}

Returns:
list[dict]: Tool items.

"""
if variant is None:
variant = get_settings_variant()

query = f"?variant={variant}"
if version is not None:
query += f"&version={version}"
response = ayon_api.get(
f"addons/{self.name}/{self.version}/"
f"tools/{project_name}{query}"
)
return response.data["applications"]

def launch_application(
self,
app_name: str,
Expand Down
101 changes: 27 additions & 74 deletions server/actions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import copy
import typing
from typing import Any

from ayon_server.actions import (
SimpleActionManifest,
Expand All @@ -15,7 +13,11 @@
except ImportError:
SimpleForm = None

from .utils import get_application_items, ApplicationItem
from .utils import (
get_app_names_by_task_type,
get_application_items,
ApplicationItem,
)

IDENTIFIER_PREFIX = "application.launch."
IDENTIFIER_WORKFILE_PREFIX = "application.launch-workfile."
Expand Down Expand Up @@ -43,63 +45,6 @@ def _prepare_label_kwargs(item: ApplicationItem) -> dict[str, str]:
}


def _get_app_items_by_name(
addon_settings: dict[str, Any]
) -> dict[str, ApplicationItem]:
return {
item.full_name: item
for item in get_application_items(addon_settings)
}


def _get_app_names_by_task_type(
app_items_by_name: dict[str, ApplicationItem],
addon_settings: dict[str, Any],
project_entity: ProjectEntity
) -> dict[str, list[str]]:
profiles = copy.deepcopy(
addon_settings["project_applications"]["profiles"]
)

default_profile = None
profiles_by_task_type = {}
for profile in profiles:
if not profile["task_types"]:
if default_profile is None:
default_profile = profile
continue

for task_type in profile["task_types"]:
profiles_by_task_type.setdefault(task_type, profile)

app_names_by_task_type = {
task_type["name"]: []
for task_type in project_entity.task_types
}
for task_type in project_entity.task_types:
task_type_name = task_type["name"]
task_type_profile = profiles_by_task_type.get(task_type_name)
if task_type_profile is None:
task_type_profile = default_profile
if task_type_profile is None:
continue

if task_type_profile["allow_type"] == "all_applications":
profile_apps = list(app_items_by_name.keys())
profile_apps.sort()
else:
profile_apps = [
app_name
for app_name in task_type_profile["applications"]
if app_name in app_items_by_name
]

if profile_apps:
app_names_by_task_type[task_type_name] = profile_apps

return app_names_by_task_type


async def get_action_manifests(
addon: "ApplicationsAddon",
project_name: str,
Expand All @@ -115,12 +60,19 @@ async def get_action_manifests(
)
addon_settings = settings_model.dict()

app_items_by_name = _get_app_items_by_name(addon_settings)

app_names_by_task_type = _get_app_names_by_task_type(
app_items_by_name,
app_items = get_application_items(addon_settings)
app_items_by_name = {
item.full_name: item
for item in app_items
}
task_type_names = {
task_type["name"]
for task_type in project_entity.task_types
}
app_names_by_task_type = get_app_names_by_task_type(
addon_settings,
project_entity,
task_type_names,
app_items=app_items,
)

output = [
Expand Down Expand Up @@ -196,15 +148,11 @@ async def get_dynamic_action_manifests(
)
addon_settings = settings_model.dict()

project_entity = await ProjectEntity.load(project_name)

app_items_by_name = _get_app_items_by_name(addon_settings)

app_names_by_task_type = _get_app_names_by_task_type(
app_items_by_name,
addon_settings,
project_entity,
)
app_items = get_application_items(addon_settings)
app_items_by_name = {
item.full_name: item
for item in app_items
}

task_ids = {
workfile_entity.task_id
Expand All @@ -218,6 +166,11 @@ async def get_dynamic_action_manifests(
task_entity.task_type
for task_entity in task_entities
}
app_names_by_task_type = get_app_names_by_task_type(
addon_settings,
task_types,
app_items=app_items,
)

collected_apps = set()
output = []
Expand Down
Loading
Loading