From 3b2dc131f9a3dd2bca014b24ce4ec94e614547a8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Feb 2024 15:44:18 +0100 Subject: [PATCH] modified remaining base of create pipeline api to use product name and type --- .../pipeline/create/creator_plugins.py | 54 ++++++++--------- .../pipeline/create/legacy_create.py | 44 +++++++------- client/ayon_core/pipeline/create/utils.py | 58 +++++++++---------- .../tools/push_to_project/control.py | 4 +- 4 files changed, 80 insertions(+), 80 deletions(-) diff --git a/client/ayon_core/pipeline/create/creator_plugins.py b/client/ayon_core/pipeline/create/creator_plugins.py index 9e39409f0c..21d4371dc3 100644 --- a/client/ayon_core/pipeline/create/creator_plugins.py +++ b/client/ayon_core/pipeline/create/creator_plugins.py @@ -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 diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index df0c942ffd..cf78f5b061 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -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 diff --git a/client/ayon_core/pipeline/create/utils.py b/client/ayon_core/pipeline/create/utils.py index c2655f319f..44063bd9ac 100644 --- a/client/ayon_core/pipeline/create/utils.py +++ b/client/ayon_core/pipeline/create/utils.py @@ -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( diff --git a/client/ayon_core/tools/push_to_project/control.py b/client/ayon_core/tools/push_to_project/control.py index 1336721e5a..b3a5382343 100644 --- a/client/ayon_core/tools/push_to_project/control.py +++ b/client/ayon_core/tools/push_to_project/control.py @@ -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,