diff --git a/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py b/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py index abe670b691..a7eef0fce4 100644 --- a/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py +++ b/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py @@ -18,7 +18,7 @@ class CollectRenderPath(pyblish.api.InstancePlugin): def process(self, instance): anatomy = instance.context.data["anatomy"] anatomy_data = copy.deepcopy(instance.data["anatomyData"]) - padding = anatomy.templates.get("frame_padding", 4) + padding = anatomy.templates_obj.frame_padding product_type = "render" anatomy_data.update({ "frame": f"%0{padding}d", @@ -28,15 +28,14 @@ class CollectRenderPath(pyblish.api.InstancePlugin): }) anatomy_data["product"]["type"] = product_type - anatomy_filled = anatomy.format(anatomy_data) - # get anatomy rendering keys r_anatomy_key = self.anatomy_template_key_render_files m_anatomy_key = self.anatomy_template_key_metadata # get folder and path for rendering images from celaction - render_dir = anatomy_filled[r_anatomy_key]["folder"] - render_path = anatomy_filled[r_anatomy_key]["path"] + r_template_item = anatomy.get_template("publish", r_anatomy_key) + render_dir = r_template_item["directory"].format_strict(anatomy_data) + render_path = r_template_item["path"].format_strict(anatomy_data) self.log.debug("__ render_path: `{}`".format(render_path)) # create dir if it doesnt exists @@ -51,11 +50,12 @@ class CollectRenderPath(pyblish.api.InstancePlugin): instance.data["path"] = render_path # get anatomy for published renders folder path - if anatomy_filled.get(m_anatomy_key): - instance.data["publishRenderMetadataFolder"] = anatomy_filled[ - m_anatomy_key]["folder"] - self.log.info("Metadata render path: `{}`".format( - instance.data["publishRenderMetadataFolder"] - )) + m_template_item = anatomy.get_template("publish", m_anatomy_key) + if m_template_item is not None: + metadata_path = m_template_item["directory"].format_strict( + anatomy_data + ) + instance.data["publishRenderMetadataFolder"] = metadata_path + self.log.info("Metadata render path: `{}`".format(metadata_path)) self.log.info(f"Render output path set to: `{render_path}`") diff --git a/client/ayon_core/hosts/fusion/api/plugin.py b/client/ayon_core/hosts/fusion/api/plugin.py index f63b5eaec3..492841f967 100644 --- a/client/ayon_core/hosts/fusion/api/plugin.py +++ b/client/ayon_core/hosts/fusion/api/plugin.py @@ -133,7 +133,7 @@ class GenericCreateSaver(Creator): formatting_data = deepcopy(data) # get frame padding from anatomy templates - frame_padding = self.project_anatomy.templates["frame_padding"] + frame_padding = self.project_anatomy.templates_obj.frame_padding # get output format ext = data["creator_attributes"]["image_format"] diff --git a/client/ayon_core/hosts/hiero/api/lib.py b/client/ayon_core/hosts/hiero/api/lib.py index c46269b532..666119593a 100644 --- a/client/ayon_core/hosts/hiero/api/lib.py +++ b/client/ayon_core/hosts/hiero/api/lib.py @@ -632,7 +632,7 @@ def sync_avalon_data_to_workfile(): project_name = get_current_project_name() anatomy = Anatomy(project_name) - work_template = anatomy.templates["work"]["path"] + work_template = anatomy.get_template("work", "default", "path") work_root = anatomy.root_value_for_template(work_template) active_project_root = ( os.path.join(work_root, project_name) @@ -825,7 +825,7 @@ class PublishAction(QtWidgets.QAction): # root_node = hiero.core.nuke.RootNode() # # anatomy = Anatomy(get_current_project_name()) -# work_template = anatomy.templates["work"]["path"] +# work_template = anatomy.get_template("work", "default", "path") # root_path = anatomy.root_value_for_template(work_template) # # nuke_script.addNode(root_node) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_workfile_xgen.py b/client/ayon_core/hosts/maya/plugins/publish/extract_workfile_xgen.py index 9aaba532b2..a0328725ca 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_workfile_xgen.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_workfile_xgen.py @@ -128,9 +128,9 @@ class ExtractWorkfileXgen(publish.Extractor): alembic_files.append(alembic_file) template_data = copy.deepcopy(instance.data["anatomyData"]) - published_maya_path = StringTemplate( - instance.context.data["anatomy"].templates["publish"]["file"] - ).format(template_data) + anatomy = instance.context.data["anatomy"] + publish_template = anatomy.get_template("publish", "default", "file") + published_maya_path = publish_template.format(template_data) published_basename, _ = os.path.splitext(published_maya_path) for source in alembic_files: diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_xgen.py b/client/ayon_core/hosts/maya/plugins/publish/extract_xgen.py index ee864bd89b..eff4dcc881 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_xgen.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_xgen.py @@ -39,8 +39,9 @@ class ExtractXgen(publish.Extractor): # Get published xgen file name. template_data = copy.deepcopy(instance.data["anatomyData"]) template_data.update({"ext": "xgen"}) - templates = instance.context.data["anatomy"].templates["publish"] - xgen_filename = StringTemplate(templates["file"]).format(template_data) + anatomy = instance.context.data["anatomy"] + file_template = anatomy.get_template("publish", "default", "file") + xgen_filename = file_template.format(template_data) xgen_path = os.path.join( self.staging_dir(instance), xgen_filename diff --git a/client/ayon_core/hosts/nuke/api/lib.py b/client/ayon_core/hosts/nuke/api/lib.py index 8e39475f10..1bb0ff79e0 100644 --- a/client/ayon_core/hosts/nuke/api/lib.py +++ b/client/ayon_core/hosts/nuke/api/lib.py @@ -982,26 +982,18 @@ def format_anatomy(data): project_name = get_current_project_name() anatomy = Anatomy(project_name) - log.debug("__ anatomy.templates: {}".format(anatomy.templates)) - padding = None - if "frame_padding" in anatomy.templates.keys(): - padding = int(anatomy.templates["frame_padding"]) - elif "render" in anatomy.templates.keys(): - padding = int( - anatomy.templates["render"].get( - "frame_padding" - ) - ) + frame_padding = anatomy.templates_obj.frame_padding - version = data.get("version", None) - if not version: + version = data.get("version") + if version is None: file = script_name() data["version"] = get_version_from_path(file) folder_path = data["folderPath"] task_name = data["task"] host_name = get_current_host_name() + context_data = get_template_data_with_names( project_name, folder_path, task_name, host_name ) @@ -1013,7 +1005,7 @@ def format_anatomy(data): "name": data["productName"], "type": data["productType"], }, - "frame": "#" * padding, + "frame": "#" * frame_padding, }) return anatomy.format(data) @@ -1171,7 +1163,9 @@ def create_write_node( anatomy_filled = format_anatomy(data) # build file path to workfiles - fdir = str(anatomy_filled["work"]["folder"]).replace("\\", "/") + fdir = str( + anatomy_filled["work"]["default"]["directory"] + ).replace("\\", "/") data["work"] = fdir fpath = StringTemplate(data["fpath_template"]).format_strict(data) diff --git a/client/ayon_core/hosts/nuke/startup/custom_write_node.py b/client/ayon_core/hosts/nuke/startup/custom_write_node.py index 075c8e7a17..098c3da3a8 100644 --- a/client/ayon_core/hosts/nuke/startup/custom_write_node.py +++ b/client/ayon_core/hosts/nuke/startup/custom_write_node.py @@ -2,7 +2,7 @@ import os import nuke import nukescripts -from ayon_core.pipeline import Anatomy +from ayon_core.pipeline import Anatomy, get_current_project_name from ayon_core.hosts.nuke.api.lib import ( set_node_knobs_from_settings, get_nuke_imageio_settings @@ -102,13 +102,9 @@ class WriteNodeKnobSettingPanel(nukescripts.PythonPanel): for knob in ext_knob_list: ext = knob["value"] - anatomy = Anatomy() + anatomy = Anatomy(get_current_project_name()) - frame_padding = int( - anatomy.templates["render"].get( - "frame_padding" - ) - ) + frame_padding = anatomy.templates_obj.frame_padding for write_node in write_selected_nodes: # data for mapping the path # TODO add more fill data diff --git a/client/ayon_core/hosts/photoshop/api/launch_logic.py b/client/ayon_core/hosts/photoshop/api/launch_logic.py index 17fe7d5920..ccb7b0048b 100644 --- a/client/ayon_core/hosts/photoshop/api/launch_logic.py +++ b/client/ayon_core/hosts/photoshop/api/launch_logic.py @@ -392,17 +392,14 @@ class PhotoshopRoute(WebSocketRoute): ) data["root"] = anatomy.roots - file_template = anatomy.templates[template_key]["file"] + work_template = anatomy.get_template("work", template_key) # Define saving file extension extensions = host.get_workfile_extensions() - folder_template = anatomy.templates[template_key]["folder"] - work_root = StringTemplate.format_strict_template( - folder_template, data - ) + work_root = work_template["directory"].format_strict(data) last_workfile_path = get_last_workfile( - work_root, file_template, data, extensions, True + work_root, work_template["file"], data, extensions, True ) return last_workfile_path diff --git a/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py b/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py index 4bb34089bd..16cb54f4a3 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py +++ b/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py @@ -80,7 +80,7 @@ class LoadWorkfile(plugin.Loader): ) data["root"] = anatomy.roots - file_template = anatomy.templates[template_key]["file"] + work_template = anatomy.get_template("work", template_key) # Define saving file extension extensions = host.get_workfile_extensions() @@ -91,14 +91,11 @@ class LoadWorkfile(plugin.Loader): # Fall back to the first extension supported for this host. extension = extensions[0] - data["ext"] = extension + data["ext"] = extension.lstrip(".") - folder_template = anatomy.templates[template_key]["folder"] - work_root = StringTemplate.format_strict_template( - folder_template, data - ) + work_root = work_template["directory"].format_strict(data) version = get_last_workfile_with_version( - work_root, file_template, data, extensions + work_root, work_template["file"], data, extensions )[1] if version is None: diff --git a/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py b/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py index 2f78bf026d..040beccb5e 100644 --- a/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py +++ b/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py @@ -66,7 +66,9 @@ class UnrealPrelaunchHook(PreLaunchHook): self.host_name, ) # Fill templates - template_obj = anatomy.templates_obj[workfile_template_key]["file"] + template_obj = anatomy.get_template( + "work", workfile_template_key, "file" + ) # Return filename return template_obj.format_strict(workdir_data) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 4bf0c31d93..c4f1d168b5 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1862,7 +1862,7 @@ def _prepare_last_workfile(data, workdir, addons_manager): project_settings=project_settings ) # Find last workfile - file_template = str(anatomy.templates[template_key]["file"]) + file_template = anatomy.get_template("work", template_key, "file") workdir_data.update({ "version": 1, diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_celaction_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_celaction_deadline.py index bc3636da63..e11b74ae81 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -74,6 +74,8 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): render_path = os.path.normpath(render_path) script_name = os.path.basename(script_path) + anatomy = instance.context.data["anatomy"] + publish_template = anatomy.get_template("publish", "default", "path") for item in instance.context: if "workfile" in item.data["productType"]: msg = "Workfile (scene) must be published along" @@ -84,9 +86,9 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): template_data["representation"] = rep template_data["ext"] = rep template_data["comment"] = None - anatomy_filled = instance.context.data["anatomy"].format( - template_data) - template_filled = anatomy_filled["publish"]["path"] + template_filled = publish_template.format_strict( + template_data + ) script_path = os.path.normpath(template_filled) self.log.info( diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py index 837ed91c60..f99a7c6ba3 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py @@ -123,6 +123,8 @@ class FusionSubmitDeadline( script_path = context.data["currentFile"] + anatomy = instance.context.data["anatomy"] + publish_template = anatomy.get_template("publish", "default", "path") for item in context: if "workfile" in item.data["families"]: msg = "Workfile (scene) must be published along" @@ -133,8 +135,9 @@ class FusionSubmitDeadline( template_data["representation"] = rep template_data["ext"] = rep template_data["comment"] = None - anatomy_filled = context.data["anatomy"].format(template_data) - template_filled = anatomy_filled["publish"]["path"] + template_filled = publish_template.format_strict( + template_data + ) script_path = os.path.normpath(template_filled) self.log.info( diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py index a3111454b3..193cad1d24 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -196,6 +196,9 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, def _get_published_workfile_path(self, context): """This method is temporary while the class is not inherited from AbstractSubmitDeadline""" + anatomy = context.data["anatomy"] + # WARNING Hardcoded template name 'default' > may not be used + publish_template = anatomy.get_template("publish", "default", "path") for instance in context: if ( instance.data["productType"] != "workfile" @@ -216,11 +219,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, template_data["ext"] = ext template_data["comment"] = None - anatomy = context.data["anatomy"] - # WARNING Hardcoded template name 'publish' > may not be used - template_obj = anatomy.templates_obj["publish"]["path"] - - template_filled = template_obj.format(template_data) + template_filled = publish_template.format(template_data) script_path = os.path.normpath(template_filled) self.log.info( "Using published scene for render {}".format( diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py index 0561e0f65c..dbc5a12fa8 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -450,23 +450,10 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, "type": product_type, } - render_templates = anatomy.templates_obj[template_name] - if "folder" in render_templates: - publish_folder = render_templates["folder"].format_strict( - template_data - ) - else: - # solve deprecated situation when `folder` key is not underneath - # `publish` anatomy - self.log.warning(( - "Deprecation warning: Anatomy does not have set `folder`" - " key underneath `publish` (in global of for project `{}`)." - ).format(project_name)) - - file_path = render_templates["path"].format_strict(template_data) - publish_folder = os.path.dirname(file_path) - - return publish_folder + render_dir_template = anatomy.get_template( + "publish", template_name, "directory" + ) + return render_dir_template.format_strict(template_data) @classmethod def get_attribute_defs(cls): diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index 7a6abd5507..ce1c75e2ee 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -573,23 +573,10 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "type": product_type, } - render_templates = anatomy.templates_obj[template_name] - if "folder" in render_templates: - publish_folder = render_templates["folder"].format_strict( - template_data - ) - else: - # solve deprecated situation when `folder` key is not underneath - # `publish` anatomy - self.log.warning(( - "Deprecation warning: Anatomy does not have set `folder`" - " key underneath `publish` (in global of for project `{}`)." - ).format(project_name)) - - file_path = render_templates["path"].format_strict(template_data) - publish_folder = os.path.dirname(file_path) - - return publish_folder + render_dir_template = anatomy.get_template( + "publish", template_name, "directory" + ) + return render_dir_template.format_strict(template_data) @classmethod def get_attribute_defs(cls): diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 50c384bf88..bf21b43e0b 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -545,7 +545,7 @@ def get_workdir_from_session(session=None, template_key=None): ) anatomy = Anatomy(project_name) - template_obj = anatomy.templates_obj[template_key]["folder"] + template_obj = anatomy.get_template("work", template_key, "directory") path = template_obj.format_strict(template_data) if path: path = os.path.normpath(path) diff --git a/client/ayon_core/pipeline/delivery.py b/client/ayon_core/pipeline/delivery.py index d2b78422e3..666909ef8d 100644 --- a/client/ayon_core/pipeline/delivery.py +++ b/client/ayon_core/pipeline/delivery.py @@ -77,8 +77,8 @@ def check_destination_path( """ anatomy_data.update(datetime_data) - anatomy_filled = anatomy.format_all(anatomy_data) - dest_path = anatomy_filled["delivery"][template_name] + path_template = anatomy.get_template("delivery", template_name, "path") + dest_path = path_template.format(anatomy_data) report_items = collections.defaultdict(list) if not dest_path.solved: @@ -150,7 +150,7 @@ def deliver_single_file( if format_dict: anatomy_data = copy.deepcopy(anatomy_data) anatomy_data["root"] = format_dict["root"] - template_obj = anatomy.templates_obj["delivery"][template_name] + template_obj = anatomy.get_template("delivery", template_name, "path") delivery_path = template_obj.format_strict(anatomy_data) # Backwards compatibility when extension contained `.` @@ -220,8 +220,9 @@ def deliver_sequence( report_items["Source file was not found"].append(msg) return report_items, 0 - delivery_templates = anatomy.templates.get("delivery") or {} - delivery_template = delivery_templates.get(template_name) + delivery_template = anatomy.get_template( + "delivery", template_name, "path" + ) if delivery_template is None: msg = ( "Delivery template \"{}\" in anatomy of project \"{}\"" @@ -277,7 +278,7 @@ def deliver_sequence( anatomy_data["frame"] = frame_indicator if format_dict: anatomy_data["root"] = format_dict["root"] - template_obj = anatomy.templates_obj["delivery"][template_name] + template_obj = anatomy.get_template("delivery", template_name, "path") delivery_path = template_obj.format_strict(anatomy_data) delivery_path = os.path.normpath(delivery_path.replace("\\", "/")) diff --git a/client/ayon_core/pipeline/farm/tools.py b/client/ayon_core/pipeline/farm/tools.py index 8ab3b87ff6..1ed7e4b3f5 100644 --- a/client/ayon_core/pipeline/farm/tools.py +++ b/client/ayon_core/pipeline/farm/tools.py @@ -54,7 +54,7 @@ def from_published_scene(instance, replace_in_path=True): template_data["comment"] = None anatomy = instance.context.data['anatomy'] - template_obj = anatomy.templates_obj["publish"]["path"] + template_obj = anatomy.get_template("publish", "default", "path") template_filled = template_obj.format_strict(template_data) file_path = os.path.normpath(template_filled) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index b4ed69b5d7..8d2ae85694 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -742,29 +742,18 @@ def get_custom_staging_dir_info( anatomy = Anatomy(project_name) template_name = profile["template_name"] or TRANSIENT_DIR_TEMPLATE - _validate_transient_template(project_name, template_name, anatomy) - custom_staging_dir = anatomy.templates[template_name]["folder"] + custom_staging_dir = anatomy.get_template( + "staging", template_name, "directory" + ) + if custom_staging_dir is None: + raise ValueError(( + "Anatomy of project \"{}\" does not have set" + " \"{}\" template key!" + ).format(project_name, template_name)) is_persistent = profile["custom_staging_dir_persistent"] - return custom_staging_dir, is_persistent - - -def _validate_transient_template(project_name, template_name, anatomy): - """Check that transient template is correctly configured. - - Raises: - ValueError - if misconfigured template - """ - if template_name not in anatomy.templates: - raise ValueError(("Anatomy of project \"{}\" does not have set" - " \"{}\" template key!" - ).format(project_name, template_name)) - - if "folder" not in anatomy.templates[template_name]: - raise ValueError(("There is not set \"folder\" template in \"{}\" anatomy" # noqa - " for project \"{}\"." - ).format(template_name, project_name)) + return str(custom_staging_dir), is_persistent def get_published_workfile_instance(context): @@ -815,9 +804,9 @@ def replace_with_published_scene_path(instance, replace_in_path=True): template_data["ext"] = rep.get("ext") template_data["comment"] = None - anatomy = instance.context.data['anatomy'] - anatomy_filled = anatomy.format(template_data) - template_filled = anatomy_filled["publish"]["path"] + anatomy = instance.context.data["anatomy"] + template = anatomy.get_template("publish", "default", "path") + template_filled = template.format_strict(template_data) file_path = os.path.normpath(template_filled) log.info("Using published scene for render {}".format(file_path)) diff --git a/client/ayon_core/pipeline/usdlib.py b/client/ayon_core/pipeline/usdlib.py index dedcee6f99..9fabd1dce5 100644 --- a/client/ayon_core/pipeline/usdlib.py +++ b/client/ayon_core/pipeline/usdlib.py @@ -341,7 +341,9 @@ def get_usd_master_path(folder_entity, product_name, representation): "version": 0, # stub version zero }) - template_obj = anatomy.templates_obj["publish"]["path"] + template_obj = anatomy.get_template( + "publish", "default","path" + ) path = template_obj.format_strict(template_data) # Remove the version folder diff --git a/client/ayon_core/pipeline/workfile/path_resolving.py b/client/ayon_core/pipeline/workfile/path_resolving.py index 5d36f432ad..239b8c1096 100644 --- a/client/ayon_core/pipeline/workfile/path_resolving.py +++ b/client/ayon_core/pipeline/workfile/path_resolving.py @@ -135,7 +135,7 @@ def get_workdir_with_workdir_data( project_settings ) - template_obj = anatomy.templates_obj[template_key]["folder"] + template_obj = anatomy.get_template("work", template_key, "directory") # Output is TemplateResult object which contain useful data output = template_obj.format_strict(workdir_data) if output: @@ -309,11 +309,12 @@ def get_last_workfile( Returns file with version 1 if there is not workfile yet. Args: - workdir(str): Path to dir where workfiles are stored. - file_template(str): Template of file name. - fill_data(Dict[str, Any]): Data for filling template. - extensions(Iterable[str]): All allowed file extensions of workfile. - full_path(bool): Full path to file is returned if set to True. + workdir (str): Path to dir where workfiles are stored. + file_template (str): Template of file name. + fill_data (Dict[str, Any]): Data for filling template. + extensions (Iterable[str]): All allowed file extensions of workfile. + full_path (Optional[bool]): Full path to file is returned if + set to True. Returns: str: Last or first workfile as filename of full path to filename. @@ -334,7 +335,7 @@ def get_last_workfile( data.pop("comment", None) if not data.get("ext"): data["ext"] = extensions[0] - data["ext"] = data["ext"].replace('.', '') + data["ext"] = data["ext"].lstrip(".") filename = StringTemplate.format_strict_template(file_template, data) if full_path: diff --git a/client/ayon_core/plugins/actions/open_file_explorer.py b/client/ayon_core/plugins/actions/open_file_explorer.py index c221752f11..9369a25eb0 100644 --- a/client/ayon_core/plugins/actions/open_file_explorer.py +++ b/client/ayon_core/plugins/actions/open_file_explorer.py @@ -70,7 +70,9 @@ class OpenTaskPath(LauncherAction): data = get_template_data(project_entity, folder_entity, task_entity) anatomy = Anatomy(project_name) - workdir = anatomy.templates_obj["work"]["folder"].format(data) + workdir = anatomy.get_template( + "work", "default", "folder" + ).format(data) # Remove any potential un-formatted parts of the path valid_workdir = self._find_first_filled_path(workdir) @@ -85,7 +87,9 @@ class OpenTaskPath(LauncherAction): return valid_workdir data.pop("task", None) - workdir = anatomy.templates_obj["work"]["folder"].format(data) + workdir = anatomy.get_template( + "work", "default", "folder" + ).format(data) valid_workdir = self._find_first_filled_path(workdir) if valid_workdir: # Normalize diff --git a/client/ayon_core/plugins/load/delivery.py b/client/ayon_core/plugins/load/delivery.py index 453bdfb87a..5289e594f7 100644 --- a/client/ayon_core/plugins/load/delivery.py +++ b/client/ayon_core/plugins/load/delivery.py @@ -282,7 +282,11 @@ class DeliveryOptionsDialog(QtWidgets.QDialog): """Adds list of delivery templates from Anatomy to dropdown.""" templates = {} for template_name, value in anatomy.templates["delivery"].items(): - if not isinstance(value, str) or not value.startswith('{root'): + path_template = value["path"] + if ( + not isinstance(path_template, str) + or not path_template.startswith('{root') + ): continue templates[template_name] = value diff --git a/client/ayon_core/plugins/publish/collect_otio_subset_resources.py b/client/ayon_core/plugins/publish/collect_otio_subset_resources.py index 3f47e6e3bf..ad3a4d2c23 100644 --- a/client/ayon_core/plugins/publish/collect_otio_subset_resources.py +++ b/client/ayon_core/plugins/publish/collect_otio_subset_resources.py @@ -43,8 +43,10 @@ class CollectOtioSubsetResources(pyblish.api.InstancePlugin): template_name = self.get_template_name(instance) anatomy = instance.context.data["anatomy"] - publish_template_category = anatomy.templates[template_name] - template = os.path.normpath(publish_template_category["path"]) + publish_path_template = anatomy.get_template( + "publish", template_name, "path" + ) + template = os.path.normpath(publish_path_template) self.log.debug( ">> template: {}".format(template)) diff --git a/client/ayon_core/plugins/publish/collect_resources_path.py b/client/ayon_core/plugins/publish/collect_resources_path.py index 6a871124f1..05015909d5 100644 --- a/client/ayon_core/plugins/publish/collect_resources_path.py +++ b/client/ayon_core/plugins/publish/collect_resources_path.py @@ -79,23 +79,12 @@ class CollectResourcesPath(pyblish.api.InstancePlugin): "representation": "TEMP" }) - publish_templates = anatomy.templates_obj["publish"] - if "folder" in publish_templates: - publish_folder = publish_templates["folder"].format_strict( - template_data - ) - else: - # solve deprecated situation when `folder` key is not underneath - # `publish` anatomy - self.log.warning(( - "Deprecation warning: Anatomy does not have set `folder`" - " key underneath `publish` (in global of for project `{}`)." - ).format(anatomy.project_name)) - - file_path = publish_templates["path"].format_strict(template_data) - publish_folder = os.path.dirname(file_path) - - publish_folder = os.path.normpath(publish_folder) + publish_templates = anatomy.get_template( + "publish", "default", "directory" + ) + publish_folder = os.path.normpath( + publish_templates.format_strict(template_data) + ) resources_folder = os.path.join(publish_folder, "resources") instance.data["publishDir"] = publish_folder diff --git a/client/ayon_core/plugins/publish/integrate.py b/client/ayon_core/plugins/publish/integrate.py index b7839338ae..16c8ebaaf5 100644 --- a/client/ayon_core/plugins/publish/integrate.py +++ b/client/ayon_core/plugins/publish/integrate.py @@ -665,8 +665,9 @@ class IntegrateAsset(pyblish.api.InstancePlugin): self.log.debug("Anatomy template name: {}".format(template_name)) anatomy = instance.context.data["anatomy"] - publish_template_category = anatomy.templates[template_name] - template = os.path.normpath(publish_template_category["path"]) + publish_template = anatomy.get_template("publish", template_name) + path_template_obj = publish_template["path"] + template = os.path.normpath(path_template_obj) is_udim = bool(repre.get("udim")) @@ -698,7 +699,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin): # - template_data (Dict[str, Any]): source data used to fill template # - to add required data to 'repre_context' not used for # formatting - path_template_obj = anatomy.templates_obj[template_name]["path"] # Treat template with 'orignalBasename' in special way if "{originalBasename}" in template: @@ -753,9 +753,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin): if not is_udim: # Change padding for frames if template has defined higher # padding. - template_padding = int( - publish_template_category["frame_padding"] - ) + template_padding = anatomy.templates_obj.frame_padding if template_padding > destination_padding: destination_padding = template_padding @@ -841,7 +839,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin): # todo: Are we sure the assumption each representation # ends up in the same folder is valid? if not instance.data.get("publishDir"): - template_obj = anatomy.templates_obj[template_name]["folder"] + template_obj = publish_template["directory"] template_filled = template_obj.format_strict(template_data) instance.data["publishDir"] = template_filled diff --git a/client/ayon_core/plugins/publish/integrate_hero_version.py b/client/ayon_core/plugins/publish/integrate_hero_version.py index 6d690ba94b..e313c94393 100644 --- a/client/ayon_core/plugins/publish/integrate_hero_version.py +++ b/client/ayon_core/plugins/publish/integrate_hero_version.py @@ -103,22 +103,15 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin): project_name = anatomy.project_name template_key = self._get_template_key(project_name, instance) + hero_template = anatomy.get_template("hero", template_key, "path") - if template_key not in anatomy.templates: + if hero_template is None: self.log.warning(( "!!! Anatomy of project \"{}\" does not have set" " \"{}\" template key!" ).format(project_name, template_key)) return - if "path" not in anatomy.templates[template_key]: - self.log.warning(( - "!!! There is not set \"path\" template in \"{}\" anatomy" - " for project \"{}\"." - ).format(template_key, project_name)) - return - - hero_template = anatomy.templates[template_key]["path"] self.log.debug("`hero` template check was successful. `{}`".format( hero_template )) @@ -327,7 +320,9 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin): try: src_to_dst_file_paths = [] repre_integrate_data = [] - path_template_obj = anatomy.templates_obj[template_key]["path"] + path_template_obj = anatomy.get_template( + "hero", template_key, "path" + ) for repre_info in published_repres.values(): # Skip if new repre does not have published repre files @@ -383,9 +378,7 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin): anatomy_data ) head, tail = _template_filled.split(frame_splitter) - padding = int( - anatomy.templates[template_key]["frame_padding"] - ) + padding = anatomy.templates_obj.frame_padding dst_col = clique.Collection( head=head, padding=padding, tail=tail @@ -545,29 +538,12 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin): "originalBasename": instance.data.get("originalBasename") }) - if "folder" in anatomy.templates[template_key]: - template_obj = anatomy.templates_obj[template_key]["folder"] - publish_folder = template_obj.format_strict(template_data) - else: - # This is for cases of Deprecated anatomy without `folder` - # TODO remove when all clients have solved this issue - self.log.warning(( - "Deprecation warning: Anatomy does not have set `folder`" - " key underneath `publish` (in global of for project `{}`)." - ).format(anatomy.project_name)) - # solve deprecated situation when `folder` key is not underneath - # `publish` anatomy - template_data.update({ - "frame": "FRAME_TEMP", - "representation": "TEMP" - }) - template_obj = anatomy.templates_obj[template_key]["path"] - file_path = template_obj.format_strict(template_data) - - # Directory - publish_folder = os.path.dirname(file_path) - - publish_folder = os.path.normpath(publish_folder) + template_obj = anatomy.get_template( + "hero", template_key, "directory" + ) + publish_folder = os.path.normpath( + template_obj.format_strict(template_data) + ) self.log.debug("hero publish dir: \"{}\"".format(publish_folder)) diff --git a/client/ayon_core/tools/push_to_project/models/integrate.py b/client/ayon_core/tools/push_to_project/models/integrate.py index 8a29da2fe4..0987dc0c56 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -973,12 +973,9 @@ class ProjectPushItemProcess: "version": version_entity["version"] }) - path_template = anatomy.templates[template_name]["path"].replace( - "\\", "/" - ) - file_template = StringTemplate( - anatomy.templates[template_name]["file"] - ) + publish_template = anatomy.get_template("publish", template_name) + path_template = publish_template["path"].replace("\\", "/") + file_template = publish_template["file"] self._log_info("Preparing files to transfer") processed_repre_items = self._prepare_file_transactions( anatomy, template_name, formatting_data, file_template @@ -1014,7 +1011,9 @@ class ProjectPushItemProcess: if repre_output_name is not None: repre_format_data["output"] = repre_output_name - template_obj = anatomy.templates_obj[template_name]["folder"] + template_obj = anatomy.get_template( + "publish", template_name, "directory" + ) folder_path = template_obj.format_strict(formatting_data) repre_context = folder_path.used_values folder_path_rootless = folder_path.rootless diff --git a/client/ayon_core/tools/texture_copy/app.py b/client/ayon_core/tools/texture_copy/app.py index b3484fbcd0..9a94ba44f7 100644 --- a/client/ayon_core/tools/texture_copy/app.py +++ b/client/ayon_core/tools/texture_copy/app.py @@ -40,7 +40,9 @@ class TextureCopy: }, }) anatomy = Anatomy(project_name, project_entity=project_entity) - template_obj = anatomy.templates_obj["texture"]["path"] + template_obj = anatomy.get_template( + "publish", "texture", "path" + ) return template_obj.format_strict(template_data) def _get_version(self, path): diff --git a/client/ayon_core/tools/workfiles/models/workfiles.py b/client/ayon_core/tools/workfiles/models/workfiles.py index 35a49a908f..f4ca08a45a 100644 --- a/client/ayon_core/tools/workfiles/models/workfiles.py +++ b/client/ayon_core/tools/workfiles/models/workfiles.py @@ -253,8 +253,9 @@ class WorkareaModel: return list(comment_hints), current_comment def _get_workdir(self, anatomy, template_key, fill_data): - template_info = anatomy.templates_obj[template_key] - directory_template = template_info["folder"] + directory_template = anatomy.get_template( + "work", template_key, "directory" + ) return directory_template.format_strict(fill_data).normalized() def get_workarea_save_as_data(self, folder_id, task_id): @@ -299,8 +300,7 @@ class WorkareaModel: workdir = self._get_workdir(anatomy, template_key, fill_data) - template_info = anatomy.templates_obj[template_key] - file_template = template_info["file"] + file_template = anatomy.get_template("work", template_key, "file") comment_hints, comment = self._get_comments_from_root( file_template, @@ -342,8 +342,7 @@ class WorkareaModel: workdir = self._get_workdir(anatomy, template_key, fill_data) - template_info = anatomy.templates_obj[template_key] - file_template = template_info["file"] + file_template = anatomy.get_template("work", template_key, "file") if use_last_version: version = self._get_last_workfile_version(