From fe60155d96168c1e9685255deb8707a595c48a49 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Fri, 28 Jun 2019 13:29:49 +0100 Subject: [PATCH] Tagging assetbuilds. --- pype/nukestudio/tags.py | 6 +- .../publish/integrate_hierarchy_ftrack.py | 34 ++++++++++- .../publish/integrate_hierarchy_avalon.py | 8 ++- .../nukestudio/publish/collect_assets.py | 59 +++++++++++++++++++ .../nukestudio/publish/collect_handles.py | 11 +++- .../publish/collect_hierarchy_context.py | 25 +++++--- .../nukestudio/publish/collect_shot.py | 4 +- 7 files changed, 128 insertions(+), 19 deletions(-) create mode 100644 pype/plugins/nukestudio/publish/collect_assets.py diff --git a/pype/nukestudio/tags.py b/pype/nukestudio/tags.py index 7fec8ae33a..d10fa60ba4 100644 --- a/pype/nukestudio/tags.py +++ b/pype/nukestudio/tags.py @@ -79,17 +79,17 @@ def add_tags_from_presets(): # Get project assets. Currently Ftrack specific to differentiate between # asset builds and shots. - nks_pres_tags["[Assets]"] = {} + nks_pres_tags["[AssetBuilds]"] = {} for asset in io.find({"type": "asset"}): if asset["data"]["entityType"] == "AssetBuild": - nks_pres_tags["[Assets]"][asset["name"]] = { + nks_pres_tags["[AssetBuilds]"][asset["name"]] = { "editable": "1", "note": "", "icon": { "path": "icons:TagActor.png" }, "metadata": { - "family": "asset" + "family": "assetbuild" } } diff --git a/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py b/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py index 69788756cf..5f0516c593 100644 --- a/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py +++ b/pype/plugins/ftrack/publish/integrate_hierarchy_ftrack.py @@ -1,4 +1,5 @@ import pyblish.api +from avalon import io class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): @@ -35,6 +36,9 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): if "hierarchyContext" not in context.data: return + if not io.Session: + io.install() + self.ft_project = None self.session = context.data["ftrackSession"] @@ -81,10 +85,13 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): # CUSTOM ATTRIBUTES custom_attributes = entity_data.get('custom_attributes', []) instances = [ - i for i in self.context[:] if i.data['asset'] in entity['name']] + i for i in self.context[:] if i.data['asset'] in entity['name'] + ] for key in custom_attributes: assert (key in entity['custom_attributes']), ( - 'Missing custom attribute key: `{0}` in attrs: `{1}`'.format(key, entity['custom_attributes'].keys())) + 'Missing custom attribute key: `{0}` in attrs: ' + '`{1}`'.format(key, entity['custom_attributes'].keys()) + ) entity['custom_attributes'][key] = custom_attributes[key] @@ -116,10 +123,33 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin): ) self.session.commit() + # Incoming links. + self.create_links(entity_data, entity) + self.session.commit() + if 'childs' in entity_data: self.import_to_ftrack( entity_data['childs'], entity) + def create_links(self, entity_data, entity): + # Clear existing links. + for link in entity.get("incoming_links", []): + self.session.delete(link) + self.session.commit() + + # Create new links. + for input in entity_data.get("inputs", []): + input_id = io.find_one({"_id": input})["data"]["ftrackId"] + assetbuild = self.session.get("AssetBuild", input_id) + self.log.debug( + "Creating link from {0} to {1}".format( + assetbuild["name"], entity["name"] + ) + ) + self.session.create( + "TypedContextLink", {"from": assetbuild, "to": entity} + ) + def get_all_task_types(self, project): tasks = {} proj_template = project['project_schema'] diff --git a/pype/plugins/global/publish/integrate_hierarchy_avalon.py b/pype/plugins/global/publish/integrate_hierarchy_avalon.py index 66a3825a1d..1962bda132 100644 --- a/pype/plugins/global/publish/integrate_hierarchy_avalon.py +++ b/pype/plugins/global/publish/integrate_hierarchy_avalon.py @@ -25,13 +25,15 @@ class IntegrateHierarchyToAvalon(pyblish.api.ContextPlugin): self.import_to_avalon(input_data) def import_to_avalon(self, input_data, parent=None): - for name in input_data: self.log.info('input_data[name]: {}'.format(input_data[name])) entity_data = input_data[name] entity_type = entity_data['entity_type'] data = {} + + data["inputs"] = entity_data.get("inputs", []) + # Process project if entity_type.lower() == 'project': entity = self.db.find_one({'type': 'project'}) @@ -73,7 +75,9 @@ class IntegrateHierarchyToAvalon(pyblish.api.ContextPlugin): data = input_data[name] if self.av_project['_id'] != parent['_id']: visualParent = parent['_id'] - parents.extend(parent.get('data', {}).get('parents', [])) + parents.extend( + parent.get('data', {}).get('parents', []) + ) parents.append(parent['name']) data['visualParent'] = visualParent data['parents'] = parents diff --git a/pype/plugins/nukestudio/publish/collect_assets.py b/pype/plugins/nukestudio/publish/collect_assets.py new file mode 100644 index 0000000000..b1db1b1bf2 --- /dev/null +++ b/pype/plugins/nukestudio/publish/collect_assets.py @@ -0,0 +1,59 @@ +from pyblish import api +from avalon import io + + +class CollectAssetBuilds(api.InstancePlugin): + """Collect asset from tags. + + Tag is expected to have name of the asset and metadata: + { + "family": "asset" + } + """ + + # Run just before CollectShot + order = api.CollectorOrder + 0.102 + label = "Collect AssetBuilds" + hosts = ["nukestudio"] + families = ["clip"] + + def process(self, instance): + # Exclude non-tagged instances. + tagged = False + asset_names = [] + for tag in instance.data["tags"]: + family = dict(tag["metadata"]).get("tag.family", "") + if family.lower() == "assetbuild": + asset_names.append(tag["name"]) + tagged = True + + if not tagged: + self.log.debug( + "Skipping \"{}\" because its not tagged with " + "\"assetbuild\"".format(instance) + ) + return + + # Collect asset builds. + data = {"assetBuilds": []} + for name in asset_names: + data["assetBuilds"].append( + instance.context.data["assetBuilds"][name] + ) + self.log.debug("Found asset builds: {}".format(data["assetBuilds"])) + + instance.data.update(data) + + +class CollectExistingAssetBuilds(api.ContextPlugin): + """Collect all asset builds from database.""" + + order = CollectAssetBuilds.order - 0.1 + label = "Collect Existing AssetBuilds" + hosts = ["nukestudio"] + + def process(self, context): + context.data["assetBuilds"] = {} + for asset in io.find({"type": "asset"}): + if asset["data"]["entityType"] == "AssetBuild": + context.data["assetBuilds"][asset["name"]] = asset diff --git a/pype/plugins/nukestudio/publish/collect_handles.py b/pype/plugins/nukestudio/publish/collect_handles.py index 2f2831237f..0aa339d039 100644 --- a/pype/plugins/nukestudio/publish/collect_handles.py +++ b/pype/plugins/nukestudio/publish/collect_handles.py @@ -8,7 +8,6 @@ class CollectClipHandles(api.ContextPlugin): order = api.CollectorOrder + 0.1025 label = "Collect Handles" hosts = ["nukestudio"] - families = ['clip'] def process(self, context): assets_shared = context.data.get("assetsShared") @@ -16,7 +15,15 @@ class CollectClipHandles(api.ContextPlugin): # find all main types instances and add its handles to asset shared instances = context[:] + filtered_instances = [] for instance in instances: + families = instance.data.get("families", []) + families += [instance.data["family"]] + if "clip" in families: + filtered_instances.append(instance) + else: + continue + # get handles handles = int(instance.data["handles"]) handle_start = int(instance.data["handleStart"]) @@ -33,7 +40,7 @@ class CollectClipHandles(api.ContextPlugin): "handleEnd": handle_end }) - for instance in instances: + for instance in filtered_instances: if not instance.data.get("main"): self.log.debug("Synchronize handles on: `{}`".format( instance.data["name"])) diff --git a/pype/plugins/nukestudio/publish/collect_hierarchy_context.py b/pype/plugins/nukestudio/publish/collect_hierarchy_context.py index 459a8ed002..ba9fe118da 100644 --- a/pype/plugins/nukestudio/publish/collect_hierarchy_context.py +++ b/pype/plugins/nukestudio/publish/collect_hierarchy_context.py @@ -43,7 +43,9 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): # build data for inner nukestudio project property data = { - "sequence": context.data['activeSequence'].name().replace(' ', '_'), + "sequence": ( + context.data['activeSequence'].name().replace(' ', '_') + ), "track": clip.parent().name().replace(' ', '_'), "clip": asset } @@ -110,7 +112,10 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): # create new shot asset name instance.data["asset"] = instance.data["asset"].format( **d_metadata) - self.log.debug("__ instance.data[asset]: {}".format(instance.data["asset"])) + self.log.debug( + "__ instance.data[asset]: " + "{}".format(instance.data["asset"]) + ) # lastly fill those individual properties itno # format the string with collected data @@ -126,8 +131,10 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin): # check if hierarchy attribute is already created # it should not be so return warning if it is hd = instance.data.get("hierarchy") - assert not hd, "Only one Hierarchy Tag is \ - allowed. Clip: `{}`".format(asset) + assert not hd, ( + "Only one Hierarchy Tag is allowed. " + "Clip: `{}`".format(asset) + ) assetsShared = { asset: { @@ -179,11 +186,6 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin): handle_start = int(instance.data["handleStart"] + handles) handle_end = int(instance.data["handleEnd"] + handles) - # get source frames - source_first = int(instance.data["sourceFirst"]) - source_in = int(instance.data["sourceIn"]) - source_out = int(instance.data["sourceOut"]) - instance.data['startFrame'] = ( instance.data["item"].timelineIn() - handle_start ) @@ -217,6 +219,11 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin): ) in_info = {} + + in_info["inputs"] = [ + x["_id"] for x in instance.data["assetBuilds"] + ] + # suppose that all instances are Shots in_info['entity_type'] = 'Shot' diff --git a/pype/plugins/nukestudio/publish/collect_shot.py b/pype/plugins/nukestudio/publish/collect_shot.py index 35aa926541..33e6a7ee7e 100644 --- a/pype/plugins/nukestudio/publish/collect_shot.py +++ b/pype/plugins/nukestudio/publish/collect_shot.py @@ -34,7 +34,9 @@ class CollectShot(api.InstancePlugin): data["families"] = [] data["frameStart"] = 1 - data["label"] += " - tasks: {}".format(data["tasks"]) + data["label"] += " - tasks: {} - assetbuilds: {}".format( + data["tasks"], [x["name"] for x in data["assetBuilds"]] + ) # Get handles. data["handleStart"] = instance.data["handleStart"] + data["handles"]