Merge branch 'develop' into enhancement/1496-yn-0069-more-user-data-in-templates

This commit is contained in:
Jakub Trllo 2025-10-23 11:09:19 +02:00 committed by GitHub
commit 7542d446d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 67 additions and 70 deletions

View file

@ -35,6 +35,8 @@ body:
label: Version label: Version
description: What version are you running? Look to AYON Tray description: What version are you running? Look to AYON Tray
options: options:
- 1.6.6
- 1.6.5
- 1.6.4 - 1.6.4
- 1.6.3 - 1.6.3
- 1.6.2 - 1.6.2

View file

@ -2,7 +2,6 @@
"""Base class for AYON addons.""" """Base class for AYON addons."""
from __future__ import annotations from __future__ import annotations
import copy
import os import os
import sys import sys
import time import time
@ -13,6 +12,7 @@ import collections
import warnings import warnings
from uuid import uuid4 from uuid import uuid4
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from urllib.parse import urlencode
from types import ModuleType from types import ModuleType
import typing import typing
from typing import Optional, Any, Union from typing import Optional, Any, Union
@ -136,39 +136,47 @@ def load_addons(force: bool = False) -> None:
time.sleep(0.1) time.sleep(0.1)
def _get_ayon_bundle_data() -> Optional[dict[str, Any]]: def _get_ayon_bundle_data() -> tuple[
dict[str, Any], Optional[dict[str, Any]]
]:
studio_bundle_name = os.environ.get("AYON_STUDIO_BUNDLE_NAME") studio_bundle_name = os.environ.get("AYON_STUDIO_BUNDLE_NAME")
project_bundle_name = os.getenv("AYON_BUNDLE_NAME") project_bundle_name = os.getenv("AYON_BUNDLE_NAME")
bundles = ayon_api.get_bundles()["bundles"] bundles = ayon_api.get_bundles()["bundles"]
project_bundle = next( studio_bundle = next(
( (
bundle bundle
for bundle in bundles for bundle in bundles
if bundle["name"] == project_bundle_name if bundle["name"] == studio_bundle_name
), ),
None None
) )
studio_bundle = None
if studio_bundle_name and project_bundle_name != studio_bundle_name: if studio_bundle is None:
studio_bundle = next( raise RuntimeError(f"Failed to find bundle '{studio_bundle_name}'.")
project_bundle = None
if project_bundle_name and project_bundle_name != studio_bundle_name:
project_bundle = next(
( (
bundle bundle
for bundle in bundles for bundle in bundles
if bundle["name"] == studio_bundle_name if bundle["name"] == project_bundle_name
), ),
None None
) )
if project_bundle and studio_bundle: if project_bundle is None:
addons = copy.deepcopy(studio_bundle["addons"]) raise RuntimeError(
addons.update(project_bundle["addons"]) f"Failed to find project bundle '{project_bundle_name}'."
project_bundle["addons"] = addons )
return project_bundle
return studio_bundle, project_bundle
def _get_ayon_addons_information( def _get_ayon_addons_information(
bundle_info: dict[str, Any] studio_bundle: dict[str, Any],
) -> list[dict[str, Any]]: project_bundle: Optional[dict[str, Any]],
) -> dict[str, str]:
"""Receive information about addons to use from server. """Receive information about addons to use from server.
Todos: Todos:
@ -181,22 +189,20 @@ def _get_ayon_addons_information(
list[dict[str, Any]]: List of addon information to use. list[dict[str, Any]]: List of addon information to use.
""" """
output = [] key_values = {
bundle_addons = bundle_info["addons"] "summary": "true",
addons = ayon_api.get_addons_info()["addons"] "bundle_name": studio_bundle["name"],
for addon in addons: }
name = addon["name"] if project_bundle:
versions = addon.get("versions") key_values["project_bundle_name"] = project_bundle["name"]
addon_version = bundle_addons.get(name)
if addon_version is None or not versions: query = urlencode(key_values)
continue
version = versions.get(addon_version) response = ayon_api.get(f"settings?{query}")
if version: return {
version = copy.deepcopy(version) addon["name"]: addon["version"]
version["name"] = name for addon in response.data["addons"]
version["version"] = addon_version }
output.append(version)
return output
def _load_ayon_addons(log: logging.Logger) -> list[ModuleType]: def _load_ayon_addons(log: logging.Logger) -> list[ModuleType]:
@ -214,8 +220,8 @@ def _load_ayon_addons(log: logging.Logger) -> list[ModuleType]:
""" """
all_addon_modules = [] all_addon_modules = []
bundle_info = _get_ayon_bundle_data() studio_bundle, project_bundle = _get_ayon_bundle_data()
addons_info = _get_ayon_addons_information(bundle_info) addons_info = _get_ayon_addons_information(studio_bundle, project_bundle)
if not addons_info: if not addons_info:
return all_addon_modules return all_addon_modules
@ -227,17 +233,16 @@ def _load_ayon_addons(log: logging.Logger) -> list[ModuleType]:
dev_addons_info = {} dev_addons_info = {}
if dev_mode_enabled: if dev_mode_enabled:
# Get dev addons info only when dev mode is enabled # Get dev addons info only when dev mode is enabled
dev_addons_info = bundle_info.get("addonDevelopment", dev_addons_info) dev_addons_info = studio_bundle.get(
"addonDevelopment", dev_addons_info
)
addons_dir_exists = os.path.exists(addons_dir) addons_dir_exists = os.path.exists(addons_dir)
if not addons_dir_exists: if not addons_dir_exists:
log.warning( log.warning(
f"Addons directory does not exists. Path \"{addons_dir}\"") f"Addons directory does not exists. Path \"{addons_dir}\"")
for addon_info in addons_info: for addon_name, addon_version in addons_info.items():
addon_name = addon_info["name"]
addon_version = addon_info["version"]
# core addon does not have any addon object # core addon does not have any addon object
if addon_name == "core": if addon_name == "core":
continue continue

View file

@ -32,6 +32,7 @@ class CollectCoreJobEnvVars(pyblish.api.ContextPlugin):
for key in [ for key in [
"AYON_BUNDLE_NAME", "AYON_BUNDLE_NAME",
"AYON_STUDIO_BUNDLE_NAME",
"AYON_USE_STAGING", "AYON_USE_STAGING",
"AYON_IN_TESTS", "AYON_IN_TESTS",
# NOTE Not sure why workdir is needed? # NOTE Not sure why workdir is needed?

View file

@ -130,7 +130,7 @@ class ExtractOTIOReview(
# NOTE it looks like it is set only in hiero integration # NOTE it looks like it is set only in hiero integration
res_data = {"width": self.to_width, "height": self.to_height} res_data = {"width": self.to_width, "height": self.to_height}
for key in res_data: for key in res_data:
for meta_prefix in ("ayon.source.", "openpype.source."): for meta_prefix in ("ayon.source", "openpype.source"):
meta_key = f"{meta_prefix}.{key}" meta_key = f"{meta_prefix}.{key}"
value = media_metadata.get(meta_key) value = media_metadata.get(meta_key)
if value is not None: if value is not None:

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Package declaring AYON addon 'core' version.""" """Package declaring AYON addon 'core' version."""
__version__ = "1.6.4+dev" __version__ = "1.6.6+dev"

View file

@ -1,6 +1,6 @@
name = "core" name = "core"
title = "Core" title = "Core"
version = "1.6.4+dev" version = "1.6.6+dev"
client_dir = "ayon_core" client_dir = "ayon_core"

View file

@ -5,7 +5,7 @@
[tool.poetry] [tool.poetry]
name = "ayon-core" name = "ayon-core"
version = "1.6.4+dev" version = "1.6.6+dev"
description = "" description = ""
authors = ["Ynput Team <team@ynput.io>"] authors = ["Ynput Team <team@ynput.io>"]
readme = "README.md" readme = "README.md"
@ -27,17 +27,6 @@ codespell = "^2.2.6"
semver = "^3.0.2" semver = "^3.0.2"
mypy = "^1.14.0" mypy = "^1.14.0"
mock = "^5.0.0" mock = "^5.0.0"
tomlkit = "^0.13.2"
requests = "^2.32.3"
mkdocs-material = "^9.6.7"
mkdocs-autoapi = "^0.4.0"
mkdocstrings-python = "^1.16.2"
mkdocs-minify-plugin = "^0.8.0"
markdown-checklist = "^0.4.4"
mdx-gh-links = "^0.4"
pymdown-extensions = "^10.14.3"
mike = "^2.1.3"
mkdocstrings-shell = "^1.0.2"
nxtools = "^1.6" nxtools = "^1.6"
[tool.poetry.group.test.dependencies] [tool.poetry.group.test.dependencies]

View file

@ -454,7 +454,7 @@ DEFAULT_TOOLS_VALUES = {
"hosts": [], "hosts": [],
"task_types": [], "task_types": [],
"tasks": [], "tasks": [],
"template": "{product[type]}{Task[name]}{Variant}" "template": "{product[type]}{Task[name]}{Variant}<_{Aov}>"
}, },
{ {
"product_types": [ "product_types": [

View file

@ -246,75 +246,75 @@ def test_multiple_review_clips_no_gap():
expected = [ expected = [
# 10 head black frames generated from gap (991-1000) # 10 head black frames generated from gap (991-1000)
'/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi' '/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi'
' -i color=c=black:s=1280x720 -tune ' ' -i color=c=black:s=1920x1080 -tune '
'stillimage -start_number 991 -pix_fmt rgba C:/result/output.%04d.png', 'stillimage -start_number 991 -pix_fmt rgba C:/result/output.%04d.png',
# Alternance 25fps tiff sequence and 24fps exr sequence # Alternance 25fps tiff sequence and 24fps exr sequence
# for 100 frames each # for 100 frames each
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1001 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1001 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr ' f'C:\\with_tc{os.sep}output.%04d.exr '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1102 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1102 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1198 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1198 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr ' f'C:\\with_tc{os.sep}output.%04d.exr '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1299 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1299 -pix_fmt rgba C:/result/output.%04d.png',
# Repeated 25fps tiff sequence multiple times till the end # Repeated 25fps tiff sequence multiple times till the end
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1395 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1395 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1496 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1496 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1597 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1597 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1698 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1698 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1799 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1799 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1900 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1900 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 2001 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 2001 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 2102 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 2102 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i '
f'C:\\no_tc{os.sep}output.%04d.tif ' f'C:\\no_tc{os.sep}output.%04d.tif '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 2203 -pix_fmt rgba C:/result/output.%04d.png' '-start_number 2203 -pix_fmt rgba C:/result/output.%04d.png'
] ]
@ -348,12 +348,12 @@ def test_multiple_review_clips_with_gap():
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr ' f'C:\\with_tc{os.sep}output.%04d.exr '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1003 -pix_fmt rgba C:/result/output.%04d.png', '-start_number 1003 -pix_fmt rgba C:/result/output.%04d.png',
'/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i ' '/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i '
f'C:\\with_tc{os.sep}output.%04d.exr ' f'C:\\with_tc{os.sep}output.%04d.exr '
'-vf scale=1280:720:flags=lanczos -compression_level 5 ' '-vf scale=1920:1080:flags=lanczos -compression_level 5 '
'-start_number 1091 -pix_fmt rgba C:/result/output.%04d.png' '-start_number 1091 -pix_fmt rgba C:/result/output.%04d.png'
] ]