modified remaining base of create pipeline api to use product name and type

This commit is contained in:
Jakub Trllo 2024-02-21 15:44:18 +01:00
parent 6cff87d7a6
commit 3b2dc131f9
4 changed files with 80 additions and 80 deletions

View file

@ -179,7 +179,7 @@ class BaseCreator:
# Creator is enabled (Probably does not have reason of existence?)
enabled = True
# Creator (and family) icon
# Creator (and product type) icon
# - may not be used if `get_icon` is reimplemented
icon = None
@ -329,14 +329,14 @@ class BaseCreator:
def identifier(self):
"""Identifier of creator (must be unique).
Default implementation returns plugin's family.
Default implementation returns plugin's product type.
"""
return self.family
return self.product_type
@property
@abstractmethod
def family(self):
def product_type(self):
"""Family that plugin represents."""
pass
@ -370,7 +370,7 @@ class BaseCreator:
Default implementation use attributes in this order:
- 'group_label' -> 'label' -> 'identifier'
Keep in mind that 'identifier' use 'family' by default.
Keep in mind that 'identifier' use 'product_type' by default.
Returns:
str: Group label that can be used for grouping of instances in UI.
@ -489,7 +489,7 @@ class BaseCreator:
pass
def get_icon(self):
"""Icon of creator (family).
"""Icon of creator (product type).
Can return path to image file or awesome icon name.
"""
@ -499,7 +499,7 @@ class BaseCreator:
def get_dynamic_data(
self, variant, task_name, asset_doc, project_name, host_name, instance
):
"""Dynamic data for subset name filling.
"""Dynamic data for product name filling.
These may be get dynamically created based on current context of
workfile.
@ -516,7 +516,7 @@ class BaseCreator:
host_name=None,
instance=None
):
"""Return subset name for passed context.
"""Return product name for passed context.
CHANGES:
Argument `asset_id` was replaced with `asset_doc`. It is easier to
@ -526,19 +526,19 @@ class BaseCreator:
NOTE:
Asset document is not used yet but is required if would like to use
task type in subset templates.
task type in product templates.
Method is also called on subset name update. In that case origin
Method is also called on product name update. In that case origin
instance is passed in.
Args:
variant(str): Subset name variant. In most of cases user input.
task_name(str): For which task subset is created.
asset_doc(dict): Asset document for which subset is created.
task_name(str): For which task product is created.
asset_doc(dict): Asset document for which product is created.
project_name(str): Project name.
host_name(str): Which host creates subset.
host_name(str): Which host creates product.
instance(CreatedInstance|None): Object of 'CreatedInstance' for
which is subset name updated. Passed only on subset name
which is product name updated. Passed only on product name
update.
"""
@ -551,7 +551,7 @@ class BaseCreator:
asset_doc,
task_name,
host_name,
self.family,
self.product_type,
variant,
dynamic_data=dynamic_data,
project_settings=self.project_settings
@ -599,8 +599,8 @@ class BaseCreator:
"""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'.
It is using context information on instance to receive them,
'folderPath' and 'product'.
Output will contain version by each instance id.
@ -620,7 +620,7 @@ class BaseCreator:
class Creator(BaseCreator):
"""Creator that has more information for artist to show in UI.
Creation requires prepared subset name and instance data.
Creation requires prepared product name and instance data.
"""
# GUI Purposes
@ -630,11 +630,11 @@ class Creator(BaseCreator):
# Default variant used in 'get_default_variant'
_default_variant = None
# Short description of family
# Short description of product type
# - may not be used if `get_description` is overriden
description = None
# Detailed description of family for artists
# Detailed description of product type for artists
# - may not be used if `get_detail_description` is overriden
detailed_description = None
@ -681,39 +681,39 @@ class Creator(BaseCreator):
return self.order
@abstractmethod
def create(self, subset_name, instance_data, pre_create_data):
def create(self, product_name, instance_data, pre_create_data):
"""Create new instance and store it.
Ideally should be stored to workfile using host implementation.
Args:
subset_name(str): Subset name of created instance.
product_name(str): Subset name of created instance.
instance_data(dict): Base data for instance.
pre_create_data(dict): Data based on pre creation attributes.
Those may affect how creator works.
"""
# instance = CreatedInstance(
# self.family, subset_name, instance_data
# self.product_type, product_name, instance_data
# )
pass
def get_description(self):
"""Short description of family and plugin.
"""Short description of product type and plugin.
Returns:
str: Short description of family.
str: Short description of product type.
"""
return self.description
def get_detail_description(self):
"""Description of family and plugin.
"""Description of product type and plugin.
Can be detailed with markdown or html tags.
Returns:
str: Detailed description of family for artist.
str: Detailed description of product type for artist.
"""
return self.detailed_description

View file

@ -18,12 +18,12 @@ from .product_name import get_product_name
class LegacyCreator(object):
"""Determine how assets are created"""
label = None
family = None
product_type = None
defaults = None
maintain_selection = True
enabled = True
dynamic_subset_keys = []
dynamic_product_name_keys = []
log = logging.getLogger("LegacyCreator")
log.propagate = True
@ -36,9 +36,9 @@ class LegacyCreator(object):
self.data = collections.OrderedDict()
# TODO use 'AYON_INSTANCE_ID' when all hosts support it
self.data["id"] = AVALON_INSTANCE_ID
self.data["family"] = self.family
self.data["productType"] = self.product_type
self.data["folderPath"] = folder_path
self.data["subset"] = name
self.data["productName"] = name
self.data["active"] = True
self.data.update(data or {})
@ -93,19 +93,19 @@ class LegacyCreator(object):
):
"""Return dynamic data for current Creator plugin.
By default return keys from `dynamic_subset_keys` attribute as mapping
to keep formatted template unchanged.
By default return keys from `dynamic_product_name_keys` attribute
as mapping to keep formatted template unchanged.
```
dynamic_subset_keys = ["my_key"]
dynamic_product_name_keys = ["my_key"]
---
output = {
"my_key": "{my_key}"
}
```
Dynamic keys may override default Creator keys (family, task, asset,
...) but do it wisely if you need.
Dynamic keys may override default Creator keys (productType, task,
folderPath, ...) but do it wisely if you need.
All of keys will be converted into 3 variants unchanged, capitalized
and all upper letters. Because of that are all keys lowered.
@ -114,10 +114,10 @@ class LegacyCreator(object):
is class method.
Returns:
dict: Fill data for subset name template.
dict: Fill data for product name template.
"""
dynamic_data = {}
for key in cls.dynamic_subset_keys:
for key in cls.dynamic_product_name_keys:
key = key.lower()
dynamic_data[key] = "{" + key + "}"
return dynamic_data
@ -126,14 +126,14 @@ class LegacyCreator(object):
def get_product_name(
cls, variant, task_name, asset_id, project_name, host_name=None
):
"""Return subset name created with entered arguments.
"""Return product name created with entered arguments.
Logic extracted from Creator tool. This method should give ability
to get subset name without the tool.
to get product name without the tool.
TODO: Maybe change `variant` variable.
By default is output concatenated family with user text.
By default is output concatenated product type with variant.
Args:
variant (str): What is entered by user in creator tool.
@ -143,7 +143,7 @@ class LegacyCreator(object):
host_name (str): Name of host.
Returns:
str: Formatted subset name with entered arguments. Should match
str: Formatted product name with entered arguments. Should match
config's logic.
"""
@ -160,7 +160,7 @@ class LegacyCreator(object):
asset_doc,
task_name,
host_name,
cls.family,
cls.product_type,
variant,
dynamic_data=dynamic_data
)
@ -169,23 +169,23 @@ class LegacyCreator(object):
def legacy_create(Creator, name, asset, options=None, data=None):
"""Create a new instance
Associate nodes with a subset and family. These nodes are later
validated, according to their `family`, and integrated into the
shared environment, relative their `subset`.
Associate nodes with a product name and type. These nodes are later
validated, according to their `product type`, and integrated into the
shared environment, relative their `productName`.
Data relative each family, along with default data, are imprinted
Data relative each product type, along with default data, are imprinted
into the resulting objectSet. This data is later used by extractors
and finally asset browsers to help identify the origin of the asset.
Arguments:
Creator (Creator): Class of creator
name (str): Name of subset
name (str): Name of product
asset (str): Name of asset
options (dict, optional): Additional options from GUI
data (dict, optional): Additional data from GUI
Raises:
NameError on `subset` already exists
NameError on `productName` already exists
KeyError on invalid dynamic property
RuntimeError on host error

View file

@ -11,14 +11,14 @@ from ayon_core.client import (
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.
"""Get last versions for instances by their folder path and product 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 instances without filled folder or product name. -1 is used
for missing entities.
Returns:
@ -29,72 +29,72 @@ def get_last_versions_for_instances(
instance.id: -1 if use_value_for_missing else None
for instance in instances
}
subset_names_by_asset_name = collections.defaultdict(set)
product_names_by_folder_path = collections.defaultdict(set)
instances_by_hierarchy = {}
for instance in instances:
asset_name = instance.data.get("folderPath")
subset_name = instance.subset_name
if not asset_name or not subset_name:
folder_path = instance.data.get("folderPath")
product_name = instance.product_name
if not folder_path or not product_name:
if use_value_for_missing:
output[instance.id] = -2
continue
(
instances_by_hierarchy
.setdefault(asset_name, {})
.setdefault(subset_name, [])
.setdefault(folder_path, {})
.setdefault(product_name, [])
.append(instance)
)
subset_names_by_asset_name[asset_name].add(subset_name)
product_names_by_folder_path[folder_path].add(product_name)
subset_names = set()
for names in subset_names_by_asset_name.values():
subset_names |= names
product_names = set()
for names in product_names_by_folder_path.values():
product_names |= names
if not subset_names:
if not product_names:
return output
asset_docs = get_assets(
project_name,
asset_names=subset_names_by_asset_name.keys(),
asset_names=product_names_by_folder_path.keys(),
fields=["name", "_id", "data.parents"]
)
asset_names_by_id = {
folder_paths_by_id = {
asset_doc["_id"]: get_asset_name_identifier(asset_doc)
for asset_doc in asset_docs
}
if not asset_names_by_id:
if not folder_paths_by_id:
return output
subset_docs = get_subsets(
project_name,
asset_ids=asset_names_by_id.keys(),
subset_names=subset_names,
asset_ids=folder_paths_by_id.keys(),
subset_names=product_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]:
folder_id = subset_doc["parent"]
folder_path = folder_paths_by_id[folder_id]
product_name = subset_doc["name"]
if product_name not in product_names_by_folder_path[folder_path]:
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(
last_versions_by_product_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():
for subset_id, version_doc in last_versions_by_product_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"]]
folder_id = subset_doc["parent"]
folder_path = folder_paths_by_id[folder_id]
_instances = instances_by_hierarchy[folder_path][subset_doc["name"]]
for instance in _instances:
output[instance.id] = version_doc["name"]
@ -102,7 +102,7 @@ def get_last_versions_for_instances(
def get_next_versions_for_instances(project_name, instances):
"""Get next versions for instances by their asset and subset name.
"""Get next versions for instances by their folder path and product name.
Args:
project_name (str): Project name.
@ -110,7 +110,7 @@ def get_next_versions_for_instances(project_name, instances):
Returns:
dict[str, Union[int, None]]: Next versions by instance id. Version is
'None' if instance has no asset or subset name.
'None' if instance has no folder path or product name.
"""
last_versions = get_last_versions_for_instances(

View file

@ -9,7 +9,7 @@ from ayon_core.client import (
from ayon_core.settings import get_project_settings
from ayon_core.lib import prepare_template_data
from ayon_core.lib.events import QueuedEventSystem
from ayon_core.pipeline.create import get_subset_name_template
from ayon_core.pipeline.create import get_product_name_template
from ayon_core.tools.ayon_utils.models import ProjectsModel, HierarchyModel
from .models import (
@ -259,7 +259,7 @@ class PushToContextController:
family = subset_doc["data"].get("family")
if not family:
family = subset_doc["data"]["families"][0]
template = get_subset_name_template(
template = get_product_name_template(
self._src_project_name,
family,
task_name,