Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CreatePlugin: Get next version helper #5242

Merged
merged 7 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions openpype/pipeline/create/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
PRE_CREATE_THUMBNAIL_KEY,
)

from .utils import (
get_last_versions_for_instances,
get_next_versions_for_instances,
)

from .subset_name import (
TaskNotSetError,
get_subset_name_template,
Expand Down Expand Up @@ -46,6 +51,9 @@
"DEFAULT_SUBSET_TEMPLATE",
"PRE_CREATE_THUMBNAIL_KEY",

"get_last_versions_for_instances",
"get_next_versions_for_instances",

"TaskNotSetError",
"get_subset_name_template",
"get_subset_name",
Expand Down
4 changes: 2 additions & 2 deletions openpype/pipeline/create/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -1122,10 +1122,10 @@ def creator_attributes(self):

@property
def creator_attribute_defs(self):
"""Attribute defintions defined by creator plugin.
"""Attribute definitions defined by creator plugin.

Returns:
List[AbstractAttrDef]: Attribute defitions.
List[AbstractAttrDef]: Attribute definitions.
"""

return self.creator_attributes.attr_defs
Expand Down
23 changes: 22 additions & 1 deletion openpype/pipeline/create/creator_plugins.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import copy
import collections

Expand All @@ -21,6 +20,7 @@
)

from .subset_name import get_subset_name
from .utils import get_next_versions_for_instances
from .legacy_create import LegacyCreator


Expand Down Expand Up @@ -483,6 +483,27 @@ def set_instance_thumbnail_path(self, instance_id, thumbnail_path=None):
thumbnail_path
)

def get_next_versions_for_instances(self, instances):
"""Prepare next versions for instances.

This is helper method to receive next possible versions for instances.
It is using context information on instance to receive them, 'asset'
and 'subset'.

Output will contain version by each instance id.

Args:
instances (list[CreatedInstance]): Instances for which to get next
versions.

Returns:
Dict[str, int]: Next versions by instance id.
"""

return get_next_versions_for_instances(
self.create_context.project_name, instances
)


class Creator(BaseCreator):
"""Creator that has more information for artist to show in UI.
Expand Down
122 changes: 122 additions & 0 deletions openpype/pipeline/create/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import collections

from openpype.client import get_assets, get_subsets, get_last_versions


def get_last_versions_for_instances(
project_name, instances, use_value_for_missing=False
):
"""Get last versions for instances by their asset and subset name.

Args:
project_name (str): Project name.
instances (list[CreatedInstance]): Instances to get next versions for.
use_value_for_missing (Optional[bool]): Missing values are replaced
with negative value if True. Otherwise None is used. -2 is used
for instances without filled asset or subset name. -1 is used
for missing entities.

Returns:
dict[str, Union[int, None]]: Last versions by instance id.
"""

output = {
instance.id: -1 if use_value_for_missing else None
for instance in instances
}
subset_names_by_asset_name = collections.defaultdict(set)
instances_by_hierarchy = {}
for instance in instances:
asset_name = instance.data.get("asset")
subset_name = instance.subset_name
if not asset_name or not subset_name:
if use_value_for_missing:
output[instance.id] = -2
continue

(
instances_by_hierarchy
.setdefault(asset_name, {})
.setdefault(subset_name, [])
.append(instance)
)
subset_names_by_asset_name[asset_name].add(subset_name)

subset_names = set()
for names in subset_names_by_asset_name.values():
subset_names |= names

if not subset_names:
return output

asset_docs = get_assets(
project_name,
asset_names=subset_names_by_asset_name.keys(),
fields=["name", "_id"]
)
asset_names_by_id = {
asset_doc["_id"]: asset_doc["name"]
for asset_doc in asset_docs
}
if not asset_names_by_id:
return output

subset_docs = get_subsets(
project_name,
asset_ids=asset_names_by_id.keys(),
subset_names=subset_names,
fields=["_id", "name", "parent"]
)
subset_docs_by_id = {}
for subset_doc in subset_docs:
# Filter subset docs by subset names under parent
asset_id = subset_doc["parent"]
asset_name = asset_names_by_id[asset_id]
subset_name = subset_doc["name"]
if subset_name not in subset_names_by_asset_name[asset_name]:
continue
subset_docs_by_id[subset_doc["_id"]] = subset_doc

if not subset_docs_by_id:
return output

last_versions_by_subset_id = get_last_versions(
project_name,
subset_docs_by_id.keys(),
fields=["name", "parent"]
)
for subset_id, version_doc in last_versions_by_subset_id.items():
subset_doc = subset_docs_by_id[subset_id]
asset_id = subset_doc["parent"]
asset_name = asset_names_by_id[asset_id]
_instances = instances_by_hierarchy[asset_name][subset_doc["name"]]
for instance in _instances:
output[instance.id] = version_doc["name"]

return output


def get_next_versions_for_instances(project_name, instances):
"""Get next versions for instances by their asset and subset name.

Args:
project_name (str): Project name.
instances (list[CreatedInstance]): Instances to get next versions for.

Returns:
dict[str, Union[int, None]]: Next versions by instance id. Version is
'None' if instance has no asset or subset name.
"""

last_versions = get_last_versions_for_instances(
project_name, instances, True)

output = {}
for instance_id, version in last_versions.items():
if version == -2:
output[instance_id] = None
elif version == -1:
output[instance_id] = 1
else:
output[instance_id] = version + 1
return output