fallback to latest version if missing approved version with status

This commit is contained in:
jm22dogs 2025-11-14 11:25:23 +00:00
parent ee7ee67542
commit be0f9d0a80

View file

@ -9,7 +9,7 @@ import collections
import numbers
import copy
from functools import wraps
from typing import Optional, Union, Any, overload
from typing import Optional, Union, Any, overload, Iterable
import ayon_api
@ -28,6 +28,7 @@ ContainersFilterResult = collections.namedtuple(
["latest", "outdated", "not_found", "invalid"]
)
_PLACEHOLDER = object()
class HeroVersionType(object):
def __init__(self, version):
@ -999,35 +1000,13 @@ def get_last_versions_with_status(
statuses: Iterable[str],
active: Union[bool, None] = True,
fields: Optional[Iterable[str]] = None,
own_attributes=ayon_api.server_api._PLACEHOLDER,
own_attributes=_PLACEHOLDER,
):
"""
Retrieve the latest version for each product ID that matches the given status filter.
Args:
project_name (str): Name of the project.
product_ids (Iterable[str]): Iterable of product IDs to query.
statuses (Iterable[str]): Iterable of status names to filter versions.
active (bool or None, optional): If True, only active versions are returned.
If False, only inactive versions are returned. If None, both are returned.
fields (Optional[Iterable[str]], optional): Additional fields to include in the result.
own_attributes: Custom attributes to include in the query (default is ayon_api.server_api._PLACEHOLDER).
Returns:
Dict[str, Optional[dict]]: A dictionary mapping each product ID to its latest version
entity (as a dict) that matches the status filter. If no version matches for a
product ID, its value will be None.
Behavior:
- Only the latest version (by version number) for each product ID is returned.
- If no versions match the status filter for a product ID, the value for that product ID
in the output dictionary will be None.
"""
if fields:
fields = set(fields)
fields.add("productId")
product_ids = set(product_ids)
versions = ayon_api.get_versions(
versions_with_status = ayon_api.get_versions(
project_name,
product_ids=product_ids,
hero=False,
@ -1036,27 +1015,39 @@ def get_last_versions_with_status(
statuses=statuses,
own_attributes=own_attributes,
)
versions_by_product_id = {
product_id: []
for product_id in product_ids
latest_versions = ayon_api.get_versions(
project_name,
product_ids=product_ids,
latest=True,
hero=False,
active=active,
fields=fields,
own_attributes=own_attributes,
)
latest_versions_by_product_ids = {
pid: [v for v in latest_versions if v["productId"] == pid]
for pid in product_ids
}
for version in versions:
product_id = version["productId"]
versions_by_product_id[product_id].append(version)
output = {
product_id: None
for product_id in product_ids
# remove all not latest versions
version_by_product_ids = {
pid: [v for v in versions_with_status if v["productId"] == pid]
for pid in product_ids
}
for product_id, product_versions in versions_by_product_id.items():
if not product_versions:
continue
product_versions.sort(key=lambda v: v["version"])
output[product_id] = product_versions[-1]
versions = list()
for pid in product_ids:
if not version_by_product_ids[pid]:
version_by_product_ids[pid] = latest_versions_by_product_ids[pid]
sorted_versions = sorted(
version_by_product_ids[pid], key=lambda x: x["version"]
)
versions.append(sorted_versions[-1])
output = {version["productId"]: version for version in versions}
for product_id in product_ids:
output.setdefault(product_id, None)
return output
def is_compatible_loader(Loader, context):
"""Return whether a loader is compatible with a context.