From 3c6d807df54a44d51956a33cda083fb93ec3a92e Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Wed, 20 Oct 2021 10:20:13 +0200 Subject: [PATCH 01/31] add dict for task name short and type --- openpype/hosts/maya/api/customize.py | 9 +++-- .../plugins/publish/extract_harmony_zip.py | 11 ++++-- openpype/lib/anatomy.py | 8 +++++ openpype/lib/avalon_context.py | 36 +++++++++---------- .../defaults/project_anatomy/templates.json | 4 +-- .../schemas/schema_anatomy_templates.json | 4 +++ openpype/settings/lib.py | 7 ++++ openpype/tools/workfiles/app.py | 21 +++++++++-- 8 files changed, 74 insertions(+), 26 deletions(-) diff --git a/openpype/hosts/maya/api/customize.py b/openpype/hosts/maya/api/customize.py index a84412963b..0b95073ea0 100644 --- a/openpype/hosts/maya/api/customize.py +++ b/openpype/hosts/maya/api/customize.py @@ -84,7 +84,7 @@ def override_toolbox_ui(): log.warning("Could not import Loader tool") try: - from avalon.maya.pipeline import launch_workfiles_app + from openpype.tools import workfiles as launch_workfiles_app except Exception: log.warning("Could not import Workfiles tool") @@ -142,7 +142,12 @@ def override_toolbox_ui(): annotation="Work Files", label="Work Files", image=os.path.join(icons, "workfiles.png"), - command=lambda: launch_workfiles_app(), + command=lambda: launch_workfiles_app.show( + os.path.join( + mc.workspace(query=True, rootDirectory=True), + mc.workspace(fileRuleEntry="scene") + ) + ), bgc=background_color, width=icon_size, height=icon_size, diff --git a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py index adbac6ef09..8014349de3 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py @@ -220,6 +220,10 @@ class ExtractHarmonyZip(openpype.api.Extractor): anatomy = openpype.api.Anatomy() project_entity = instance.context.data["projectEntity"] + task_name = instance.data.get("task") + task_type = instance.data['tasks'].get(task_name, {}).get('type') + task_short = project_entity['config']['tasks'][task_type]['short_name'] + data = { "root": api.registered_root(), "project": { @@ -229,14 +233,17 @@ class ExtractHarmonyZip(openpype.api.Extractor): "asset": instance.data["asset"], "hierarchy": openpype.api.get_hierarchy(instance.data["asset"]), "family": instance.data["family"], - "task": instance.data.get("task"), + "task": { + "name": task_name, + "type": task_type, + "short": task_short, + }, "subset": instance.data["subset"], "version": 1, "ext": "zip", } host_name = "harmony" template_name = get_workfile_template_key_from_context( - instance.data["asset"], instance.data.get("task"), host_name, project_name=project_entity["name"], diff --git a/openpype/lib/anatomy.py b/openpype/lib/anatomy.py index 7a4a55363c..78dc323d4d 100644 --- a/openpype/lib/anatomy.py +++ b/openpype/lib/anatomy.py @@ -989,6 +989,10 @@ class Templates: invalid_required = [] missing_required = [] replace_keys = [] + + if "{task[name]}" in orig_template and not isinstance(data["task"], dict): + data['task']= {'name': data.get("task")} + for group in self.key_pattern.findall(template): orig_key = group[1:-1] key = str(orig_key) @@ -1074,6 +1078,10 @@ class Templates: output = collections.defaultdict(dict) for key, orig_value in templates.items(): if isinstance(orig_value, StringType): + # Replace {task} by '{task[name]}' for backward compatibility + if '{task}' in orig_value: + orig_value = orig_value.replace('{task}', '{task[name]}') + output[key] = self._format(orig_value, data) continue diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index b043cbfdb4..1f28a5088f 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -7,6 +7,7 @@ import platform import logging import collections import functools +import getpass from openpype.settings import get_project_settings from .anatomy import Anatomy @@ -346,7 +347,7 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): def get_workfile_template_key_from_context( - asset_name, task_name, host_name, project_name=None, + task_info, host_name, project_name=None, dbcon=None, project_settings=None ): """Helper function to get template key for workfile template. @@ -358,9 +359,8 @@ def get_workfile_template_key_from_context( 'project_name' arguments. Args: - asset_name(str): Name of asset document. - task_name(str): Task name for which is template key retrieved. - Must be available on asset document under `data.tasks`. + task_info(dict): Information about the task is used to retrieve the + `type` of the task. host_name(str): Name of host implementation for which is workfile used. project_name(str): Project name where asset and task is. Not required @@ -387,17 +387,6 @@ def get_workfile_template_key_from_context( elif not project_name: project_name = dbcon.Session["AVALON_PROJECT"] - asset_doc = dbcon.find_one( - { - "type": "asset", - "name": asset_name - }, - { - "data.tasks": 1 - } - ) - asset_tasks = asset_doc.get("data", {}).get("tasks") or {} - task_info = asset_tasks.get(task_name) or {} task_type = task_info.get("type") return get_workfile_template_key( @@ -479,15 +468,27 @@ def get_workdir_data(project_doc, asset_doc, task_name, host_name): """ hierarchy = "/".join(asset_doc["data"]["parents"]) + task_type = asset_doc['data']['tasks'].get(task_name, {}).get('type') + + if task_type: + task_code = project_doc['config']['tasks'][task_type]['short_name'] + else: + task_code = None + data = { "project": { "name": project_doc["name"], "code": project_doc["data"].get("code") }, - "task": task_name, + "task": { + "name": task_name, + "type": task_type, + "short": task_code, + }, "asset": asset_doc["name"], "app": host_name, - "hierarchy": hierarchy + "user": getpass.getuser(), + "hierarchy": hierarchy, } return data @@ -530,7 +531,6 @@ def get_workdir_with_workdir_data( if not template_key: template_key = get_workfile_template_key_from_context( - workdir_data["asset"], workdir_data["task"], workdir_data["app"], project_name=workdir_data["project"]["name"], diff --git a/openpype/settings/defaults/project_anatomy/templates.json b/openpype/settings/defaults/project_anatomy/templates.json index 53abd35ed5..c6e79b8dcd 100644 --- a/openpype/settings/defaults/project_anatomy/templates.json +++ b/openpype/settings/defaults/project_anatomy/templates.json @@ -6,8 +6,8 @@ "frame": "{frame:0>{@frame_padding}}" }, "work": { - "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/work/{task}", - "file": "{project[code]}_{asset}_{task}_{@version}<_{comment}>.{ext}", + "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/work/{task[user]}", + "file": "{project[code]}_{asset}_{task[user]}_{@version}<_{comment}>.{ext}", "path": "{@folder}/{@file}" }, "render": { diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json index a8534e7e29..be8d6661cf 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json @@ -11,6 +11,10 @@ "type": "dict", "key": "defaults", "children": [ + { + "type": "label", + "label": "The list of existing default placeholders for the construction of paths:
{root[`root_name`]}, {project[name]}, {project[short]}, {hierarchy}, {asset}, {task[name]}, {task[type]}, {task[code]}, {family}, {subset}, {output}, {ext}, {thumbnail_root}, {_id}, {thumbnail_type} " + }, { "type": "number", "key": "version_padding", diff --git a/openpype/settings/lib.py b/openpype/settings/lib.py index 60ed54bd4a..88ce8b6719 100644 --- a/openpype/settings/lib.py +++ b/openpype/settings/lib.py @@ -856,6 +856,13 @@ def get_anatomy_settings( apply_local_settings_on_anatomy_settings( result, local_settings, project_name, site_name ) + + # Replace {task} by '{task[name]}' in all template for backward compatibility + for template in result.get('templates', {}).values(): + for sub_template_name, sub_template_value in template.items(): + if isinstance(sub_template_value, str) and '{task}' in sub_template_value: + template[sub_template_name] = sub_template_value.replace('{task}', '{task[name]}') + return result diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 6fff0d0278..716c417cd1 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -65,16 +65,33 @@ class NameWindow(QtWidgets.QDialog): {"type": "project"}, { "name": True, - "data.code": True + "data.code": True, + "config.tasks": True, } ) + asset_doc = io.find_one({ + "type": "asset", + "name": asset_name + }) + + task_type = asset_doc['data']['tasks'].get(session["AVALON_TASK"], {}).get('type') + + if task_type: + task_short = project_doc['config']['tasks'][task_type]['short_name'] + else: + task_short = None + self.data = { "project": { "name": project_doc["name"], "code": project_doc["data"].get("code") }, "asset": asset_name, - "task": session["AVALON_TASK"], + "task": { + "name": session["AVALON_TASK"], + "type": task_type, + "short": task_short, + }, "version": 1, "user": getpass.getuser(), "comment": "", From 52ce86060f01028c4921931559f93a2e79fdad24 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Wed, 20 Oct 2021 10:26:09 +0200 Subject: [PATCH 02/31] change task name --- openpype/settings/defaults/project_anatomy/templates.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/settings/defaults/project_anatomy/templates.json b/openpype/settings/defaults/project_anatomy/templates.json index c6e79b8dcd..9a03b893bf 100644 --- a/openpype/settings/defaults/project_anatomy/templates.json +++ b/openpype/settings/defaults/project_anatomy/templates.json @@ -6,8 +6,8 @@ "frame": "{frame:0>{@frame_padding}}" }, "work": { - "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/work/{task[user]}", - "file": "{project[code]}_{asset}_{task[user]}_{@version}<_{comment}>.{ext}", + "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/work/{task[name]}", + "file": "{project[code]}_{asset}_{task[name]}_{@version}<_{comment}>.{ext}", "path": "{@folder}/{@file}" }, "render": { From a7f5130741a5eb279ec19ca34debfe10385e3ce0 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 21 Oct 2021 11:20:19 +0200 Subject: [PATCH 03/31] remove change on get_anatomy_settings --- openpype/settings/lib.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openpype/settings/lib.py b/openpype/settings/lib.py index 88ce8b6719..ff75562413 100644 --- a/openpype/settings/lib.py +++ b/openpype/settings/lib.py @@ -857,12 +857,6 @@ def get_anatomy_settings( result, local_settings, project_name, site_name ) - # Replace {task} by '{task[name]}' in all template for backward compatibility - for template in result.get('templates', {}).values(): - for sub_template_name, sub_template_value in template.items(): - if isinstance(sub_template_value, str) and '{task}' in sub_template_value: - template[sub_template_name] = sub_template_value.replace('{task}', '{task[name]}') - return result From f4641e1eda2b1c0673af0ee3701534b62efed09f Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 21 Oct 2021 11:20:40 +0200 Subject: [PATCH 04/31] add suggestion --- openpype/lib/anatomy.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/lib/anatomy.py b/openpype/lib/anatomy.py index 78dc323d4d..aaf10479fd 100644 --- a/openpype/lib/anatomy.py +++ b/openpype/lib/anatomy.py @@ -990,8 +990,12 @@ class Templates: missing_required = [] replace_keys = [] - if "{task[name]}" in orig_template and not isinstance(data["task"], dict): - data['task']= {'name': data.get("task")} + task_data = data.get("task") + if ( + isinstance(task_data, StringType) + and "{task[name]}" in orig_template + ): + data["task"] = {"name": task_data} for group in self.key_pattern.findall(template): orig_key = group[1:-1] From bb544efbc6c13e584017e75e2464bff0b7052119 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Fri, 22 Oct 2021 07:22:20 +0200 Subject: [PATCH 05/31] Fix line too long --- openpype/tools/workfiles/app.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 716c417cd1..9e06a2f310 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -74,10 +74,12 @@ class NameWindow(QtWidgets.QDialog): "name": asset_name }) - task_type = asset_doc['data']['tasks'].get(session["AVALON_TASK"], {}).get('type') + task_type = asset_doc["data"]["tasks"].get( + session["AVALON_TASK"], {}).get("type") if task_type: - task_short = project_doc['config']['tasks'][task_type]['short_name'] + task_short = project_doc["config"]["tasks"].get( + task_type, {}).get("short_name") else: task_short = None From bdf81f21370324e5c46d425368ffdbfe988f1414 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Fri, 22 Oct 2021 16:42:06 +0200 Subject: [PATCH 06/31] remove openpype workfile --- openpype/hosts/maya/api/customize.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/maya/api/customize.py b/openpype/hosts/maya/api/customize.py index 0b95073ea0..a84412963b 100644 --- a/openpype/hosts/maya/api/customize.py +++ b/openpype/hosts/maya/api/customize.py @@ -84,7 +84,7 @@ def override_toolbox_ui(): log.warning("Could not import Loader tool") try: - from openpype.tools import workfiles as launch_workfiles_app + from avalon.maya.pipeline import launch_workfiles_app except Exception: log.warning("Could not import Workfiles tool") @@ -142,12 +142,7 @@ def override_toolbox_ui(): annotation="Work Files", label="Work Files", image=os.path.join(icons, "workfiles.png"), - command=lambda: launch_workfiles_app.show( - os.path.join( - mc.workspace(query=True, rootDirectory=True), - mc.workspace(fileRuleEntry="scene") - ) - ), + command=lambda: launch_workfiles_app(), bgc=background_color, width=icon_size, height=icon_size, From af2450fb0401b12b0b1afab52dfae2725c0039a8 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Mon, 25 Oct 2021 15:12:25 +0200 Subject: [PATCH 07/31] remove change on get_workfile_template_key_from_context --- .../plugins/publish/extract_harmony_zip.py | 7 +++--- openpype/lib/avalon_context.py | 25 +++++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py index 8014349de3..fd89b089c4 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py @@ -11,7 +11,7 @@ import zipfile import pyblish.api from avalon import api, io import openpype.api -from openpype.lib import get_workfile_template_key_from_context +from openpype.lib import get_workfile_template_key class ExtractHarmonyZip(openpype.api.Extractor): @@ -243,11 +243,10 @@ class ExtractHarmonyZip(openpype.api.Extractor): "ext": "zip", } host_name = "harmony" - template_name = get_workfile_template_key_from_context( - instance.data.get("task"), + template_name = get_workfile_template_key( + instance.data.get("task").get("type"), host_name, project_name=project_entity["name"], - dbcon=io ) # Get a valid work filename first with version 1 diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index 1f28a5088f..817e79b7c8 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -347,7 +347,7 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): def get_workfile_template_key_from_context( - task_info, host_name, project_name=None, + asset_name, task_name, host_name, project_name=None, dbcon=None, project_settings=None ): """Helper function to get template key for workfile template. @@ -359,10 +359,9 @@ def get_workfile_template_key_from_context( 'project_name' arguments. Args: - task_info(dict): Information about the task is used to retrieve the - `type` of the task. - host_name(str): Name of host implementation for which is workfile - used. + asset_name(str): Name of asset document. + task_name(str): Task name for which is template key retrieved. + Must be available on asset document under `data.tasks`. project_name(str): Project name where asset and task is. Not required when 'dbcon' is passed. dbcon(AvalonMongoDB): Connection to mongo with already set project @@ -387,6 +386,17 @@ def get_workfile_template_key_from_context( elif not project_name: project_name = dbcon.Session["AVALON_PROJECT"] + asset_doc = dbcon.find_one( + { + "type": "asset", + "name": asset_name + }, + { + "data.tasks": 1 + } + ) + asset_tasks = asset_doc.get("data", {}).get("tasks") or {} + task_info = asset_tasks.get(task_name) or {} task_type = task_info.get("type") return get_workfile_template_key( @@ -530,11 +540,10 @@ def get_workdir_with_workdir_data( anatomy = Anatomy(project_name) if not template_key: - template_key = get_workfile_template_key_from_context( - workdir_data["task"], + template_key = get_workfile_template_key( + workdir_data["task"].get("type"), workdir_data["app"], project_name=workdir_data["project"]["name"], - dbcon=dbcon ) anatomy_filled = anatomy.format(workdir_data) From 17af919d7500aaa7a5a51cf9b9977448e917283d Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Mon, 25 Oct 2021 15:16:20 +0200 Subject: [PATCH 08/31] replace docstring --- openpype/lib/avalon_context.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index 817e79b7c8..fa14589760 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -362,6 +362,8 @@ def get_workfile_template_key_from_context( asset_name(str): Name of asset document. task_name(str): Task name for which is template key retrieved. Must be available on asset document under `data.tasks`. + host_name(str): Name of host implementation for which is workfile + used. project_name(str): Project name where asset and task is. Not required when 'dbcon' is passed. dbcon(AvalonMongoDB): Connection to mongo with already set project From 7ec884f2d5082dd8ca9acff8af988cd94fdd51b2 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 26 Oct 2021 17:22:27 +0200 Subject: [PATCH 09/31] filled anatomyData in publish plugins --- .../plugins/publish/collect_farm_render.py | 3 ++- .../plugins/publish/collect_palettes.py | 2 +- .../plugins/publish/collect_harmony_scenes.py | 18 ++++++++++++- .../plugins/publish/collect_harmony_zips.py | 25 +++++++++++++++---- .../plugins/publish/extract_harmony_zip.py | 12 +++++---- openpype/lib/applications.py | 4 +++ .../plugins/publish/collect_ftrack_api.py | 2 +- .../publish/collect_anatomy_context_data.py | 15 ++++++++++- .../publish/collect_anatomy_instance_data.py | 6 ++--- openpype/plugins/publish/integrate_new.py | 20 ++++++--------- 10 files changed, 76 insertions(+), 31 deletions(-) diff --git a/openpype/hosts/harmony/plugins/publish/collect_farm_render.py b/openpype/hosts/harmony/plugins/publish/collect_farm_render.py index fc80e7c029..31a249591e 100644 --- a/openpype/hosts/harmony/plugins/publish/collect_farm_render.py +++ b/openpype/hosts/harmony/plugins/publish/collect_farm_render.py @@ -126,7 +126,8 @@ class CollectFarmRender(openpype.lib.abstract_collect_render. # because of using 'renderFarm' as a family, replace 'Farm' with # capitalized task name - issue of avalon-core Creator app subset_name = node.split("/")[1] - task_name = context.data["anatomyData"]["task"].capitalize() + task_name = context.data["anatomyData"]["task"][ + "name"].capitalize() replace_str = "" if task_name.lower() not in subset_name.lower(): replace_str = task_name diff --git a/openpype/hosts/harmony/plugins/publish/collect_palettes.py b/openpype/hosts/harmony/plugins/publish/collect_palettes.py index b8671badb3..e47cbaf17e 100644 --- a/openpype/hosts/harmony/plugins/publish/collect_palettes.py +++ b/openpype/hosts/harmony/plugins/publish/collect_palettes.py @@ -28,7 +28,7 @@ class CollectPalettes(pyblish.api.ContextPlugin): # skip collecting if not in allowed task if self.allowed_tasks: - task_name = context.data["anatomyData"]["task"].lower() + task_name = context.data["anatomyData"]["task"]["name"].lower() if (not any([re.search(pattern, task_name) for pattern in self.allowed_tasks])): return diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py index a4fed3bc3f..f76e46bc78 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py @@ -49,10 +49,26 @@ class CollectHarmonyScenes(pyblish.api.InstancePlugin): # fix anatomy data anatomy_data_new = copy.deepcopy(anatomy_data) + + project_entity = context.data["projectEntity"] + asset_entity = context.data["assetEntity"] + + task_type = asset_entity["data"]["tasks"].get(task, {}).get("type") + + if task_type: + task_code = project_entity["config"]["tasks"][task_type][ + "short_name"] + else: + task_code = None + # updating hierarchy data anatomy_data_new.update({ "asset": asset_data["name"], - "task": task, + "task": { + "name": task, + "type": task_type, + "short": task_code, + }, "subset": subset_name }) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py index 93eff85486..f7282ae6e9 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py @@ -27,6 +27,7 @@ class CollectHarmonyZips(pyblish.api.InstancePlugin): anatomy_data = instance.context.data["anatomyData"] repres = instance.data["representations"] files = repres[0]["files"] + project_entity = context.data["projectEntity"] if files.endswith(".zip"): # A zip file was dropped @@ -45,14 +46,28 @@ class CollectHarmonyZips(pyblish.api.InstancePlugin): self.log.info("Copied data: {}".format(new_instance.data)) + task_type = asset_data["data"]["tasks"].get(task, {}).get("type") + + if task_type: + task_code = project_entity["config"]["tasks"][task_type][ + "short_name"] + else: + task_code = None + # fix anatomy data anatomy_data_new = copy.deepcopy(anatomy_data) # updating hierarchy data - anatomy_data_new.update({ - "asset": asset_data["name"], - "task": task, - "subset": subset_name - }) + anatomy_data_new.update( + { + "asset": asset_data["name"], + "task": { + "name": task, + "type": task_type, + "short": task_code, + }, + "subset": subset_name, + } + ) new_instance.data["label"] = f"{instance_name}" new_instance.data["subset"] = subset_name diff --git a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py index fd89b089c4..2318c6176f 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py @@ -31,8 +31,10 @@ class ExtractHarmonyZip(openpype.api.Extractor): # Presets create_workfile = True - default_task = "harmonyIngest" - default_task_type = "Ingest" + default_task = { + "name": "harmonyIngest", + "type": "Ingest", + } default_task_status = "Ingested" assetversion_status = "Ingested" @@ -220,9 +222,9 @@ class ExtractHarmonyZip(openpype.api.Extractor): anatomy = openpype.api.Anatomy() project_entity = instance.context.data["projectEntity"] - task_name = instance.data.get("task") - task_type = instance.data['tasks'].get(task_name, {}).get('type') - task_short = project_entity['config']['tasks'][task_type]['short_name'] + task_name = instance.data.get("task").get("name") + task_type = instance.data.get("task").get("type") + task_short = instance.data.get("task").get("short") data = { "root": api.registered_root(), diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index cc8cb8e7be..c536f9fd15 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -1361,6 +1361,10 @@ def _prepare_last_workfile(data, workdir, workfile_template_key): anatomy = data["anatomy"] # Find last workfile file_template = anatomy.templates["work"]["file"] + # Replace {task} by '{task[name]}' for backward compatibility + if '{task}' in file_template: + file_template = file_template.replace('{task}', '{task[name]}') + workdir_data.update({ "version": 1, "user": get_openpype_username(), diff --git a/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py b/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py index a348617cfc..984e76d8ca 100644 --- a/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py +++ b/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py @@ -109,7 +109,7 @@ class CollectFtrackApi(pyblish.api.ContextPlugin): "Checking entities of instance \"{}\"".format(str(instance)) ) instance_asset_name = instance.data.get("asset") - instance_task_name = instance.data.get("task") + instance_task_name = instance.data.get("task").get("name") if not instance_asset_name and not instance_task_name: self.log.debug("Instance does not have set context keys.") diff --git a/openpype/plugins/publish/collect_anatomy_context_data.py b/openpype/plugins/publish/collect_anatomy_context_data.py index ec88d5669d..7d6482e911 100644 --- a/openpype/plugins/publish/collect_anatomy_context_data.py +++ b/openpype/plugins/publish/collect_anatomy_context_data.py @@ -54,6 +54,15 @@ class CollectAnatomyContextData(pyblish.api.ContextPlugin): if hierarchy_items: hierarchy = os.path.join(*hierarchy_items) + task_type = asset_entity['data']['tasks'].get( + task_name, {}).get('type') + + if task_type: + task_code = project_entity['config']['tasks'][task_type][ + 'short_name'] + else: + task_code = None + context_data = { "project": { "name": project_entity["name"], @@ -61,7 +70,11 @@ class CollectAnatomyContextData(pyblish.api.ContextPlugin): }, "asset": asset_entity["name"], "hierarchy": hierarchy.replace("\\", "/"), - "task": task_name, + "task": { + "name": task_name, + "type": task_type, + "short": task_code, + }, "username": context.data["user"], "app": context.data["hostName"] } diff --git a/openpype/plugins/publish/collect_anatomy_instance_data.py b/openpype/plugins/publish/collect_anatomy_instance_data.py index 4fd657167c..e8eba0c5d3 100644 --- a/openpype/plugins/publish/collect_anatomy_instance_data.py +++ b/openpype/plugins/publish/collect_anatomy_instance_data.py @@ -238,9 +238,9 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): anatomy_updates["hierarchy"] = "/".join(parents) # Task - task_name = instance.data.get("task") - if task_name: - anatomy_updates["task"] = task_name + task_info = instance.data.get("task") + if task_info: + anatomy_updates["task"] = task_info # Additional data resolution_width = instance.data.get("resolutionWidth") diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 451ea1d80d..16b936c0e6 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -171,19 +171,13 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): anatomy_data["hierarchy"] = hierarchy # Make sure task name in anatomy data is same as on instance.data - task_name = instance.data.get("task") - if task_name: - anatomy_data["task"] = task_name + task_info = instance.data.get("task") + if task_info: + anatomy_data["task"] = task_info else: - # Just set 'task_name' variable to context task - task_name = anatomy_data["task"] + # Just set 'task_info' variable to context task + task_info = anatomy_data["task"] - # Find task type for current task name - # - this should be already prepared on instance - asset_tasks = ( - asset_entity.get("data", {}).get("tasks") - ) or {} - task_info = asset_tasks.get(task_name) or {} task_type = task_info.get("type") instance.data["task_type"] = task_type @@ -321,7 +315,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): key_values = { "families": family, - "tasks": task_name, + "tasks": task_info.get("name"), "hosts": instance.context.data["hostName"], "task_types": task_type } @@ -804,7 +798,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): # data? # - should we use context task in that case? task_name = ( - instance.data["anatomyData"]["task"] + instance.data["anatomyData"]["task"].get("name") or io.Session["AVALON_TASK"] ) task_type = instance.data["task_type"] From 46de3e116fe3ea297b814947df117723136f097d Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 26 Oct 2021 17:29:04 +0200 Subject: [PATCH 10/31] fix indent error --- openpype/plugins/publish/collect_anatomy_context_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/plugins/publish/collect_anatomy_context_data.py b/openpype/plugins/publish/collect_anatomy_context_data.py index 7d6482e911..96cf39cd2a 100644 --- a/openpype/plugins/publish/collect_anatomy_context_data.py +++ b/openpype/plugins/publish/collect_anatomy_context_data.py @@ -61,7 +61,7 @@ class CollectAnatomyContextData(pyblish.api.ContextPlugin): task_code = project_entity['config']['tasks'][task_type][ 'short_name'] else: - task_code = None + task_code = None context_data = { "project": { From 90c9f6cd10ed7f1a6661f336bf215a77f10b93ba Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Fri, 29 Oct 2021 10:11:44 +0200 Subject: [PATCH 11/31] Update documentation --- .../projects_schema/schemas/schema_anatomy_templates.json | 2 +- website/docs/admin_settings_project_anatomy.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json index be8d6661cf..e208069e6f 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_templates.json @@ -13,7 +13,7 @@ "children": [ { "type": "label", - "label": "The list of existing default placeholders for the construction of paths:
{root[`root_name`]}, {project[name]}, {project[short]}, {hierarchy}, {asset}, {task[name]}, {task[type]}, {task[code]}, {family}, {subset}, {output}, {ext}, {thumbnail_root}, {_id}, {thumbnail_type} " + "label": "The list of existing placeholders is available here:
https://openpype.io/docs/admin_settings_project_anatomy/#available-template-keys " }, { "type": "number", diff --git a/website/docs/admin_settings_project_anatomy.md b/website/docs/admin_settings_project_anatomy.md index 54023d468f..30784686e2 100644 --- a/website/docs/admin_settings_project_anatomy.md +++ b/website/docs/admin_settings_project_anatomy.md @@ -57,7 +57,9 @@ We have a few required anatomy templates for OpenPype to work properly, however | `project[code]` | Project's code | | `hierarchy` | All hierarchical parents as subfolders | | `asset` | Name of asset or shot | -| `task` | Name of task | +| `task[name]` | Name of task | +| `task[type]` | Type of task | +| `task[short]` | Shortname of task | | `version` | Version number | | `subset` | Subset name | | `family` | Main family name | From 30ec2f5218af3dc9164267f23171ac282b9e6188 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 2 Nov 2021 09:56:52 +0100 Subject: [PATCH 12/31] Get task type and short_name from db --- .../plugins/publish/extract_harmony_zip.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py index 2318c6176f..ceac710bb5 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/extract_harmony_zip.py @@ -221,10 +221,19 @@ class ExtractHarmonyZip(openpype.api.Extractor): # Setup the data needed to form a valid work path filename anatomy = openpype.api.Anatomy() project_entity = instance.context.data["projectEntity"] + asset_entity = io.find_one({ + "type": "asset", + "name": instance.data["asset"] + }) - task_name = instance.data.get("task").get("name") - task_type = instance.data.get("task").get("type") - task_short = instance.data.get("task").get("short") + task_name = instance.data.get("task") + task_type = asset_entity["data"]["tasks"][task_name].get("type") + + if task_type: + task_short = project_entity["config"]["tasks"].get( + task_type, {}).get("short_name") + else: + task_short = None data = { "root": api.registered_root(), From 1f4777c48a98f53dbe0f04cf7746c38275bce173 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Nov 2021 15:22:40 +0100 Subject: [PATCH 13/31] removed unused argument --- openpype/lib/applications.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index c536f9fd15..3a82e4b068 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -1295,10 +1295,10 @@ def prepare_context_environments(data): ) data["env"].update(context_env) - _prepare_last_workfile(data, workdir, workfile_template_key) + _prepare_last_workfile(data, workdir) -def _prepare_last_workfile(data, workdir, workfile_template_key): +def _prepare_last_workfile(data, workdir): """last workfile workflow preparation. Function check if should care about last workfile workflow and tries From 789e13b1a51df605ddff340508fb97c44e50e36b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Nov 2021 15:23:03 +0100 Subject: [PATCH 14/31] removed dbcon argument as is not used --- openpype/lib/avalon_context.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index fa14589760..e74ecd7281 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -506,8 +506,7 @@ def get_workdir_data(project_doc, asset_doc, task_name, host_name): def get_workdir_with_workdir_data( - workdir_data, anatomy=None, project_name=None, - template_key=None, dbcon=None + workdir_data, anatomy=None, project_name=None, template_key=None ): """Fill workdir path from entered data and project's anatomy. @@ -659,7 +658,7 @@ def create_workfile_doc(asset_doc, task_name, filename, workdir, dbcon=None): anatomy = Anatomy(project_doc["name"]) # Get workdir path (result is anatomy.TemplateResult) template_workdir = get_workdir_with_workdir_data( - workdir_data, anatomy, dbcon=dbcon + workdir_data, anatomy ) template_workdir_path = str(template_workdir).replace("\\", "/") From 73ead413a27287c4a614f50e567d66e28bc31f7e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Nov 2021 15:23:22 +0100 Subject: [PATCH 15/31] we know that type key is available on workdir data --- openpype/lib/avalon_context.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index e74ecd7281..bf04aa4435 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -542,9 +542,9 @@ def get_workdir_with_workdir_data( if not template_key: template_key = get_workfile_template_key( - workdir_data["task"].get("type"), + workdir_data["task"]["type"], workdir_data["app"], - project_name=workdir_data["project"]["name"], + project_name=workdir_data["project"]["name"] ) anatomy_filled = anatomy.format(workdir_data) From c4c8cc17f4d93b1b8d7efc4276e846359d48ff3b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Nov 2021 15:39:04 +0100 Subject: [PATCH 16/31] simplified application launch --- openpype/lib/applications.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index 3a82e4b068..e190c38fd9 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -1246,23 +1246,12 @@ def prepare_context_environments(data): anatomy = data["anatomy"] - asset_tasks = asset_doc.get("data", {}).get("tasks") or {} - task_info = asset_tasks.get(task_name) or {} - task_type = task_info.get("type") + task_type = workdir_data["task"]["type"] # Temp solution how to pass task type to `_prepare_last_workfile` data["task_type"] = task_type - workfile_template_key = get_workfile_template_key( - task_type, - app.host_name, - project_name=project_name, - project_settings=project_settings - ) - try: - workdir = get_workdir_with_workdir_data( - workdir_data, anatomy, template_key=workfile_template_key - ) + workdir = get_workdir_with_workdir_data(workdir_data, anatomy) except Exception as exc: raise ApplicationLaunchFailed( From 733448e132ba5b727e5de0114585e293ccdc128c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Nov 2021 15:40:23 +0100 Subject: [PATCH 17/31] simplified getting short name --- .../plugins/publish/collect_harmony_scenes.py | 8 ++----- .../plugins/publish/collect_harmony_zips.py | 10 +++----- openpype/lib/avalon_context.py | 6 ++--- .../publish/collect_anatomy_context_data.py | 11 ++++----- openpype/tools/workfiles/app.py | 24 +++++++++---------- 5 files changed, 23 insertions(+), 36 deletions(-) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py index f76e46bc78..48c36aa067 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py @@ -54,12 +54,8 @@ class CollectHarmonyScenes(pyblish.api.InstancePlugin): asset_entity = context.data["assetEntity"] task_type = asset_entity["data"]["tasks"].get(task, {}).get("type") - - if task_type: - task_code = project_entity["config"]["tasks"][task_type][ - "short_name"] - else: - task_code = None + project_task_types = project_entity["config"]["tasks"] + task_code = project_task_types.get(task_type, {}).get("short_name") # updating hierarchy data anatomy_data_new.update({ diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py index f7282ae6e9..40a969f8df 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py @@ -47,12 +47,8 @@ class CollectHarmonyZips(pyblish.api.InstancePlugin): self.log.info("Copied data: {}".format(new_instance.data)) task_type = asset_data["data"]["tasks"].get(task, {}).get("type") - - if task_type: - task_code = project_entity["config"]["tasks"][task_type][ - "short_name"] - else: - task_code = None + project_task_types = project_entity["config"]["tasks"] + task_code = project_task_types.get(task_type, {}).get("short_name") # fix anatomy data anatomy_data_new = copy.deepcopy(anatomy_data) @@ -65,7 +61,7 @@ class CollectHarmonyZips(pyblish.api.InstancePlugin): "type": task_type, "short": task_code, }, - "subset": subset_name, + "subset": subset_name } ) diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index bf04aa4435..dd9e8b2ab8 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -482,10 +482,8 @@ def get_workdir_data(project_doc, asset_doc, task_name, host_name): task_type = asset_doc['data']['tasks'].get(task_name, {}).get('type') - if task_type: - task_code = project_doc['config']['tasks'][task_type]['short_name'] - else: - task_code = None + project_task_types = project_doc["config"]["tasks"] + task_code = project_task_types.get(task_type, {}).get("short_name") data = { "project": { diff --git a/openpype/plugins/publish/collect_anatomy_context_data.py b/openpype/plugins/publish/collect_anatomy_context_data.py index 96cf39cd2a..6b95979b76 100644 --- a/openpype/plugins/publish/collect_anatomy_context_data.py +++ b/openpype/plugins/publish/collect_anatomy_context_data.py @@ -54,14 +54,11 @@ class CollectAnatomyContextData(pyblish.api.ContextPlugin): if hierarchy_items: hierarchy = os.path.join(*hierarchy_items) - task_type = asset_entity['data']['tasks'].get( - task_name, {}).get('type') + asset_tasks = asset_entity["data"]["tasks"] + task_type = asset_tasks.get(task_name, {}).get("type") - if task_type: - task_code = project_entity['config']['tasks'][task_type][ - 'short_name'] - else: - task_code = None + project_task_types = project_entity["config"]["tasks"] + task_code = project_task_types.get(task_type, {}).get("short_name") context_data = { "project": { diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 9e06a2f310..314ec0a0e1 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -61,6 +61,7 @@ class NameWindow(QtWidgets.QDialog): # Set work file data for template formatting asset_name = session["AVALON_ASSET"] + task_name = session["AVALON_TASK"] project_doc = io.find_one( {"type": "project"}, { @@ -69,19 +70,18 @@ class NameWindow(QtWidgets.QDialog): "config.tasks": True, } ) - asset_doc = io.find_one({ - "type": "asset", - "name": asset_name - }) + asset_doc = io.find_one( + { + "type": "asset", + "name": asset_name + }, + {"data.tasks": True} + ) - task_type = asset_doc["data"]["tasks"].get( - session["AVALON_TASK"], {}).get("type") + task_type = asset_doc["data"]["tasks"].get(task_name, {}).get("type") - if task_type: - task_short = project_doc["config"]["tasks"].get( - task_type, {}).get("short_name") - else: - task_short = None + project_task_types = project_doc["config"]["tasks"] + task_short = project_task_types.get(task_type, {}).get("short_name") self.data = { "project": { @@ -90,7 +90,7 @@ class NameWindow(QtWidgets.QDialog): }, "asset": asset_name, "task": { - "name": session["AVALON_TASK"], + "name": task_name, "type": task_type, "short": task_short, }, From c3738a4d2f16ca115dc4866c45ad6af7483f120b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Nov 2021 15:43:34 +0100 Subject: [PATCH 18/31] instance.data["task"] is not task info but string --- .../plugins/publish/collect_ftrack_api.py | 2 +- .../publish/collect_anatomy_instance_data.py | 19 ++++++++-- openpype/plugins/publish/integrate_new.py | 36 +++++++++++-------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py b/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py index 984e76d8ca..a348617cfc 100644 --- a/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py +++ b/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py @@ -109,7 +109,7 @@ class CollectFtrackApi(pyblish.api.ContextPlugin): "Checking entities of instance \"{}\"".format(str(instance)) ) instance_asset_name = instance.data.get("asset") - instance_task_name = instance.data.get("task").get("name") + instance_task_name = instance.data.get("task") if not instance_asset_name and not instance_task_name: self.log.debug("Instance does not have set context keys.") diff --git a/openpype/plugins/publish/collect_anatomy_instance_data.py b/openpype/plugins/publish/collect_anatomy_instance_data.py index e8eba0c5d3..286a14485f 100644 --- a/openpype/plugins/publish/collect_anatomy_instance_data.py +++ b/openpype/plugins/publish/collect_anatomy_instance_data.py @@ -212,6 +212,8 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): project_doc = context.data["projectEntity"] context_asset_doc = context.data["assetEntity"] + project_task_types = project_doc["config"]["tasks"] + for instance in context: version_number = instance.data.get("version") # If version is not specified for instance or context @@ -238,9 +240,20 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): anatomy_updates["hierarchy"] = "/".join(parents) # Task - task_info = instance.data.get("task") - if task_info: - anatomy_updates["task"] = task_info + task_name = instance.data.get("task") + if task_name: + asset_tasks = asset_doc["data"]["tasks"] + task_type = asset_tasks.get(task_name, {}).get("type") + task_code = ( + project_task_types + .get(task_type, {}) + .get("short_name") + ) + anatomy_updates["task"] = { + "name": task_name, + "type": task_type, + "short": task_code + } # Additional data resolution_width = instance.data.get("resolutionWidth") diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 16b936c0e6..0898275cd8 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -171,15 +171,26 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): anatomy_data["hierarchy"] = hierarchy # Make sure task name in anatomy data is same as on instance.data - task_info = instance.data.get("task") - if task_info: - anatomy_data["task"] = task_info - else: - # Just set 'task_info' variable to context task - task_info = anatomy_data["task"] + asset_tasks = ( + asset_entity.get("data", {}).get("tasks") + ) or {} + task_name = instance.data.get("task") + if task_name: + task_info = asset_tasks.get(task_name) or {} + task_type = task_info.get("type") - task_type = task_info.get("type") - instance.data["task_type"] = task_type + project_task_types = project_entity["config"]["tasks"] + task_code = project_task_types.get(task_type, {}).get("short_name") + anatomy_data["task"] = { + "name": task_name, + "type": task_type, + "short": task_code + } + + else: + # Just set 'task_name' variable to context task + task_name = anatomy_data["task"]["name"] + task_type = anatomy_data["task"]["type"] # Fill family in anatomy data anatomy_data["family"] = instance.data.get("family") @@ -315,7 +326,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): key_values = { "families": family, - "tasks": task_info.get("name"), + "tasks": task_name, "hosts": instance.context.data["hostName"], "task_types": task_type } @@ -797,11 +808,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): # - is there a chance that task name is not filled in anatomy # data? # - should we use context task in that case? - task_name = ( - instance.data["anatomyData"]["task"].get("name") - or io.Session["AVALON_TASK"] - ) - task_type = instance.data["task_type"] + task_name = instance.data["anatomyData"]["task"]["name"] + task_type = instance.data["anatomyData"]["task"]["type"] filtering_criteria = { "families": instance.data["family"], "hosts": instance.context.data["hostName"], From 77927bdeeacb6251386ca61148d85abbbe6d8b2c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Nov 2021 10:31:03 +0100 Subject: [PATCH 19/31] fix burnin templates --- openpype/plugins/publish/extract_burnin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index 06eb85c593..cbebed927a 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -184,7 +184,9 @@ class ExtractBurnin(openpype.api.Extractor): for key in self.positions: value = burnin_def.get(key) if value: - burnin_values[key] = value + burnin_values[key] = value.replace( + "{task}", "{task[name]}" + ) # Remove "delete" tag from new representation if "delete" in new_repre["tags"]: From 9e3157e7690ff25954e8214ca57705e479d9bb59 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 12 Nov 2021 19:00:23 +0100 Subject: [PATCH 20/31] initial work --- openpype/tools/repack_version.py | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 openpype/tools/repack_version.py diff --git a/openpype/tools/repack_version.py b/openpype/tools/repack_version.py new file mode 100644 index 0000000000..ab1a095632 --- /dev/null +++ b/openpype/tools/repack_version.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +"""Script to rehash and repack current version.""" +from igniter import bootstrap_repos +import enlighten +import blessed +from pathlib import Path +import os +from zipfile import ZipFile, BadZipFile +from igniter.bootstrap_repos import sha256sum + + +term = blessed.Terminal() +manager = enlighten.get_manager() +last_increment = 0 + +progress_bar = enlighten.Counter( + total=100, desc="OpenPype ZIP", units="%", color="green") + + + +zip_path = Path(version_path).parent + + +with ZipFile(zip_path, "w") as zip_file: + progress = 0 + openpype_root = openpype_path.resolve() + # generate list of filtered paths + dir_filter = [openpype_root / f for f in self.openpype_filter] + checksums = [] + + file: Path + for file in openpype_list: + progress += openpype_inc + self._progress_callback(int(progress)) + + # if file resides in filtered path, skip it + is_inside = None + df: Path + for df in dir_filter: + try: + is_inside = file.resolve().relative_to(df) + except ValueError: + pass + + if not is_inside: + continue + + processed_path = file + self._print(f"- processing {processed_path}") + + checksums.append( + ( + sha256sum(file.as_posix()), + file.resolve().relative_to(openpype_root) + ) + ) + zip_file.write( + file, file.resolve().relative_to(openpype_root)) + + checksums_str = "" + for c in checksums: + checksums_str += "{}:{}\n".format(c[0], c[1]) + zip_file.writestr("checksums", checksums_str) + # test if zip is ok + zip_file.testzip() + self._progress_callback(100) From cc580b07f3112279f7635ed015c69ca17fd74991 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 16 Nov 2021 18:34:14 +0100 Subject: [PATCH 21/31] version repacker command --- igniter/bootstrap_repos.py | 35 ++-- openpype/cli.py | 12 ++ openpype/pype_commands.py | 7 + openpype/tools/repack_version.py | 185 +++++++++++++++------ tests/unit/igniter/test_bootstrap_repos.py | 2 +- 5 files changed, 174 insertions(+), 67 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index f7f35824c8..a7b79b2ac0 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -10,6 +10,7 @@ import tempfile from pathlib import Path from typing import Union, Callable, List, Tuple import hashlib +import platform from zipfile import ZipFile, BadZipFile @@ -196,21 +197,21 @@ class OpenPypeVersion(semver.VersionInfo): return str(self.finalize_version()) @staticmethod - def version_in_str(string: str) -> Tuple: + def version_in_str(string: str) -> Union[None, OpenPypeVersion]: """Find OpenPype version in given string. Args: string (str): string to search. Returns: - tuple: True/False and OpenPypeVersion if found. + OpenPypeVersion: of detected or None. """ m = re.search(OpenPypeVersion._VERSION_REGEX, string) if not m: - return False, None + return None version = OpenPypeVersion.parse(string[m.start():m.end()]) - return True, version + return version @classmethod def parse(cls, version): @@ -531,6 +532,7 @@ class BootstrapRepos: processed_path = file self._print(f"- processing {processed_path}") + checksums.append( ( sha256sum(file.as_posix()), @@ -542,7 +544,10 @@ class BootstrapRepos: checksums_str = "" for c in checksums: - checksums_str += "{}:{}\n".format(c[0], c[1]) + file_str = c[1] + if platform.system().lower() == "windows": + file_str = c[1].as_posix().replace("\\", "/") + checksums_str += "{}:{}\n".format(c[0], file_str) zip_file.writestr("checksums", checksums_str) # test if zip is ok zip_file.testzip() @@ -589,13 +594,16 @@ class BootstrapRepos: # calculate and compare checksums in the zip file for file in checksums: + file_name = file[1] + if platform.system().lower() == "windows": + file_name = file_name.replace("/", "\\") h = hashlib.sha256() try: - h.update(zip_file.read(file[1])) + h.update(zip_file.read(file_name)) except FileNotFoundError: - return False, f"Missing file [ {file[1]} ]" + return False, f"Missing file [ {file_name} ]" if h.hexdigest() != file[0]: - return False, f"Invalid checksum on {file[1]}" + return False, f"Invalid checksum on {file_name}" # get list of files in zip minus `checksums` file itself # and turn in to set to compare against list of files @@ -631,13 +639,16 @@ class BootstrapRepos: files_in_checksum = set([file[1] for file in checksums]) for file in checksums: + file_name = file[1] + if platform.system().lower() == "windows": + file_name = file_name.replace("/", "\\") try: - current = sha256sum((path / file[1]).as_posix()) + current = sha256sum((path / file_name).as_posix()) except FileNotFoundError: - return False, f"Missing file [ {file[1]} ]" + return False, f"Missing file [ {file_name} ]" if file[0] != current: - return False, f"Invalid checksum on {file[1]}" + return False, f"Invalid checksum on {file_name}" diff = files_in_dir.difference(files_in_checksum) if diff: return False, f"Missing files {diff}" @@ -1163,7 +1174,7 @@ class BootstrapRepos: if result[0]: detected_version: OpenPypeVersion - detected_version = result[1] + detected_version = result if item.is_dir() and not self._is_openpype_in_dir( item, detected_version diff --git a/openpype/cli.py b/openpype/cli.py index 3194723d4c..e5aaca3db1 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -384,3 +384,15 @@ def syncserver(debug, active_site): if debug: os.environ['OPENPYPE_DEBUG'] = '3' PypeCommands().syncserver(active_site) + + +@main.command() +@click.argument("directory", help="OpenPype version directory") +def repack_version(directory): + """Repack OpenPype version from directory. + + This command will re-create zip file from specified directory, + recalculating file checksums. It will try to use version detected in + directory name. + """ + PypeCommands().repack_version(directory) diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index f72c7404f9..37430f879c 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -405,3 +405,10 @@ class PypeCommands: import time while True: time.sleep(1.0) + + def repack_version(self, directory): + """Repacking OpenPype version.""" + from openpype.tools.repack_version import VersionRepacker + + version_packer = VersionRepacker(directory) + version_packer.process() diff --git a/openpype/tools/repack_version.py b/openpype/tools/repack_version.py index ab1a095632..15e75e0469 100644 --- a/openpype/tools/repack_version.py +++ b/openpype/tools/repack_version.py @@ -1,66 +1,143 @@ # -*- coding: utf-8 -*- """Script to rehash and repack current version.""" -from igniter import bootstrap_repos + import enlighten import blessed from pathlib import Path import os +import platform from zipfile import ZipFile, BadZipFile -from igniter.bootstrap_repos import sha256sum +from typing import Union, Callable, List, Tuple +import hashlib +import sys +from igniter.bootstrap_repos import OpenPypeVersion +import re -term = blessed.Terminal() -manager = enlighten.get_manager() -last_increment = 0 +class VersionRepacker: -progress_bar = enlighten.Counter( - total=100, desc="OpenPype ZIP", units="%", color="green") + def __init__(self, directory: str): + self._term = blessed.Terminal() + self._manager = enlighten.get_manager() + self._last_increment = 0 + self.version_path = Path(directory) + self.zip_path = self.version_path.parent + _version = {} + with open(self.version_path / "openpype" / "version.py") as fp: + exec(fp.read(), _version) + self._version_py = _version["__version__"] + del _version + + def _print(self, msg: str, message_type: int = 0) -> None: + """Print message to console. + + Args: + msg (str): message to print + message_type (int): type of message (0 info, 1 error, 2 note) + + """ + if message_type == 0: + header = self._term.aquamarine3(">>> ") + elif message_type == 1: + header = self._term.orangered2("!!! ") + elif message_type == 2: + header = self._term.tan1("... ") + else: + header = self._term.darkolivegreen3("--- ") + + print("{}{}".format(header, msg)) + + @staticmethod + def sha256sum(filename): + """Calculate sha256 for content of the file. + + Args: + filename (str): Path to file. + + Returns: + str: hex encoded sha256 + + """ + h = hashlib.sha256() + b = bytearray(128 * 1024) + mv = memoryview(b) + with open(filename, 'rb', buffering=0) as f: + for n in iter(lambda: f.readinto(mv), 0): + h.update(mv[:n]) + return h.hexdigest() + + @staticmethod + def _filter_dir(path: Path, path_filter: List) -> List[Path]: + """Recursively crawl over path and filter.""" + result = [] + for item in path.iterdir(): + if item.name in path_filter: + continue + if item.name.startswith('.'): + continue + if item.is_dir(): + result.extend(VersionRepacker._filter_dir(item, path_filter)) + else: + result.append(item) + return result + + def process(self): + if (self.version_path / "pyproject.toml").exists(): + self._print( + ("This cannot run on OpenPype sources. " + "Please run it on extracted version."), 1) + return + self._print(f"Rehashing and zipping {self.version_path}") + version = OpenPypeVersion.version_in_str(self.version_path.name) + if not version: + self._print("Cannot get version from directory", 1) + return + + self._print(f"Detected version is {version}") + self._print(f"Recalculating checksums ...", 2) + + checksums = [] + + file_list = VersionRepacker._filter_dir(self.version_path, []) + progress_bar = enlighten.Counter( + total=len(file_list), desc="Calculating checksums", + nits="%", color="green") + for file in file_list: + checksums.append(( + VersionRepacker.sha256sum(file.as_posix()), + file.resolve().relative_to(self.version_path), + file + )) + progress_bar.update() + progress_bar.close() + + progress_bar = enlighten.Counter( + total=len(checksums), desc="Zipping directory", + nits="%", color=(56, 211, 159)) + + with ZipFile(self.zip_path, "w") as zip_file: + checksums = [] + + for item in checksums: + + processed_path = item[0] + self._print(f"- processing {processed_path}") + + zip_file.write(item[2], item[1]) + progress_bar.update() + + checksums_str = "" + for c in checksums: + file_str = c[1] + if platform.system().lower() == "windows": + file_str = c[1].as_posix().replace("\\", "/") + checksums_str += "{}:{}\n".format(c[0], file_str) + zip_file.writestr("checksums", checksums_str) + # test if zip is ok + zip_file.testzip() - -zip_path = Path(version_path).parent - - -with ZipFile(zip_path, "w") as zip_file: - progress = 0 - openpype_root = openpype_path.resolve() - # generate list of filtered paths - dir_filter = [openpype_root / f for f in self.openpype_filter] - checksums = [] - - file: Path - for file in openpype_list: - progress += openpype_inc - self._progress_callback(int(progress)) - - # if file resides in filtered path, skip it - is_inside = None - df: Path - for df in dir_filter: - try: - is_inside = file.resolve().relative_to(df) - except ValueError: - pass - - if not is_inside: - continue - - processed_path = file - self._print(f"- processing {processed_path}") - - checksums.append( - ( - sha256sum(file.as_posix()), - file.resolve().relative_to(openpype_root) - ) - ) - zip_file.write( - file, file.resolve().relative_to(openpype_root)) - - checksums_str = "" - for c in checksums: - checksums_str += "{}:{}\n".format(c[0], c[1]) - zip_file.writestr("checksums", checksums_str) - # test if zip is ok - zip_file.testzip() - self._progress_callback(100) +if __name__ == '__main__': + print(sys.argv[1]) + version_packer = VersionRepacker(sys.argv[1]) + version_packer.process() diff --git a/tests/unit/igniter/test_bootstrap_repos.py b/tests/unit/igniter/test_bootstrap_repos.py index 740a71a5ce..d6e861c262 100644 --- a/tests/unit/igniter/test_bootstrap_repos.py +++ b/tests/unit/igniter/test_bootstrap_repos.py @@ -140,7 +140,7 @@ def test_search_string_for_openpype_version(printer): ] for ver_string in strings: printer(f"testing {ver_string[0]} should be {ver_string[1]}") - assert OpenPypeVersion.version_in_str(ver_string[0])[0] == \ + assert OpenPypeVersion.version_in_str(ver_string[0]) == \ ver_string[1] From 5e8d5086e9ab464d98890bda9c1914028dd99edb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Nov 2021 15:27:21 +0100 Subject: [PATCH 22/31] Added experimental tools action to houdini menu --- openpype/hosts/houdini/startup/MainMenuCommon.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openpype/hosts/houdini/startup/MainMenuCommon.xml b/openpype/hosts/houdini/startup/MainMenuCommon.xml index 2b556a2e75..c34310cf72 100644 --- a/openpype/hosts/houdini/startup/MainMenuCommon.xml +++ b/openpype/hosts/houdini/startup/MainMenuCommon.xml @@ -67,6 +67,16 @@ from avalon.houdini import pipeline pipeline.reload_pipeline()]]> + + + + + + From 618b7c432810bd9b40a142bbc3a4c616d25d8121 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 18 Nov 2021 15:56:41 +0100 Subject: [PATCH 23/31] fix zip staging --- igniter/bootstrap_repos.py | 4 +++- openpype/cli.py | 2 +- openpype/tools/repack_version.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index a7b79b2ac0..de70dfde66 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -211,6 +211,8 @@ class OpenPypeVersion(semver.VersionInfo): if not m: return None version = OpenPypeVersion.parse(string[m.start():m.end()]) + if "staging" in m.group("buildmetadata"): + version.staging = True return version @classmethod @@ -1172,7 +1174,7 @@ class BootstrapRepos: name = item.name if item.is_dir() else item.stem result = OpenPypeVersion.version_in_str(name) - if result[0]: + if result: detected_version: OpenPypeVersion detected_version = result diff --git a/openpype/cli.py b/openpype/cli.py index e5aaca3db1..4c4dc1a3c6 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -387,7 +387,7 @@ def syncserver(debug, active_site): @main.command() -@click.argument("directory", help="OpenPype version directory") +@click.argument("directory") def repack_version(directory): """Repack OpenPype version from directory. diff --git a/openpype/tools/repack_version.py b/openpype/tools/repack_version.py index 15e75e0469..9388563f63 100644 --- a/openpype/tools/repack_version.py +++ b/openpype/tools/repack_version.py @@ -94,7 +94,7 @@ class VersionRepacker: return self._print(f"Detected version is {version}") - self._print(f"Recalculating checksums ...", 2) + self._print("Recalculating checksums ...", 2) checksums = [] From 18e27546c3d55f922c457e8d693ad6a964d9ea32 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Nov 2021 17:34:14 +0100 Subject: [PATCH 24/31] removed not used IntegrateCleanComponentData plugin --- .../publish/integrate_remove_components.py | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 openpype/modules/default_modules/ftrack/plugins/publish/integrate_remove_components.py diff --git a/openpype/modules/default_modules/ftrack/plugins/publish/integrate_remove_components.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_remove_components.py deleted file mode 100644 index 26cac0f1ae..0000000000 --- a/openpype/modules/default_modules/ftrack/plugins/publish/integrate_remove_components.py +++ /dev/null @@ -1,30 +0,0 @@ -import pyblish.api -import os - - -class IntegrateCleanComponentData(pyblish.api.InstancePlugin): - """ - Cleaning up thumbnail an mov files after they have been integrated - """ - - order = pyblish.api.IntegratorOrder + 0.5 - label = 'Clean component data' - families = ["ftrack"] - optional = True - active = False - - def process(self, instance): - - for comp in instance.data['representations']: - self.log.debug('component {}'.format(comp)) - - if "%" in comp['published_path'] or "#" in comp['published_path']: - continue - - if comp.get('thumbnail') or ("thumbnail" in comp.get('tags', [])): - os.remove(comp['published_path']) - self.log.info('Thumbnail image was erased') - - elif comp.get('preview') or ("preview" in comp.get('tags', [])): - os.remove(comp['published_path']) - self.log.info('Preview mov file was erased') From 5a029336658b7ed17ef8ce3643838a7a266c5329 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 18 Nov 2021 18:53:47 +0100 Subject: [PATCH 25/31] staging fixes and docs --- igniter/bootstrap_repos.py | 8 +++--- openpype/tools/repack_version.py | 35 ++++++++++++++++++++----- website/docs/admin_openpype_commands.md | 13 +++++++-- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index de70dfde66..151597e505 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -211,7 +211,7 @@ class OpenPypeVersion(semver.VersionInfo): if not m: return None version = OpenPypeVersion.parse(string[m.start():m.end()]) - if "staging" in m.group("buildmetadata"): + if "staging" in string[m.start():m.end()]: version.staging = True return version @@ -570,6 +570,8 @@ class BootstrapRepos: and string with reason as second. """ + if os.getenv("OPENPYPE_DONT_VALIDATE_VERSION"): + return True, "Disabled validation" if not path.exists(): return False, "Path doesn't exist" @@ -614,7 +616,7 @@ class BootstrapRepos: files_in_zip = zip_file.namelist() files_in_zip.remove("checksums") files_in_zip = set(files_in_zip) - files_in_checksum = set([file[1] for file in checksums]) + files_in_checksum = {file[1] for file in checksums} diff = files_in_zip.difference(files_in_checksum) if diff: return False, f"Missing files {diff}" @@ -638,7 +640,7 @@ class BootstrapRepos: ] files_in_dir.remove("checksums") files_in_dir = set(files_in_dir) - files_in_checksum = set([file[1] for file in checksums]) + files_in_checksum = {file[1] for file in checksums} for file in checksums: file_name = file[1] diff --git a/openpype/tools/repack_version.py b/openpype/tools/repack_version.py index 9388563f63..9ce788c5e5 100644 --- a/openpype/tools/repack_version.py +++ b/openpype/tools/repack_version.py @@ -94,6 +94,8 @@ class VersionRepacker: return self._print(f"Detected version is {version}") + # replace version in version.py + self._replace_version(version, self.version_path) self._print("Recalculating checksums ...", 2) checksums = [] @@ -115,14 +117,13 @@ class VersionRepacker: total=len(checksums), desc="Zipping directory", nits="%", color=(56, 211, 159)) - with ZipFile(self.zip_path, "w") as zip_file: - checksums = [] + zip_filename = self.zip_path / f"openpype-v{version}.zip" + with ZipFile(zip_filename, "w") as zip_file: for item in checksums: - - processed_path = item[0] - self._print(f"- processing {processed_path}") - + if item[1].as_posix() == "checksums": + progress_bar.update() + continue zip_file.write(item[2], item[1]) progress_bar.update() @@ -135,6 +136,28 @@ class VersionRepacker: zip_file.writestr("checksums", checksums_str) # test if zip is ok zip_file.testzip() + self._print(f"All done, you can find new zip here: {zip_filename}") + + @staticmethod + def _replace_version(version: OpenPypeVersion, path: Path): + """Replace version in version.py. + + Args: + version (OpenPypeVersion): OpenPype version to set + path (Path): Path to unzipped version. + + """ + with open(path / "openpype" / "version.py", "r") as op_version_file: + replacement = "" + + for line in op_version_file: + stripped_line = line.strip() + if stripped_line.strip().startswith("__version__ ="): + line = f'__version__ = "{version}"\n' + replacement += line + + with open(path / "openpype" / "version.py", "w") as op_version_file: + op_version_file.write(replacement) if __name__ == '__main__': diff --git a/website/docs/admin_openpype_commands.md b/website/docs/admin_openpype_commands.md index 7a46ee7906..0831cf4f5a 100644 --- a/website/docs/admin_openpype_commands.md +++ b/website/docs/admin_openpype_commands.md @@ -32,7 +32,10 @@ For more information [see here](admin_use#run-openpype). | Command | Description | Arguments | | --- | --- |: --- :| -| tray | Launch OpenPype Tray. | [📑](#tray-arguments) +| contextselection | Open Context selection dialog. | | +| module | Run command line arguments for modules. | | +| repack-version | Tool to re-create version zip. | [📑](#repack-version-arguments) | +| tray | Launch OpenPype Tray. | [📑](#tray-arguments) | eventserver | This should be ideally used by system service (such as systemd or upstart on linux and window service). | [📑](#eventserver-arguments) | | launch | Launch application in Pype environment. | [📑](#launch-arguments) | | publish | Pype takes JSON from provided path and use it to publish data in it. | [📑](#publish-arguments) | @@ -156,4 +159,10 @@ openpypeconsole settings `standalonepublisher` has no command-line arguments. ```shell openpype_console standalonepublisher -``` \ No newline at end of file +``` + +### `repack-version` arguments {#repack-version-arguments} +Takes path to unzipped and possibly modified OpenPype version. Files will be +zipped, checksums recalculated and version will be determined by folder name +(and written to `version.py`). + From 13dae8f04e04f6c9913cbc0626a16d2801fec989 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 18 Nov 2021 19:03:08 +0100 Subject: [PATCH 26/31] remove unused imports --- openpype/tools/repack_version.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openpype/tools/repack_version.py b/openpype/tools/repack_version.py index 9ce788c5e5..7f37e2eef1 100644 --- a/openpype/tools/repack_version.py +++ b/openpype/tools/repack_version.py @@ -4,14 +4,12 @@ import enlighten import blessed from pathlib import Path -import os import platform -from zipfile import ZipFile, BadZipFile -from typing import Union, Callable, List, Tuple +from zipfile import ZipFile +from typing import List import hashlib import sys from igniter.bootstrap_repos import OpenPypeVersion -import re class VersionRepacker: From 8f2fb8a27fde133d3421cc495337bd7ab178675a Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 18 Nov 2021 19:06:18 +0100 Subject: [PATCH 27/31] hound fixes --- openpype/tools/repack_version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/repack_version.py b/openpype/tools/repack_version.py index 7f37e2eef1..0172264c79 100644 --- a/openpype/tools/repack_version.py +++ b/openpype/tools/repack_version.py @@ -100,8 +100,8 @@ class VersionRepacker: file_list = VersionRepacker._filter_dir(self.version_path, []) progress_bar = enlighten.Counter( - total=len(file_list), desc="Calculating checksums", - nits="%", color="green") + total=len(file_list), desc="Calculating checksums", + nits="%", color="green") for file in file_list: checksums.append(( VersionRepacker.sha256sum(file.as_posix()), From e9784d3b48bcd638d14c78111e5771b7ca83e456 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Fri, 19 Nov 2021 12:03:04 +0100 Subject: [PATCH 28/31] replace _asse_id by _asset_id --- openpype/tools/workfiles/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index a849868d77..a4b1717a1c 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -659,7 +659,7 @@ class FilesWidget(QtWidgets.QWidget): self.host.save_file(file_path) self.set_asset_task( - self._asse_id, self._task_name, self._task_type + self._asset_id, self._task_name, self._task_type ) pipeline.emit("after.workfile.save", [file_path]) From 34bfc50139b91706ef20eadeff26bbe296457a3c Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 19 Nov 2021 13:21:35 +0100 Subject: [PATCH 29/31] Fix - missed wrong key for sftp provider --- openpype/modules/default_modules/sync_server/providers/sftp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/sync_server/providers/sftp.py b/openpype/modules/default_modules/sync_server/providers/sftp.py index 4f505ae016..3390cd5d3d 100644 --- a/openpype/modules/default_modules/sync_server/providers/sftp.py +++ b/openpype/modules/default_modules/sync_server/providers/sftp.py @@ -192,7 +192,7 @@ class SFTPHandler(AbstractProvider): Format is importing for usage of python's format ** approach """ # roots cannot be locally overridden - return self.presets['roots'] + return self.presets['root'] def get_tree(self): """ From acde01d7ef556aff280de7ed04dfd3c87a977ad5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Nov 2021 15:28:29 +0100 Subject: [PATCH 30/31] added 'get_workfir_data' to openpype api --- openpype/api.py | 1 + openpype/lib/avalon_context.py | 1 + 2 files changed, 2 insertions(+) diff --git a/openpype/api.py b/openpype/api.py index e4bbb104a3..a6529202ff 100644 --- a/openpype/api.py +++ b/openpype/api.py @@ -17,6 +17,7 @@ from .lib import ( version_up, get_asset, get_hierarchy, + get_workdir_data, get_version_from_path, get_last_version_from_path, get_app_environments_for_context, diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index dd9e8b2ab8..372e116f43 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -465,6 +465,7 @@ def get_workfile_template_key( return default +# TODO rename function as is not just "work" specific def get_workdir_data(project_doc, asset_doc, task_name, host_name): """Prepare data for workdir template filling from entered information. From 5d8c3d4c710e5826095ab6723faddd308d192156 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 19 Nov 2021 15:28:48 +0100 Subject: [PATCH 31/31] use get_workdir_data in nuke format anatomy to get context data --- openpype/hosts/nuke/api/lib.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index a321e576ee..f4c3a55c2b 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -18,7 +18,7 @@ from openpype.api import ( BuildWorkfile, get_version_from_path, get_anatomy_settings, - get_hierarchy, + get_workdir_data, get_asset, get_current_project_settings, ApplicationManager @@ -268,15 +268,21 @@ def format_anatomy(data): if not version: file = script_name() data["version"] = get_version_from_path(file) - project_document = io.find_one({"type": "project"}) + + project_doc = io.find_one({"type": "project"}) + asset_doc = io.find_one({ + "type": "asset", + "name": data["avalon"]["asset"] + }) + task_name = os.environ["AVALON_TASK"] + host_name = os.environ["AVALON_APP"] + context_data = get_workdir_data( + project_doc, asset_doc, task_name, host_name + ) + data.update(context_data) data.update({ "subset": data["avalon"]["subset"], - "asset": data["avalon"]["asset"], - "task": os.environ["AVALON_TASK"], "family": data["avalon"]["family"], - "project": {"name": project_document["name"], - "code": project_document["data"].get("code", '')}, - "hierarchy": get_hierarchy(), "frame": "#" * padding, }) return anatomy.format(data)