# -*- coding: utf-8 -*- """Extract template.""" import os import shutil import pype.api from avalon import harmony import pype.hosts.harmony class ExtractTemplate(pype.api.Extractor): """Extract the connected nodes to the composite instance.""" label = "Extract Template" hosts = ["harmony"] families = ["harmony.template"] def process(self, instance): """Plugin entry point.""" staging_dir = self.staging_dir(instance) filepath = os.path.join(staging_dir, f"{instance.name}.tpl") self.log.info(f"Outputting template to {staging_dir}") dependencies = [] self.get_dependencies(instance[0], dependencies) # Get backdrops. backdrops = {} for dependency in dependencies: for backdrop in self.get_backdrops(dependency): backdrops[backdrop["title"]["text"]] = backdrop unique_backdrops = [backdrops[x] for x in set(backdrops.keys())] if not unique_backdrops: self.log.error(("No backdrops detected for template. " "Please move template instance node onto " "some backdrop and try again.")) raise AssertionError("No backdrop detected") # Get non-connected nodes within backdrops. all_nodes = instance.context.data.get("allNodes") for node in [x for x in all_nodes if x not in dependencies]: within_unique_backdrops = bool( [x for x in self.get_backdrops(node) if x in unique_backdrops] ) if within_unique_backdrops: dependencies.append(node) # Make sure we dont export the instance node. if instance[0] in dependencies: dependencies.remove(instance[0]) # Export template. pype.hosts.harmony.export_template( unique_backdrops, dependencies, filepath ) # Prep representation. os.chdir(staging_dir) shutil.make_archive( f"{instance.name}", "zip", os.path.join(staging_dir, f"{instance.name}.tpl") ) representation = { "name": "tpl", "ext": "zip", "files": f"{instance.name}.zip", "stagingDir": staging_dir } self.log.info(instance.data.get("representations")) if instance.data.get("representations"): instance.data["representations"].extend([representation]) else: instance.data["representations"] = [representation] instance.data["version_name"] = "{}_{}".format( instance.data["subset"], os.environ["AVALON_TASK"]) def get_backdrops(self, node: str) -> list: """Get backdrops for the node. Args: node (str): Node path. Returns: list: list of Backdrops. """ self_name = self.__class__.__name__ return harmony.send({ "function": f"PypeHarmony.Publish.{self_name}.getBackdropsByNode", "args": node})["result"] def get_dependencies( self, node: str, dependencies: list = None) -> list: """Get node dependencies. This will return recursive dependency list of given node. Args: node (str): Path to the node. dependencies (list, optional): existing dependency list. Returns: list: List of dependent nodes. """ current_dependencies = harmony.send( { "function": "PypeHarmony.getDependencies", "args": node} )["result"] for dependency in current_dependencies: if not dependency: continue if dependency in dependencies: continue dependencies.append(dependency) self.get_dependencies(dependency, dependencies)