From 0fc23ce2e7600c335bd05ccc642f742497a36282 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 21 Dec 2023 15:06:31 +0000 Subject: [PATCH 001/149] Changed logic for creation of output node --- openpype/hosts/blender/api/render_lib.py | 70 ++++++++++++++++-------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index b437078ad8..cdccf13805 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -135,71 +135,95 @@ def set_render_passes(settings): return aov_list, custom_passes -def set_node_tree(output_path, name, aov_sep, ext, multilayer): +def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): # Set the scene to use the compositor node tree to render bpy.context.scene.use_nodes = True tree = bpy.context.scene.node_tree + comp_layer_type = "CompositorNodeRLayers" + output_type = "CompositorNodeOutputFile" + # Get the Render Layers node rl_node = None for node in tree.nodes: - if node.bl_idname == "CompositorNodeRLayers": + if node.bl_idname == comp_layer_type: rl_node = node break # If there's not a Render Layers node, we create it if not rl_node: - rl_node = tree.nodes.new("CompositorNodeRLayers") + rl_node = tree.nodes.new(comp_layer_type) # Get the enabled output sockets, that are the active passes for the # render. # We also exclude some layers. - exclude_sockets = ["Image", "Alpha", "Noisy Image"] + exclude_sockets = ["Alpha", "Noisy Image"] passes = [ socket for socket in rl_node.outputs if socket.enabled and socket.name not in exclude_sockets ] - # Remove all output nodes + old_output = None + + # Remove all output nodes that inlcude "AYON" in the name. + # There should be only one. for node in tree.nodes: - if node.bl_idname == "CompositorNodeOutputFile": - tree.nodes.remove(node) + if node.bl_idname == output_type and "AYON" in node.name: + old_output = node + break # Create a new output node - output = tree.nodes.new("CompositorNodeOutputFile") + output = tree.nodes.new(output_type) image_settings = bpy.context.scene.render.image_settings output.format.file_format = image_settings.file_format + slots = None + # In case of a multilayer exr, we don't need to use the output node, # because the blender render already outputs a multilayer exr. - if ext == "exr" and multilayer: - output.layer_slots.clear() - return [] + multi_exr = ext == "exr" and multilayer + slots = output.layer_slots if multi_exr else output.file_slots + output.base_path = render_product if multi_exr else str(output_path) - output.file_slots.clear() - output.base_path = str(output_path) + slots.clear() aov_file_products = [] # For each active render pass, we add a new socket to the output node # and link it - for render_pass in passes: - filepath = f"{name}{aov_sep}{render_pass.name}.####" + for rpass in passes: + if rpass.name == "Image": + pass_name = "rgba" if multi_exr else "beauty" + else: + pass_name = rpass.name + filepath = f"{name}{aov_sep}{pass_name}.####" - output.file_slots.new(filepath) + slots.new(pass_name if multi_exr else filepath) filename = str(output_path / filepath.lstrip("/")) - aov_file_products.append((render_pass.name, filename)) + aov_file_products.append((rpass.name, filename)) - node_input = output.inputs[-1] + if not old_output: + node_input = output.inputs[-1] + tree.links.new(rpass, node_input) - tree.links.new(render_pass, node_input) + for link in tree.links: + if link.to_node == old_output: + socket_name = link.to_socket.name + new_socket = output.inputs.get(socket_name) + if new_socket: + tree.links.new(link.from_socket, new_socket) - return aov_file_products + if old_output: + output.location = old_output.location + tree.nodes.remove(old_output) + output.name = "AYON File Output" + + return [] if multi_exr else aov_file_products def imprint_render_settings(node, data): @@ -236,9 +260,11 @@ def prepare_rendering(asset_group): render_product = get_render_product(output_path, name, aov_sep) aov_file_product = set_node_tree( - output_path, name, aov_sep, ext, multilayer) + output_path, render_product, name, aov_sep, ext, multilayer) - bpy.context.scene.render.filepath = render_product + # Clear the render filepath, so that the output is handled only by the + # output node in the compositor. + bpy.context.scene.render.filepath = "" render_settings = { "render_folder": render_folder, From fa5b9777a98cca34f5cd5412500f34825a6ff3d8 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 21 Dec 2023 15:07:00 +0000 Subject: [PATCH 002/149] Create a new version of the workfile instead of overwriting current one --- openpype/hosts/blender/plugins/create/create_render.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/create/create_render.py b/openpype/hosts/blender/plugins/create/create_render.py index 7fb3e5eb00..e728579286 100644 --- a/openpype/hosts/blender/plugins/create/create_render.py +++ b/openpype/hosts/blender/plugins/create/create_render.py @@ -1,8 +1,10 @@ """Create render.""" import bpy +from openpype.lib import version_up from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.render_lib import prepare_rendering +from openpype.hosts.blender.api.workio import save_file class CreateRenderlayer(plugin.BaseCreator): @@ -37,6 +39,7 @@ class CreateRenderlayer(plugin.BaseCreator): # settings. Even the validator to check that the file is saved will # detect the file as saved, even if it isn't. The only solution for # now it is to force the file to be saved. - bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath) + filepath = version_up(bpy.data.filepath) + save_file(filepath, copy=False) return collection From 0534c9c55d9eb5d0f193b2c64c3a870b6082a092 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 18 Jan 2024 10:13:24 +0000 Subject: [PATCH 003/149] Fix error when getting setting value in Ayon --- openpype/hosts/blender/api/render_lib.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index cdccf13805..904cabfc05 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -2,6 +2,7 @@ from pathlib import Path import bpy +from openpype import AYON_SERVER_ENABLED from openpype.settings import get_project_settings from openpype.pipeline import get_current_project_name @@ -124,13 +125,14 @@ def set_render_passes(settings): aovs_names = [aov.name for aov in vl.aovs] for cp in custom_passes: - cp_name = cp[0] + cp_name = cp["attribute"] if AYON_SERVER_ENABLED else cp[0] if cp_name not in aovs_names: aov = vl.aovs.add() aov.name = cp_name else: aov = vl.aovs[cp_name] - aov.type = cp[1].get("type", "VALUE") + aov.type = (cp["value"] + if AYON_SERVER_ENABLED else cp[1].get("type", "VALUE")) return aov_list, custom_passes From 1eb07bcedb97edef9bbf57fa7c605bf85794a33f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 18 Jan 2024 10:16:05 +0000 Subject: [PATCH 004/149] Added setting to choose render engine --- openpype/hosts/blender/api/render_lib.py | 11 ++++++++++- .../blender/server/settings/render_settings.py | 13 +++++++++++++ server_addon/blender/server/version.py | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index 904cabfc05..06353f8e8b 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -48,6 +48,14 @@ def get_multilayer(settings): ["multilayer_exr"]) +def get_renderer(settings): + """Get renderer from blender settings.""" + + return (settings["blender"] + ["RenderSettings"] + ["renderer"]) + + def get_render_product(output_path, name, aov_sep): """ Generate the path to the render product. Blender interprets the `#` @@ -254,9 +262,10 @@ def prepare_rendering(asset_group): aov_sep = get_aov_separator(settings) ext = get_image_format(settings) multilayer = get_multilayer(settings) + renderer = get_renderer(settings) set_render_format(ext, multilayer) - aov_list, custom_passes = set_render_passes(settings) + bpy.context.scene.render.engine = renderer output_path = Path.joinpath(dirpath, render_folder, file_name) diff --git a/server_addon/blender/server/settings/render_settings.py b/server_addon/blender/server/settings/render_settings.py index f62013982e..53cefd145d 100644 --- a/server_addon/blender/server/settings/render_settings.py +++ b/server_addon/blender/server/settings/render_settings.py @@ -25,6 +25,13 @@ def image_format_enum(): ] +def renderers_enum(): + return [ + {"value": "CYCLES", "label": "Cycles"}, + {"value": "BLENDER_EEVEE", "label": "Eevee"}, + ] + + def aov_list_enum(): return [ {"value": "empty", "label": "< none >"}, @@ -83,6 +90,11 @@ class RenderSettingsModel(BaseSettingsModel): multilayer_exr: bool = Field( title="Multilayer (EXR)" ) + renderer: str = Field( + "CYCLES", + title="Renderer", + enum_resolver=renderers_enum + ) aov_list: list[str] = Field( default_factory=list, enum_resolver=aov_list_enum, @@ -104,6 +116,7 @@ DEFAULT_RENDER_SETTINGS = { "aov_separator": "underscore", "image_format": "exr", "multilayer_exr": True, + "renderer": "CYCLES", "aov_list": [], "custom_passes": [] } diff --git a/server_addon/blender/server/version.py b/server_addon/blender/server/version.py index 1276d0254f..0a8da88258 100644 --- a/server_addon/blender/server/version.py +++ b/server_addon/blender/server/version.py @@ -1 +1 @@ -__version__ = "0.1.5" +__version__ = "0.1.6" From 2f58708f584a63a68ffcbe2c429704dca566f43b Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 18 Jan 2024 10:16:31 +0000 Subject: [PATCH 005/149] Updated aov list --- openpype/hosts/blender/api/render_lib.py | 62 ++++++++++++++----- .../server/settings/render_settings.py | 50 ++++++++++++--- 2 files changed, 90 insertions(+), 22 deletions(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index 06353f8e8b..44ee2be208 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -100,36 +100,69 @@ def set_render_format(ext, multilayer): image_settings.file_format = "TIFF" -def set_render_passes(settings): - aov_list = (settings["blender"] - ["RenderSettings"] - ["aov_list"]) - - custom_passes = (settings["blender"] - ["RenderSettings"] - ["custom_passes"]) +def set_render_passes(settings, renderer): + aov_list = settings["blender"]["RenderSettings"]["aov_list"] + custom_passes = settings["blender"]["RenderSettings"]["custom_passes"] + # Common passes for both renderers vl = bpy.context.view_layer + # Data Passes vl.use_pass_combined = "combined" in aov_list vl.use_pass_z = "z" in aov_list vl.use_pass_mist = "mist" in aov_list vl.use_pass_normal = "normal" in aov_list + + # Light Passes vl.use_pass_diffuse_direct = "diffuse_light" in aov_list vl.use_pass_diffuse_color = "diffuse_color" in aov_list vl.use_pass_glossy_direct = "specular_light" in aov_list vl.use_pass_glossy_color = "specular_color" in aov_list - vl.eevee.use_pass_volume_direct = "volume_light" in aov_list vl.use_pass_emit = "emission" in aov_list vl.use_pass_environment = "environment" in aov_list - vl.use_pass_shadow = "shadow" in aov_list vl.use_pass_ambient_occlusion = "ao" in aov_list - cycles = vl.cycles + # Cryptomatte Passes + vl.use_pass_cryptomatte_object = "cryptomatte_object" in aov_list + vl.use_pass_cryptomatte_material = "cryptomatte_material" in aov_list + vl.use_pass_cryptomatte_asset = "cryptomatte_asset" in aov_list - cycles.denoising_store_passes = "denoising" in aov_list - cycles.use_pass_volume_direct = "volume_direct" in aov_list - cycles.use_pass_volume_indirect = "volume_indirect" in aov_list + if renderer == "BLENDER_EEVEE": + # Eevee exclusive passes + eevee = vl.eevee + + # Light Passes + vl.use_pass_shadow = "shadow" in aov_list + eevee.use_pass_volume_direct = "volume_light" in aov_list + + # Effects Passes + eevee.use_pass_bloom = "bloom" in aov_list + eevee.use_pass_transparent = "transparent" in aov_list + + # Cryptomatte Passes + vl.use_pass_cryptomatte_accurate = "cryptomatte_accurate" in aov_list + elif renderer == "CYCLES": + # Cycles exclusive passes + cycles = vl.cycles + + # Data Passes + vl.use_pass_position = "position" in aov_list + vl.use_pass_vector = "vector" in aov_list + vl.use_pass_uv = "uv" in aov_list + cycles.denoising_store_passes = "denoising" in aov_list + vl.use_pass_object_index = "object_index" in aov_list + vl.use_pass_material_index = "material_index" in aov_list + cycles.pass_debug_sample_count = "sample_count" in aov_list + + # Light Passes + vl.use_pass_diffuse_indirect = "diffuse_indirect" in aov_list + vl.use_pass_glossy_indirect = "specular_indirect" in aov_list + vl.use_pass_transmission_direct = "transmission_direct" in aov_list + vl.use_pass_transmission_indirect = "transmission_indirect" in aov_list + vl.use_pass_transmission_color = "transmission_color" in aov_list + cycles.use_pass_volume_direct = "volume_light" in aov_list + cycles.use_pass_volume_indirect = "volume_indirect" in aov_list + cycles.use_pass_shadow_catcher = "shadow" in aov_list aovs_names = [aov.name for aov in vl.aovs] for cp in custom_passes: @@ -266,6 +299,7 @@ def prepare_rendering(asset_group): set_render_format(ext, multilayer) bpy.context.scene.render.engine = renderer + aov_list, custom_passes = set_render_passes(settings, renderer) output_path = Path.joinpath(dirpath, render_folder, file_name) diff --git a/server_addon/blender/server/settings/render_settings.py b/server_addon/blender/server/settings/render_settings.py index 53cefd145d..3ab720fc6a 100644 --- a/server_addon/blender/server/settings/render_settings.py +++ b/server_addon/blender/server/settings/render_settings.py @@ -39,18 +39,52 @@ def aov_list_enum(): {"value": "z", "label": "Z"}, {"value": "mist", "label": "Mist"}, {"value": "normal", "label": "Normal"}, - {"value": "diffuse_light", "label": "Diffuse Light"}, + {"value": "position", "label": "Position (Cycles Only)"}, + {"value": "vector", "label": "Vector (Cycles Only)"}, + {"value": "uv", "label": "UV (Cycles Only)"}, + {"value": "denoising", "label": "Denoising Data (Cycles Only)"}, + {"value": "object_index", "label": "Object Index (Cycles Only)"}, + {"value": "material_index", "label": "Material Index (Cycles Only)"}, + {"value": "sample_count", "label": "Sample Count (Cycles Only)"}, + {"value": "diffuse_light", "label": "Diffuse Light/Direct"}, + { + "value": "diffuse_indirect", + "label": "Diffuse Indirect (Cycles Only)" + }, {"value": "diffuse_color", "label": "Diffuse Color"}, - {"value": "specular_light", "label": "Specular Light"}, - {"value": "specular_color", "label": "Specular Color"}, - {"value": "volume_light", "label": "Volume Light"}, + {"value": "specular_light", "label": "Specular (Glossy) Light/Direct"}, + { + "value": "specular_indirect", + "label": "Specular (Glossy) Indirect (Cycles Only)" + }, + {"value": "specular_color", "label": "Specular (Glossy) Color"}, + { + "value": "transmission_light", + "label": "Transmission Light/Direct (Cycles Only)" + }, + { + "value": "transmission_indirect", + "label": "Transmission Indirect (Cycles Only)" + }, + { + "value": "transmission_color", + "label": "Transmission Color (Cycles Only)" + }, + {"value": "volume_light", "label": "Volume Light/Direct"}, + {"value": "volume_indirect", "label": "Volume Indirect (Cycles Only)"}, {"value": "emission", "label": "Emission"}, {"value": "environment", "label": "Environment"}, - {"value": "shadow", "label": "Shadow"}, + {"value": "shadow", "label": "Shadow/Shadow Catcher"}, {"value": "ao", "label": "Ambient Occlusion"}, - {"value": "denoising", "label": "Denoising"}, - {"value": "volume_direct", "label": "Direct Volumetric Scattering"}, - {"value": "volume_indirect", "label": "Indirect Volumetric Scattering"} + {"value": "bloom", "label": "Bloom (Eevee Only)"}, + {"value": "transparent", "label": "Transparent (Eevee Only)"}, + {"value": "cryptomatte_object", "label": "Cryptomatte Object"}, + {"value": "cryptomatte_material", "label": "Cryptomatte Material"}, + {"value": "cryptomatte_asset", "label": "Cryptomatte Asset"}, + { + "value": "cryptomatte_accurate", + "label": "Cryptomatte Accurate Mode (Eevee Only)" + }, ] From 91f67ca9b0a199e110650fd899d562eae3cdcd16 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 19 Jan 2024 10:00:58 +0000 Subject: [PATCH 006/149] Updated default settings for render passes --- server_addon/blender/server/settings/render_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/blender/server/settings/render_settings.py b/server_addon/blender/server/settings/render_settings.py index 3ab720fc6a..580547e510 100644 --- a/server_addon/blender/server/settings/render_settings.py +++ b/server_addon/blender/server/settings/render_settings.py @@ -151,6 +151,6 @@ DEFAULT_RENDER_SETTINGS = { "image_format": "exr", "multilayer_exr": True, "renderer": "CYCLES", - "aov_list": [], + "aov_list": ["combined"], "custom_passes": [] } From dd0533ecb36b19988ccb67b0b2e83a50f7090be1 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 19 Jan 2024 10:03:05 +0000 Subject: [PATCH 007/149] Added composite output --- openpype/hosts/blender/api/render_lib.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index 44ee2be208..fc47f5a659 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -186,12 +186,17 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): comp_layer_type = "CompositorNodeRLayers" output_type = "CompositorNodeOutputFile" + compositor_type = "CompositorNodeComposite" - # Get the Render Layers node + # Get the Render Layer and Composite nodes rl_node = None + comp_node = None for node in tree.nodes: if node.bl_idname == comp_layer_type: rl_node = node + elif node.bl_idname == compositor_type: + comp_node = node + if rl_node and comp_node: break # If there's not a Render Layers node, we create it @@ -242,29 +247,38 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): pass_name = "rgba" if multi_exr else "beauty" else: pass_name = rpass.name - filepath = f"{name}{aov_sep}{pass_name}.####" + filename = f"{name}{aov_sep}{pass_name}.####" - slots.new(pass_name if multi_exr else filepath) + slots.new(pass_name if multi_exr else filename) - filename = str(output_path / filepath.lstrip("/")) + filepath = str(output_path / filename.lstrip("/")) - aov_file_products.append((rpass.name, filename)) + aov_file_products.append((rpass.name, filepath)) if not old_output: node_input = output.inputs[-1] tree.links.new(rpass, node_input) + # Create a new socket for the composite output + pass_name = "composite" + filename = f"{name}{aov_sep}{pass_name}.####" + comp_socket = slots.new(pass_name if multi_exr else filename) + aov_file_products.append(("Composite", filepath)) + for link in tree.links: if link.to_node == old_output: socket_name = link.to_socket.name new_socket = output.inputs.get(socket_name) if new_socket: tree.links.new(link.from_socket, new_socket) + elif comp_node and link.to_node == comp_node: + tree.links.new(link.from_socket, comp_socket) if old_output: output.location = old_output.location tree.nodes.remove(old_output) output.name = "AYON File Output" + output.label = "AYON File Output" return [] if multi_exr else aov_file_products From c911c67dae109a3c769fa4fe584f925f3afe7a2e Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 19 Jan 2024 11:04:25 +0000 Subject: [PATCH 008/149] Updated OpenPype Settings --- .../defaults/project_settings/blender.json | 3 +- .../schema_project_blender.json | 43 +++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/openpype/settings/defaults/project_settings/blender.json b/openpype/settings/defaults/project_settings/blender.json index 385e97ef91..48f3ef8ef0 100644 --- a/openpype/settings/defaults/project_settings/blender.json +++ b/openpype/settings/defaults/project_settings/blender.json @@ -22,7 +22,8 @@ "aov_separator": "underscore", "image_format": "exr", "multilayer_exr": true, - "aov_list": [], + "renderer": "CYCLES", + "aov_list": ["combined"], "custom_passes": [] }, "workfile_builder": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_blender.json b/openpype/settings/entities/schemas/projects_schema/schema_project_blender.json index 535d9434a3..bbed881ab0 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_blender.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_blender.json @@ -103,6 +103,17 @@ "type": "label", "label": "Note: Multilayer EXR is only used when output format type set to EXR." }, + { + "key": "renderer", + "label": "Renderer", + "type": "enum", + "multiselection": false, + "defaults": "CYCLES", + "enum_items": [ + {"CYCLES": "Cycles"}, + {"BLENDER_EEVEE": "Eevee"} + ] + }, { "key": "aov_list", "label": "AOVs to create", @@ -115,18 +126,34 @@ {"z": "Z"}, {"mist": "Mist"}, {"normal": "Normal"}, - {"diffuse_light": "Diffuse Light"}, + {"position": "Position (Cycles Only)"}, + {"vector": "Vector (Cycles Only)"}, + {"uv": "UV (Cycles Only)"}, + {"denoising": "Denoising Data (Cycles Only)"}, + {"object_index": "Object Index (Cycles Only)"}, + {"material_index": "Material Index (Cycles Only)"}, + {"sample_count": "Sample Count (Cycles Only)"}, + {"diffuse_light": "Diffuse Light/Direct"}, + {"diffuse_indirect": "Diffuse Indirect (Cycles Only)"}, {"diffuse_color": "Diffuse Color"}, - {"specular_light": "Specular Light"}, - {"specular_color": "Specular Color"}, - {"volume_light": "Volume Light"}, + {"specular_light": "Specular (Glossy) Light/Direct"}, + {"specular_indirect": "Specular (Glossy) Indirect (Cycles Only)"}, + {"specular_color": "Specular (Glossy) Color"}, + {"transmission_light": "Transmission Light/Direct (Cycles Only)"}, + {"transmission_indirect": "Transmission Indirect (Cycles Only)"}, + {"transmission_color": "Transmission Color (Cycles Only)"}, + {"volume_light": "Volume Light/Direct"}, + {"volume_indirect": "Volume Indirect (Cycles Only)"}, {"emission": "Emission"}, {"environment": "Environment"}, - {"shadow": "Shadow"}, + {"shadow": "Shadow/Shadow Catcher"}, {"ao": "Ambient Occlusion"}, - {"denoising": "Denoising"}, - {"volume_direct": "Direct Volumetric Scattering"}, - {"volume_indirect": "Indirect Volumetric Scattering"} + {"bloom": "Bloom (Eevee Only)"}, + {"transparent": "Transparent (Eevee Only)"}, + {"cryptomatte_object": "Cryptomatte Object"}, + {"cryptomatte_material": "Cryptomatte Material"}, + {"cryptomatte_asset": "Cryptomatte Asset"}, + {"cryptomatte_accurate": "Cryptomatte Accurate Mode (Eevee Only)"} ] }, { From 44282f86df721a271a291bc005abd07f896acb49 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 1 Feb 2024 10:42:34 +0000 Subject: [PATCH 009/149] Fixed deadline validator to check compositor tree output --- .../publish/validate_deadline_publish.py | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/validate_deadline_publish.py b/openpype/hosts/blender/plugins/publish/validate_deadline_publish.py index bb243f08cc..f7860dd75d 100644 --- a/openpype/hosts/blender/plugins/publish/validate_deadline_publish.py +++ b/openpype/hosts/blender/plugins/publish/validate_deadline_publish.py @@ -28,15 +28,27 @@ class ValidateDeadlinePublish(pyblish.api.InstancePlugin, def process(self, instance): if not self.is_active(instance.data): return + + tree = bpy.context.scene.node_tree + output_type = "CompositorNodeOutputFile" + output_node = None + # Remove all output nodes that inlcude "AYON" in the name. + # There should be only one. + for node in tree.nodes: + if node.bl_idname == output_type and "AYON" in node.name: + output_node = node + break + if not output_node: + raise PublishValidationError( + "No output node found in the compositor tree." + ) filepath = bpy.data.filepath file = os.path.basename(filepath) filename, ext = os.path.splitext(file) - if filename not in bpy.context.scene.render.filepath: + if filename not in output_node.base_path: raise PublishValidationError( - "Render output folder " - "doesn't match the blender scene name! " - "Use Repair action to " - "fix the folder file path." + "Render output folder doesn't match the blender scene name! " + "Use Repair action to fix the folder file path." ) @classmethod From b7aa3e323d74a9524a30bfb472a07b77939ef8a2 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 2 Feb 2024 11:38:23 +0200 Subject: [PATCH 010/149] fix default redshift version --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index bf7fb45a8b..e0e52fe6a6 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,7 +45,7 @@ class VrayRenderPluginInfo(): @attr.s class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) - Version = attr.ib(default=None) + Version = attr.ib(default="1") class HoudiniSubmitDeadline( From c2dbf604d8eb1fec466182f434daa332e952341f Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 2 Feb 2024 14:42:28 +0200 Subject: [PATCH 011/149] add comment about using v1 as RS default version --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index e0e52fe6a6..582f7d081b 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,6 +45,9 @@ class VrayRenderPluginInfo(): @attr.s class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) + # "1" was selected as the default RS version as it's the default + # version in RS deadline plugin. + # https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/app-redshift.html#plug-in-configuration Version = attr.ib(default="1") From 7d586f59061cabab548516c3fcde289ad8dc3501 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Fri, 2 Feb 2024 15:06:12 +0200 Subject: [PATCH 012/149] remove RS deadline plugin doc link Co-authored-by: Roy Nieterau --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 582f7d081b..cf8e1617f2 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -47,7 +47,6 @@ class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) # "1" was selected as the default RS version as it's the default # version in RS deadline plugin. - # https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/app-redshift.html#plug-in-configuration Version = attr.ib(default="1") From 4e114b80324e71c808e65b872c965ce693c42923 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Fri, 2 Feb 2024 15:07:10 +0200 Subject: [PATCH 013/149] update comment about default RS version Co-authored-by: Roy Nieterau --- .../plugins/publish/submit_houdini_render_deadline.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index cf8e1617f2..402dcaf256 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,8 +45,9 @@ class VrayRenderPluginInfo(): @attr.s class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) - # "1" was selected as the default RS version as it's the default - # version in RS deadline plugin. + # Use "1" as the default Redshift version just because it + # default fallback version in Deadline's Redshift plugin + # if no version was specified Version = attr.ib(default="1") From 78a3ec2118c9963e31ea0b4ca2907d0b84a14b39 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Mon, 5 Feb 2024 12:06:19 +0000 Subject: [PATCH 014/149] Fixed issue with double entries in the json manifest --- openpype/hosts/blender/api/render_lib.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index fc47f5a659..c2792103e5 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -244,7 +244,9 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): # and link it for rpass in passes: if rpass.name == "Image": - pass_name = "rgba" if multi_exr else "beauty" + if not multi_exr: + continue + pass_name = "rgba" else: pass_name = rpass.name filename = f"{name}{aov_sep}{pass_name}.####" @@ -263,6 +265,7 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): pass_name = "composite" filename = f"{name}{aov_sep}{pass_name}.####" comp_socket = slots.new(pass_name if multi_exr else filename) + filepath = str(output_path / filename.lstrip("/")) aov_file_products.append(("Composite", filepath)) for link in tree.links: From f2429680ff5aa68b358ececeba02d24e9d86ad0c Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 6 Feb 2024 15:43:18 +0000 Subject: [PATCH 015/149] Fix old links and duplicated entries in the manifest --- openpype/hosts/blender/api/render_lib.py | 114 ++++++++++++----------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/openpype/hosts/blender/api/render_lib.py b/openpype/hosts/blender/api/render_lib.py index c2792103e5..17b9d926ec 100644 --- a/openpype/hosts/blender/api/render_lib.py +++ b/openpype/hosts/blender/api/render_lib.py @@ -178,6 +178,14 @@ def set_render_passes(settings, renderer): return aov_list, custom_passes +def _create_aov_slot(name, aov_sep, slots, rpass_name, multi_exr, output_path): + filename = f"{name}{aov_sep}{rpass_name}.####" + slot = slots.new(rpass_name if multi_exr else filename) + filepath = str(output_path / filename.lstrip("/")) + + return slot, filepath + + def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): # Set the scene to use the compositor node tree to render bpy.context.scene.use_nodes = True @@ -188,40 +196,34 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): output_type = "CompositorNodeOutputFile" compositor_type = "CompositorNodeComposite" - # Get the Render Layer and Composite nodes - rl_node = None - comp_node = None + # Get the Render Layer, Composite and the previous output nodes + render_layer_node = None + composite_node = None + old_output_node = None for node in tree.nodes: if node.bl_idname == comp_layer_type: - rl_node = node + render_layer_node = node elif node.bl_idname == compositor_type: - comp_node = node - if rl_node and comp_node: + composite_node = node + elif node.bl_idname == output_type and "AYON" in node.name: + old_output_node = node + if render_layer_node and composite_node and old_output_node: break # If there's not a Render Layers node, we create it - if not rl_node: - rl_node = tree.nodes.new(comp_layer_type) + if not render_layer_node: + render_layer_node = tree.nodes.new(comp_layer_type) # Get the enabled output sockets, that are the active passes for the # render. # We also exclude some layers. - exclude_sockets = ["Alpha", "Noisy Image"] + exclude_sockets = ["Image", "Alpha", "Noisy Image"] passes = [ socket - for socket in rl_node.outputs + for socket in render_layer_node.outputs if socket.enabled and socket.name not in exclude_sockets ] - old_output = None - - # Remove all output nodes that inlcude "AYON" in the name. - # There should be only one. - for node in tree.nodes: - if node.bl_idname == output_type and "AYON" in node.name: - old_output = node - break - # Create a new output node output = tree.nodes.new(output_type) @@ -240,46 +242,54 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): aov_file_products = [] - # For each active render pass, we add a new socket to the output node - # and link it - for rpass in passes: - if rpass.name == "Image": - if not multi_exr: - continue - pass_name = "rgba" - else: - pass_name = rpass.name - filename = f"{name}{aov_sep}{pass_name}.####" + old_links = { + link.from_socket.name: link for link in tree.links + if link.to_node == old_output_node} - slots.new(pass_name if multi_exr else filename) - - filepath = str(output_path / filename.lstrip("/")) - - aov_file_products.append((rpass.name, filepath)) - - if not old_output: - node_input = output.inputs[-1] - tree.links.new(rpass, node_input) + # Create a new socket for the beauty output + pass_name = "rgba" if multi_exr else "beauty" + slot, _ = _create_aov_slot( + name, aov_sep, slots, pass_name, multi_exr, output_path) + tree.links.new(render_layer_node.outputs["Image"], slot) # Create a new socket for the composite output pass_name = "composite" - filename = f"{name}{aov_sep}{pass_name}.####" - comp_socket = slots.new(pass_name if multi_exr else filename) - filepath = str(output_path / filename.lstrip("/")) + comp_socket, filepath = _create_aov_slot( + name, aov_sep, slots, pass_name, multi_exr, output_path) aov_file_products.append(("Composite", filepath)) - for link in tree.links: - if link.to_node == old_output: - socket_name = link.to_socket.name - new_socket = output.inputs.get(socket_name) - if new_socket: - tree.links.new(link.from_socket, new_socket) - elif comp_node and link.to_node == comp_node: - tree.links.new(link.from_socket, comp_socket) + # For each active render pass, we add a new socket to the output node + # and link it + for rpass in passes: + slot, filepath = _create_aov_slot( + name, aov_sep, slots, rpass.name, multi_exr, output_path) + aov_file_products.append((rpass.name, filepath)) + + # If the rpass was not connected with the old output node, we connect + # it with the new one. + if not old_links.get(rpass.name): + tree.links.new(rpass, slot) + + for link in list(old_links.values()): + # Check if the socket is still available in the new output node. + socket = output.inputs.get(link.to_socket.name) + # If it is, we connect it with the new output node. + if socket: + tree.links.new(link.from_socket, socket) + # Then, we remove the old link. + tree.links.remove(link) + + # If there's a composite node, we connect its input with the new output + if composite_node: + for link in tree.links: + if link.to_node == composite_node: + tree.links.new(link.from_socket, comp_socket) + break + + if old_output_node: + output.location = old_output_node.location + tree.nodes.remove(old_output_node) - if old_output: - output.location = old_output.location - tree.nodes.remove(old_output) output.name = "AYON File Output" output.label = "AYON File Output" From 14fc4ce6be35f02096ecc56cc865300ef67a705c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Feb 2024 17:51:52 +0800 Subject: [PATCH 016/149] Implementation of workfile creator --- .../max/plugins/create/create_workfile.py | 130 ++++++++++++++++++ .../max/plugins/publish/collect_members.py | 5 +- .../max/plugins/publish/collect_workfile.py | 14 +- 3 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 openpype/hosts/max/plugins/create/create_workfile.py diff --git a/openpype/hosts/max/plugins/create/create_workfile.py b/openpype/hosts/max/plugins/create/create_workfile.py new file mode 100644 index 0000000000..b43a353136 --- /dev/null +++ b/openpype/hosts/max/plugins/create/create_workfile.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +"""Creator plugin for creating workfiles.""" +from openpype import AYON_SERVER_ENABLED +from openpype.pipeline import CreatedInstance, AutoCreator, CreatorError +from openpype.client import get_asset_by_name, get_asset_name_identifier +from openpype.hosts.max.api import plugin +from openpype.hosts.max.api.lib import read, imprint +from pymxs import runtime as rt + + +class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): + """Workfile auto-creator.""" + identifier = "io.openpype.creators.max.workfile" + label = "Workfile" + family = "workfile" + icon = "fa5.file" + + default_variant = "Main" + + def create(self): + variant = self.default_variant + current_instance = next( + ( + instance for instance in self.create_context.instances + if instance.creator_identifier == self.identifier + ), None) + project_name = self.project_name + asset_name = self.create_context.get_current_asset_name() + task_name = self.create_context.get_current_task_name() + host_name = self.create_context.host_name + + if current_instance is None: + current_instance_asset = None + elif AYON_SERVER_ENABLED: + current_instance_asset = current_instance["folderPath"] + else: + current_instance_asset = current_instance["asset"] + + if current_instance is None: + asset_doc = get_asset_by_name(project_name, asset_name) + data = { + "task": task_name, + "variant": variant + } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name + + data.update( + self.get_dynamic_data( + variant, task_name, asset_doc, + project_name, host_name, current_instance) + ) + subset_name = self.get_subset_name( + variant, task_name, asset_doc, project_name, host_name + ) + self.log.info("Auto-creating workfile instance...") + instance_node = self.create_node(subset_name) + data["instance_node"] = instance_node.name + current_instance = CreatedInstance( + self.family, subset_name, data, self + ) + self._add_instance_to_context(current_instance) + imprint(instance_node.name, current_instance.data) + elif ( + current_instance_asset != asset_name + or current_instance["task"] != task_name + ): + # Update instance context if is not the same + asset_doc = get_asset_by_name(project_name, asset_name) + subset_name = self.get_subset_name( + variant, task_name, asset_doc, project_name, host_name + ) + asset_name = get_asset_name_identifier(asset_doc) + + if AYON_SERVER_ENABLED: + current_instance["folderPath"] = asset_name + else: + current_instance["asset"] = asset_name + current_instance["task"] = task_name + current_instance["subset"] = subset_name + + def collect_instances(self): + self.cache_subsets(self.collection_shared_data) + for instance in self.collection_shared_data["max_cached_subsets"].get(self.identifier, []): # noqa + if not rt.getNodeByName(instance): + continue + created_instance = CreatedInstance.from_existing( + read(rt.GetNodeByName(instance)), self + ) + self._add_instance_to_context(created_instance) + + + def update_instances(self, update_list): + for created_inst, changes in update_list: + instance_node = created_inst.get("instance_node") + new_values = { + key: changes[key].new_value + for key in changes.changed_keys + } + + imprint( + instance_node, + created_inst.data_to_store() + ) + + def remove_instances(self, instances): + """Remove specified instance from the scene. + + This is only removing `id` parameter so instance is no longer + instance, because it might contain valuable data for artist. + + """ + for instance in instances: + instance_node = rt.GetNodeByName( + instance.data.get("instance_node")) + if instance_node: + rt.Delete(instance_node) + + self._remove_instance_from_context(instance) + + + def create_node(self, subset_name): + if rt.getNodeByName(subset_name): + node = rt.getNodeByName(subset_name) + return node + node = rt.Container(name=subset_name) + node.isHidden = True + return node diff --git a/openpype/hosts/max/plugins/publish/collect_members.py b/openpype/hosts/max/plugins/publish/collect_members.py index 2970cf0e24..7cd646e0e7 100644 --- a/openpype/hosts/max/plugins/publish/collect_members.py +++ b/openpype/hosts/max/plugins/publish/collect_members.py @@ -12,7 +12,10 @@ class CollectMembers(pyblish.api.InstancePlugin): hosts = ['max'] def process(self, instance): - + if instance.data["family"] == "workfile": + self.log.debug("Skipping Actions for workfile family.") + self.log.debug("{}".format(instance.data["subset"])) + return if instance.data.get("instance_node"): container = rt.GetNodeByName(instance.data["instance_node"]) instance.data["members"] = [ diff --git a/openpype/hosts/max/plugins/publish/collect_workfile.py b/openpype/hosts/max/plugins/publish/collect_workfile.py index 0eb4bb731e..446175c0ed 100644 --- a/openpype/hosts/max/plugins/publish/collect_workfile.py +++ b/openpype/hosts/max/plugins/publish/collect_workfile.py @@ -6,15 +6,16 @@ import pyblish.api from pymxs import runtime as rt -class CollectWorkfile(pyblish.api.ContextPlugin): +class CollectWorkfile(pyblish.api.InstancePlugin): """Inject the current working file into context""" order = pyblish.api.CollectorOrder - 0.01 label = "Collect 3dsmax Workfile" hosts = ['max'] - def process(self, context): + def process(self, instance): """Inject the current working file.""" + context = instance.context folder = rt.maxFilePath file = rt.maxFileName if not folder or not file: @@ -23,15 +24,12 @@ class CollectWorkfile(pyblish.api.ContextPlugin): context.data['currentFile'] = current_file - filename, ext = os.path.splitext(file) - - task = context.data["task"] + ext = os.path.splitext(file)[-1].lstrip(".") data = {} # create instance - instance = context.create_instance(name=filename) - subset = 'workfile' + task.capitalize() + subset = instance.data["subset"] data.update({ "subset": subset, @@ -55,7 +53,7 @@ class CollectWorkfile(pyblish.api.ContextPlugin): }] instance.data.update(data) - + self.log.info('Collected data: {}'.format(data)) self.log.info('Collected instance: {}'.format(file)) self.log.info('Scene path: {}'.format(current_file)) self.log.info('staging Dir: {}'.format(folder)) From 8bac54fcf0745645489a29fc2e78bac1d9d4c284 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Feb 2024 17:54:39 +0800 Subject: [PATCH 017/149] move back the subset name before dynamic data --- openpype/hosts/max/plugins/create/create_workfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_workfile.py b/openpype/hosts/max/plugins/create/create_workfile.py index b43a353136..70944b3e2c 100644 --- a/openpype/hosts/max/plugins/create/create_workfile.py +++ b/openpype/hosts/max/plugins/create/create_workfile.py @@ -38,6 +38,9 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) + subset_name = self.get_subset_name( + variant, task_name, asset_doc, project_name, host_name + ) data = { "task": task_name, "variant": variant @@ -52,9 +55,6 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): variant, task_name, asset_doc, project_name, host_name, current_instance) ) - subset_name = self.get_subset_name( - variant, task_name, asset_doc, project_name, host_name - ) self.log.info("Auto-creating workfile instance...") instance_node = self.create_node(subset_name) data["instance_node"] = instance_node.name From af022f3561ac96b3d891b52238219ddd913d5f5c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Feb 2024 17:59:20 +0800 Subject: [PATCH 018/149] hound shut --- openpype/hosts/max/plugins/create/create_workfile.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_workfile.py b/openpype/hosts/max/plugins/create/create_workfile.py index 70944b3e2c..25213871d8 100644 --- a/openpype/hosts/max/plugins/create/create_workfile.py +++ b/openpype/hosts/max/plugins/create/create_workfile.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin for creating workfiles.""" from openpype import AYON_SERVER_ENABLED -from openpype.pipeline import CreatedInstance, AutoCreator, CreatorError +from openpype.pipeline import CreatedInstance, AutoCreator from openpype.client import get_asset_by_name, get_asset_name_identifier from openpype.hosts.max.api import plugin from openpype.hosts.max.api.lib import read, imprint @@ -91,15 +91,9 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): ) self._add_instance_to_context(created_instance) - def update_instances(self, update_list): for created_inst, changes in update_list: instance_node = created_inst.get("instance_node") - new_values = { - key: changes[key].new_value - for key in changes.changed_keys - } - imprint( instance_node, created_inst.data_to_store() @@ -120,7 +114,6 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): self._remove_instance_from_context(instance) - def create_node(self, subset_name): if rt.getNodeByName(subset_name): node = rt.getNodeByName(subset_name) From 2248240306fdf01dc2f756982b11304c48304cc5 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Feb 2024 18:00:08 +0800 Subject: [PATCH 019/149] hound shut --- openpype/hosts/max/plugins/create/create_workfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/create/create_workfile.py b/openpype/hosts/max/plugins/create/create_workfile.py index 25213871d8..4ec3c6d3ad 100644 --- a/openpype/hosts/max/plugins/create/create_workfile.py +++ b/openpype/hosts/max/plugins/create/create_workfile.py @@ -92,7 +92,7 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): self._add_instance_to_context(created_instance) def update_instances(self, update_list): - for created_inst, changes in update_list: + for created_inst, _ in update_list: instance_node = created_inst.get("instance_node") imprint( instance_node, From bd8135f4dcea13240c8a894b9f70472b7a535851 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Feb 2024 18:01:15 +0800 Subject: [PATCH 020/149] hound shut --- openpype/hosts/max/plugins/create/create_workfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/create/create_workfile.py b/openpype/hosts/max/plugins/create/create_workfile.py index 4ec3c6d3ad..30692ccd06 100644 --- a/openpype/hosts/max/plugins/create/create_workfile.py +++ b/openpype/hosts/max/plugins/create/create_workfile.py @@ -93,7 +93,7 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): def update_instances(self, update_list): for created_inst, _ in update_list: - instance_node = created_inst.get("instance_node") + instance_node = created_inst.get("instance_node") imprint( instance_node, created_inst.data_to_store() From da5a0589e6a0e2af1f0971442d46a7b99cf91d97 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:50:06 +0000 Subject: [PATCH 021/149] feat: implemented has_unsaved_changes --- client/ayon_core/hosts/max/api/pipeline.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index ff5ef0640b..b0c85c070b 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -61,8 +61,7 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): lib.check_colorspace) def has_unsaved_changes(self): - # TODO: how to get it from 3dsmax? - return True + return rt.getSaveRequired() def get_workfile_extensions(self): return [".max"] From 8bd7fde33e7fc331c268bfa4142e39e94b2298c4 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:50:43 +0000 Subject: [PATCH 022/149] feat: save_scene to use host functions to check if saving is required --- .../hosts/max/plugins/publish/save_scene.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/client/ayon_core/hosts/max/plugins/publish/save_scene.py index a40788ab41..37ff38bc59 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scene.py +++ b/client/ayon_core/hosts/max/plugins/publish/save_scene.py @@ -1,11 +1,9 @@ import pyblish.api -import os +from openpype.pipeline import registered_host class SaveCurrentScene(pyblish.api.ContextPlugin): - """Save current scene - - """ + """Save current scene""" label = "Save current file" order = pyblish.api.ExtractorOrder - 0.49 @@ -13,9 +11,13 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): families = ["maxrender", "workfile"] def process(self, context): - from pymxs import runtime as rt - folder = rt.maxFilePath - file = rt.maxFileName - current = os.path.join(folder, file) - assert context.data["currentFile"] == current - rt.saveMaxFile(current) + host = registered_host() + current_file = host.get_current_workfile() + + assert context.data["currentFile"] == current_file + + if host.workfile_has_unsaved_changes(): + self.log.info(f"Saving current file: {current_file}") + host.save_workfile(current_file) + else: + self.log.debug("No unsaved changes, skipping file save..")") \ No newline at end of file From 3cddbb809e581cf27f2ee562f398af99aba45b8f Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:51:04 +0000 Subject: [PATCH 023/149] feat: startup.ms to restore default view menu --- client/ayon_core/hosts/max/startup/startup.ms | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/hosts/max/startup/startup.ms b/client/ayon_core/hosts/max/startup/startup.ms index b80ead4b74..4c597901f3 100644 --- a/client/ayon_core/hosts/max/startup/startup.ms +++ b/client/ayon_core/hosts/max/startup/startup.ms @@ -8,5 +8,8 @@ local pythonpath = systemTools.getEnvVariable "MAX_PYTHONPATH" systemTools.setEnvVariable "PYTHONPATH" pythonpath + /*opens the create menu on startup to ensure users are presented with a useful default view.*/ + max create mode + python.ExecuteFile startup ) \ No newline at end of file From 1d9a4dd737b12a33a67acdf66ad75e3e9fad764d Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:56:31 +0000 Subject: [PATCH 024/149] refactor: replaced has_unsaved_changes with workfile_has_unsaved_changes --- client/ayon_core/hosts/max/api/pipeline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index b0c85c070b..5f20891329 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -61,6 +61,7 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): lib.check_colorspace) def has_unsaved_changes(self): + def workfile_has_unsaved_changes(self): return rt.getSaveRequired() def get_workfile_extensions(self): From 57815d19a1e9e42d7abe24721b121d6eb1b5ff45 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 16:03:02 +0000 Subject: [PATCH 025/149] chore: removed has_unsaved_changes --- client/ayon_core/hosts/max/api/pipeline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index 5f20891329..2dc3eb6da8 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -60,7 +60,6 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): rt.callbacks.addScript(rt.Name('filePostOpen'), lib.check_colorspace) - def has_unsaved_changes(self): def workfile_has_unsaved_changes(self): return rt.getSaveRequired() From 5edf44903cd214d156833af6630a417c19a7ec81 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:13:17 +0100 Subject: [PATCH 026/149] use AYON prefix in context environment variables --- client/ayon_core/cli_commands.py | 14 +++++- .../hooks/pre_create_extra_workdir_folders.py | 2 +- client/ayon_core/host/host.py | 6 +-- client/ayon_core/host/interfaces.py | 2 +- .../hosts/aftereffects/api/launch_logic.py | 6 +-- .../ayon_core/hosts/blender/api/pipeline.py | 6 +-- client/ayon_core/hosts/blender/api/workio.py | 2 +- client/ayon_core/hosts/flame/api/workio.py | 2 +- .../hosts/flame/plugins/load/load_clip.py | 2 +- .../flame/plugins/load/load_clip_batch.py | 2 +- client/ayon_core/hosts/fusion/addon.py | 2 +- client/ayon_core/hosts/fusion/api/pipeline.py | 2 +- client/ayon_core/hosts/fusion/api/plugin.py | 2 +- .../fusion/hooks/pre_fusion_profile_hook.py | 2 +- .../hosts/fusion/hooks/pre_fusion_setup.py | 2 +- client/ayon_core/hosts/harmony/api/workio.py | 2 +- .../publish/validate_scene_settings.py | 2 +- client/ayon_core/hosts/hiero/api/workio.py | 2 +- .../hosts/houdini/hooks/set_paths.py | 2 +- client/ayon_core/hosts/max/hooks/set_paths.py | 2 +- client/ayon_core/hosts/maya/api/pipeline.py | 6 +-- .../maya/api/shader_definition_editor.py | 2 +- client/ayon_core/hosts/maya/api/workio.py | 2 +- .../hosts/maya/hooks/pre_copy_mel.py | 2 +- .../maya/plugins/publish/collect_render.py | 2 +- .../ayon_core/hosts/maya/startup/userSetup.py | 2 +- client/ayon_core/hosts/nuke/api/lib.py | 8 ++-- client/ayon_core/hosts/nuke/api/workio.py | 2 +- .../hosts/nuke/startup/custom_write_node.py | 2 +- .../ayon_core/hosts/photoshop/api/pipeline.py | 2 +- .../plugins/publish/collect_batch_data.py | 8 ++-- client/ayon_core/hosts/resolve/api/workio.py | 4 +- .../hosts/traypublisher/api/pipeline.py | 4 +- .../plugins/create/create_from_settings.py | 2 +- .../ayon_core/hosts/tvpaint/api/pipeline.py | 6 +-- .../plugins/publish/collect_workfile_data.py | 4 +- .../publish/validate_workfile_project_name.py | 2 +- .../ayon_core/hosts/unreal/api/rendering.py | 2 +- .../unreal/hooks/pre_workfile_preparation.py | 2 +- client/ayon_core/lib/applications.py | 14 +++--- client/ayon_core/lib/log.py | 2 +- .../launcher_actions/ClockifyStart.py | 8 ++-- .../clockify/launcher_actions/ClockifySync.py | 2 +- .../publish/submit_aftereffects_deadline.py | 10 ++-- .../publish/submit_blender_deadline.py | 10 ++-- .../plugins/publish/submit_fusion_deadline.py | 10 ++-- .../publish/submit_harmony_deadline.py | 10 ++-- .../publish/submit_houdini_cache_deadline.py | 10 ++-- .../publish/submit_houdini_render_deadline.py | 10 ++-- .../plugins/publish/submit_max_deadline.py | 10 ++-- .../plugins/publish/submit_maya_deadline.py | 10 ++-- .../submit_maya_remote_publish_deadline.py | 8 ++-- .../plugins/publish/submit_nuke_deadline.py | 8 ++-- .../publish/submit_publish_cache_job.py | 8 ++-- .../plugins/publish/submit_publish_job.py | 8 ++-- .../custom/plugins/GlobalJobPreLoad.py | 21 +++++--- client/ayon_core/modules/royalrender/lib.py | 4 +- .../publish/create_publish_royalrender_job.py | 8 ++-- .../perjob/m50__openpype_publish_render.py | 24 ++++++---- client/ayon_core/pipeline/actions.py | 2 +- client/ayon_core/pipeline/anatomy.py | 2 +- client/ayon_core/pipeline/context_tools.py | 48 +++++++++---------- client/ayon_core/pipeline/create/context.py | 2 +- .../pipeline/create/legacy_create.py | 2 +- .../ayon_core/pipeline/create/subset_name.py | 4 +- .../pipeline/farm/pyblish_functions.py | 6 +-- client/ayon_core/pipeline/load/plugins.py | 2 +- client/ayon_core/pipeline/publish/lib.py | 2 +- .../pipeline/workfile/build_workfile.py | 4 +- .../pipeline/workfile/path_resolving.py | 2 +- .../workfile/workfile_template_builder.py | 10 ++-- .../plugins/actions/open_file_explorer.py | 8 ++-- .../plugins/load/delete_old_versions.py | 2 +- .../publish/collect_anatomy_context_data.py | 2 +- .../publish/collect_context_entities.py | 1 - .../publish/collect_from_create_context.py | 6 +-- .../plugins/publish/collect_host_name.py | 8 ++-- .../plugins/publish/collect_rendered_files.py | 6 +-- .../scripts/non_python_host_launch.py | 4 +- client/ayon_core/settings/lib.py | 6 +-- .../tools/experimental_tools/tools_def.py | 2 +- .../tools/launcher/models/actions.py | 18 ++++--- client/ayon_core/tools/publisher/control.py | 4 +- client/ayon_core/tools/texture_copy/app.py | 4 +- .../tools/workfile_template_build/window.py | 2 +- 85 files changed, 257 insertions(+), 225 deletions(-) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index c07b72afdf..31429c488b 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -73,6 +73,18 @@ class Commands: import pyblish.api import pyblish.util + # Fix older jobs + for src_key, dst_key in ( + ("AVALON_PROJECT", "AYON_PROJECT_NAME"), + ("AVALON_ASSET", "AYON_FOLDER_PATH"), + ("AVALON_TASK", "AYON_TASK_NAME"), + ("AVALON_WORKDIR", "AYON_WORKDIR"), + ("AVALON_APP_NAME", "AYON_APP_NAME"), + ("AVALON_APP", "AYON_HOST_NAME"), + ): + if src_key in os.environ and dst_key not in os.environ: + os.environ[dst_key] = os.environ[src_key] + log = Logger.get_logger("CLI-publish") install_ayon_plugins() @@ -87,7 +99,7 @@ class Commands: if not any(paths): raise RuntimeError("No publish paths specified") - app_full_name = os.getenv("AVALON_APP_NAME") + app_full_name = os.getenv("AYON_APP_NAME") if app_full_name: context = get_global_context() env = get_app_environments_for_context( diff --git a/client/ayon_core/hooks/pre_create_extra_workdir_folders.py b/client/ayon_core/hooks/pre_create_extra_workdir_folders.py index 6116d5fbd3..72c6bf2f68 100644 --- a/client/ayon_core/hooks/pre_create_extra_workdir_folders.py +++ b/client/ayon_core/hooks/pre_create_extra_workdir_folders.py @@ -21,7 +21,7 @@ class CreateWorkdirExtraFolders(PreLaunchHook): return env = self.data.get("env") or {} - workdir = env.get("AVALON_WORKDIR") + workdir = env.get("AYON_WORKDIR") if not workdir or not os.path.exists(workdir): return diff --git a/client/ayon_core/host/host.py b/client/ayon_core/host/host.py index 2dd98c8126..51dff9d558 100644 --- a/client/ayon_core/host/host.py +++ b/client/ayon_core/host/host.py @@ -106,7 +106,7 @@ class HostBase(object): Union[str, None]: Current project name. """ - return os.environ.get("AVALON_PROJECT") + return os.environ.get("AYON_PROJECT_NAME") def get_current_asset_name(self): """ @@ -114,7 +114,7 @@ class HostBase(object): Union[str, None]: Current asset name. """ - return os.environ.get("AVALON_ASSET") + return os.environ.get("AYON_FOLDER_PATH") def get_current_task_name(self): """ @@ -122,7 +122,7 @@ class HostBase(object): Union[str, None]: Current task name. """ - return os.environ.get("AVALON_TASK") + return os.environ.get("AYON_TASK_NAME") def get_current_context(self): """Get current context information. diff --git a/client/ayon_core/host/interfaces.py b/client/ayon_core/host/interfaces.py index 7c6057acf0..7157ad6f7e 100644 --- a/client/ayon_core/host/interfaces.py +++ b/client/ayon_core/host/interfaces.py @@ -234,7 +234,7 @@ class IWorkfileHost: str: Path to new workdir. """ - return session["AVALON_WORKDIR"] + return session["AYON_WORKDIR"] # --- Deprecated method names --- def file_extensions(self): diff --git a/client/ayon_core/hosts/aftereffects/api/launch_logic.py b/client/ayon_core/hosts/aftereffects/api/launch_logic.py index 3d09f4d53c..8c54908fe5 100644 --- a/client/ayon_core/hosts/aftereffects/api/launch_logic.py +++ b/client/ayon_core/hosts/aftereffects/api/launch_logic.py @@ -298,11 +298,11 @@ class AfterEffectsRoute(WebSocketRoute): log.info("Setting context change") log.info("project {} asset {} ".format(project, asset)) if project: - os.environ["AVALON_PROJECT"] = project + os.environ["AYON_PROJECT_NAME"] = project if asset: - os.environ["AVALON_ASSET"] = asset + os.environ["AYON_FOLDER_PATH"] = asset if task: - os.environ["AVALON_TASK"] = task + os.environ["AYON_TASK_NAME"] = task async def read(self): log.debug("aftereffects.read client calls server server calls " diff --git a/client/ayon_core/hosts/blender/api/pipeline.py b/client/ayon_core/hosts/blender/api/pipeline.py index 77731a0fd3..a49afeea6b 100644 --- a/client/ayon_core/hosts/blender/api/pipeline.py +++ b/client/ayon_core/hosts/blender/api/pipeline.py @@ -272,7 +272,7 @@ def set_resolution(data): def on_new(): - project = os.environ.get("AVALON_PROJECT") + project = os.environ.get("AYON_PROJECT_NAME") settings = get_project_settings(project).get("blender") set_resolution_startup = settings.get("set_resolution_startup") @@ -293,7 +293,7 @@ def on_new(): def on_open(): - project = os.environ.get("AVALON_PROJECT") + project = os.environ.get("AYON_PROJECT_NAME") settings = get_project_settings(project).get("blender") set_resolution_startup = settings.get("set_resolution_startup") @@ -379,7 +379,7 @@ def _on_task_changed(): # `directory` attribute, so it opens in that directory (does it?). # https://docs.blender.org/api/blender2.8/bpy.types.Operator.html#calling-a-file-selector # https://docs.blender.org/api/blender2.8/bpy.types.WindowManager.html#bpy.types.WindowManager.fileselect_add - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") log.debug("New working directory: %s", workdir) diff --git a/client/ayon_core/hosts/blender/api/workio.py b/client/ayon_core/hosts/blender/api/workio.py index a8f6193abc..e0f333843a 100644 --- a/client/ayon_core/hosts/blender/api/workio.py +++ b/client/ayon_core/hosts/blender/api/workio.py @@ -82,7 +82,7 @@ def file_extensions() -> List[str]: def work_root(session: dict) -> str: """Return the default root to browse for work files.""" - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = session.get("AVALON_SCENEDIR") if scene_dir: return str(Path(work_dir, scene_dir)) diff --git a/client/ayon_core/hosts/flame/api/workio.py b/client/ayon_core/hosts/flame/api/workio.py index 0e3cb7f5fd..eef10a4847 100644 --- a/client/ayon_core/hosts/flame/api/workio.py +++ b/client/ayon_core/hosts/flame/api/workio.py @@ -34,4 +34,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip.py b/client/ayon_core/hosts/flame/plugins/load/load_clip.py index 6f35196932..47d0331255 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip.py @@ -70,7 +70,7 @@ class LoadClip(opfapi.ClipLoader): self.log.info("Loading with colorspace: `{}`".format(colorspace)) # create workfile path - workfile_dir = os.environ["AVALON_WORKDIR"] + workfile_dir = os.environ["AYON_WORKDIR"] openclip_dir = os.path.join( workfile_dir, clip_name ) diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py index a66bf53622..46ed9ef58b 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py @@ -69,7 +69,7 @@ class LoadClipBatch(opfapi.ClipLoader): self.log.info("Loading with colorspace: `{}`".format(colorspace)) # create workfile path - workfile_dir = options.get("workdir") or os.environ["AVALON_WORKDIR"] + workfile_dir = options.get("workdir") or os.environ["AYON_WORKDIR"] openclip_dir = os.path.join( workfile_dir, clip_name ) diff --git a/client/ayon_core/hosts/fusion/addon.py b/client/ayon_core/hosts/fusion/addon.py index 391ee770c4..54e48ea7bf 100644 --- a/client/ayon_core/hosts/fusion/addon.py +++ b/client/ayon_core/hosts/fusion/addon.py @@ -22,7 +22,7 @@ def get_fusion_version(app_name): The function is triggered by the prelaunch hooks to get the fusion version. `app_name` is obtained by prelaunch hooks from the - `launch_context.env.get("AVALON_APP_NAME")`. + `launch_context.env.get("AYON_APP_NAME")`. To get a correct Fusion version, a version number should be present in the `applications/fusion/variants` key diff --git a/client/ayon_core/hosts/fusion/api/pipeline.py b/client/ayon_core/hosts/fusion/api/pipeline.py index 7c480704a5..0e9e0724c7 100644 --- a/client/ayon_core/hosts/fusion/api/pipeline.py +++ b/client/ayon_core/hosts/fusion/api/pipeline.py @@ -135,7 +135,7 @@ class FusionHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): return current_filepath def work_root(self, session): - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = session.get("AVALON_SCENEDIR") if scene_dir: return os.path.join(work_dir, scene_dir) diff --git a/client/ayon_core/hosts/fusion/api/plugin.py b/client/ayon_core/hosts/fusion/api/plugin.py index 80e194ea68..0d9409b4f5 100644 --- a/client/ayon_core/hosts/fusion/api/plugin.py +++ b/client/ayon_core/hosts/fusion/api/plugin.py @@ -135,7 +135,7 @@ class GenericCreateSaver(Creator): ext = data["creator_attributes"]["image_format"] # Subset change detected - workdir = os.path.normpath(os.getenv("AVALON_WORKDIR")) + workdir = os.path.normpath(os.getenv("AYON_WORKDIR")) formatting_data.update({ "workdir": workdir, "frame": "0" * frame_padding, diff --git a/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py b/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py index f63aaa1eb4..5aa2783129 100644 --- a/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -131,7 +131,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): ) = self.get_copy_fusion_prefs_settings() # Get launched application context and return correct app version - app_name = self.launch_context.env.get("AVALON_APP_NAME") + app_name = self.launch_context.env.get("AYON_APP_NAME") app_version = get_fusion_version(app_name) if app_version is None: version_names = ", ".join(str(x) for x in FUSION_VERSIONS_DICT) diff --git a/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py b/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py index 7cfa9d0a26..7eaf2ddc02 100644 --- a/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py +++ b/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py @@ -28,7 +28,7 @@ class FusionPrelaunch(PreLaunchHook): def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 - app_data = self.launch_context.env.get("AVALON_APP_NAME") + app_data = self.launch_context.env.get("AYON_APP_NAME") app_version = get_fusion_version(app_data) if not app_version: raise ApplicationLaunchFailed( diff --git a/client/ayon_core/hosts/harmony/api/workio.py b/client/ayon_core/hosts/harmony/api/workio.py index 8df5ede917..1f95148e75 100644 --- a/client/ayon_core/hosts/harmony/api/workio.py +++ b/client/ayon_core/hosts/harmony/api/workio.py @@ -74,4 +74,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py b/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py index 0cf96e70b0..6d46fbcd33 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py @@ -77,7 +77,7 @@ class ValidateSceneSettings(pyblish.api.InstancePlugin): expected_settings.pop("resolutionWidth") expected_settings.pop("resolutionHeight") - if (any(re.search(pattern, os.getenv('AVALON_TASK')) + if (any(re.search(pattern, os.getenv('AYON_TASK_NAME')) for pattern in self.skip_timelines_check)): self.log.info("Skipping frames check because of " "task name and pattern {}".format( diff --git a/client/ayon_core/hosts/hiero/api/workio.py b/client/ayon_core/hosts/hiero/api/workio.py index 14d9439344..4c2416ca38 100644 --- a/client/ayon_core/hosts/hiero/api/workio.py +++ b/client/ayon_core/hosts/hiero/api/workio.py @@ -70,4 +70,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/houdini/hooks/set_paths.py b/client/ayon_core/hosts/houdini/hooks/set_paths.py index 1f24a8dd7d..7eb346cc74 100644 --- a/client/ayon_core/hosts/houdini/hooks/set_paths.py +++ b/client/ayon_core/hosts/houdini/hooks/set_paths.py @@ -10,7 +10,7 @@ class SetPath(PreLaunchHook): launch_types = {LaunchTypes.local} def execute(self): - workdir = self.launch_context.env.get("AVALON_WORKDIR", "") + workdir = self.launch_context.env.get("AYON_WORKDIR", "") if not workdir: self.log.warning("BUG: Workdir is not filled.") return diff --git a/client/ayon_core/hosts/max/hooks/set_paths.py b/client/ayon_core/hosts/max/hooks/set_paths.py index c18fd29295..0ee1b0dab7 100644 --- a/client/ayon_core/hosts/max/hooks/set_paths.py +++ b/client/ayon_core/hosts/max/hooks/set_paths.py @@ -10,7 +10,7 @@ class SetPath(PreLaunchHook): launch_types = {LaunchTypes.local} def execute(self): - workdir = self.launch_context.env.get("AVALON_WORKDIR", "") + workdir = self.launch_context.env.get("AYON_WORKDIR", "") if not workdir: self.log.warning("BUG: Workdir is not filled.") return diff --git a/client/ayon_core/hosts/maya/api/pipeline.py b/client/ayon_core/hosts/maya/api/pipeline.py index dc6353618a..e58316030e 100644 --- a/client/ayon_core/hosts/maya/api/pipeline.py +++ b/client/ayon_core/hosts/maya/api/pipeline.py @@ -246,7 +246,7 @@ def _set_project(): None """ - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") try: os.makedirs(workdir) @@ -628,7 +628,7 @@ def on_task_changed(): # Run menu.update_menu_task_label() - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") if os.path.exists(workdir): log.info("Updating Maya workspace for task change to %s", workdir) _set_project() @@ -677,7 +677,7 @@ def workfile_save_before_xgen(event): import xgenm - current_work_dir = os.getenv("AVALON_WORKDIR").replace("\\", "/") + current_work_dir = os.getenv("AYON_WORKDIR").replace("\\", "/") expected_work_dir = event.data["workdir_path"].replace("\\", "/") if current_work_dir == expected_work_dir: return diff --git a/client/ayon_core/hosts/maya/api/shader_definition_editor.py b/client/ayon_core/hosts/maya/api/shader_definition_editor.py index 04e8dded6f..bfa531eb87 100644 --- a/client/ayon_core/hosts/maya/api/shader_definition_editor.py +++ b/client/ayon_core/hosts/maya/api/shader_definition_editor.py @@ -12,7 +12,7 @@ import gridfs DEFINITION_FILENAME = "{}/maya/shader_definition.txt".format( - os.getenv("AVALON_PROJECT")) + os.getenv("AYON_PROJECT_NAME")) class ShaderDefinitionsEditor(QtWidgets.QWidget): diff --git a/client/ayon_core/hosts/maya/api/workio.py b/client/ayon_core/hosts/maya/api/workio.py index 8c31974c73..ff6c11eb4f 100644 --- a/client/ayon_core/hosts/maya/api/workio.py +++ b/client/ayon_core/hosts/maya/api/workio.py @@ -35,7 +35,7 @@ def current_file(): def work_root(session): - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = None # Query scene file rule from workspace.mel if it exists in WORKDIR diff --git a/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py b/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py index 7198f98131..03ca8661bd 100644 --- a/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py +++ b/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py @@ -12,7 +12,7 @@ class PreCopyMel(PreLaunchHook): def execute(self): project_doc = self.data["project_doc"] - workdir = self.launch_context.env.get("AVALON_WORKDIR") + workdir = self.launch_context.env.get("AYON_WORKDIR") if not workdir: self.log.warning("BUG: Workdir is not filled.") return diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index e4221a091c..7daab19f4a 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -13,7 +13,7 @@ Requires: context -> workspaceDir context -> user - session -> AVALON_ASSET + session -> AYON_FOLDER_PATH Optional: diff --git a/client/ayon_core/hosts/maya/startup/userSetup.py b/client/ayon_core/hosts/maya/startup/userSetup.py index 882f2df27c..22b776915c 100644 --- a/client/ayon_core/hosts/maya/startup/userSetup.py +++ b/client/ayon_core/hosts/maya/startup/userSetup.py @@ -38,7 +38,7 @@ if explicit_plugins_loading["enabled"]: key = "AYON_OPEN_WORKFILE_POST_INITIALIZATION" if bool(int(os.environ.get(key, "0"))): def _log_and_open(): - path = os.environ["AVALON_LAST_WORKFILE"] + path = os.environ["AYON_LAST_WORKFILE"] print("Opening \"{}\"".format(path)) cmds.file(path, open=True, force=True) cmds.evalDeferred( diff --git a/client/ayon_core/hosts/nuke/api/lib.py b/client/ayon_core/hosts/nuke/api/lib.py index 2ac33de68e..c320df9361 100644 --- a/client/ayon_core/hosts/nuke/api/lib.py +++ b/client/ayon_core/hosts/nuke/api/lib.py @@ -120,7 +120,7 @@ def deprecated(new_destination): class Context: main_window = None context_action_item = None - project_name = os.getenv("AVALON_PROJECT") + project_name = os.getenv("AYON_PROJECT_NAME") # Workfile related code workfiles_launched = False workfiles_tool_timer = None @@ -2605,7 +2605,7 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies. def set_favorites(self): from .utils import set_context_favorites - work_dir = os.getenv("AVALON_WORKDIR") + work_dir = os.getenv("AYON_WORKDIR") asset = get_current_asset_name() favorite_items = OrderedDict() @@ -2953,7 +2953,7 @@ def process_workfile_builder(): create_fv_on = workfile_builder.get("create_first_version") or None builder_on = workfile_builder.get("builder_on_start") or None - last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE") + last_workfile_path = os.environ.get("AYON_LAST_WORKFILE") # generate first version in file not existing and feature is enabled if create_fv_on and not os.path.exists(last_workfile_path): @@ -3203,7 +3203,7 @@ class DirmapCache: @classmethod def project_name(cls): if cls._project_name is None: - cls._project_name = os.getenv("AVALON_PROJECT") + cls._project_name = os.getenv("AYON_PROJECT_NAME") return cls._project_name @classmethod diff --git a/client/ayon_core/hosts/nuke/api/workio.py b/client/ayon_core/hosts/nuke/api/workio.py index 98e59eff71..b2445fd3d2 100644 --- a/client/ayon_core/hosts/nuke/api/workio.py +++ b/client/ayon_core/hosts/nuke/api/workio.py @@ -68,7 +68,7 @@ def current_file(): def work_root(session): - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = session.get("AVALON_SCENEDIR") if scene_dir: path = os.path.join(work_dir, scene_dir) 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 01e255d0c0..89dfde297c 100644 --- a/client/ayon_core/hosts/nuke/startup/custom_write_node.py +++ b/client/ayon_core/hosts/nuke/startup/custom_write_node.py @@ -112,7 +112,7 @@ class WriteNodeKnobSettingPanel(nukescripts.PythonPanel): for write_node in write_selected_nodes: # data for mapping the path data = { - "work": os.getenv("AVALON_WORKDIR"), + "work": os.getenv("AYON_WORKDIR"), "subset": write_node["name"].value(), "frame": "#" * frame_padding, "ext": ext diff --git a/client/ayon_core/hosts/photoshop/api/pipeline.py b/client/ayon_core/hosts/photoshop/api/pipeline.py index 046ec8e6ee..ebde175053 100644 --- a/client/ayon_core/hosts/photoshop/api/pipeline.py +++ b/client/ayon_core/hosts/photoshop/api/pipeline.py @@ -62,7 +62,7 @@ class PhotoshopHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): return None def work_root(self, session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") def open_workfile(self, filepath): lib.stub().open(filepath) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py index 6639040bd7..0ed891c8cf 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py @@ -52,10 +52,10 @@ class CollectBatchData(pyblish.api.ContextPlugin): assert os.path.exists(batch_dir), \ "Folder {} doesn't exist".format(batch_dir) - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") if project_name is None: raise AssertionError( - "Environment `AVALON_PROJECT` was not found." + "Environment `AYON_PROJECT_NAME` was not found." "Could not set project `root` which may cause issues." ) @@ -68,8 +68,8 @@ class CollectBatchData(pyblish.api.ContextPlugin): batch_data["context"] ) - os.environ["AVALON_ASSET"] = asset_name - os.environ["AVALON_TASK"] = task_name + os.environ["AYON_FOLDER_PATH"] = asset_name + os.environ["AYON_TASK_NAME"] = task_name context.data["asset"] = asset_name context.data["task"] = task_name diff --git a/client/ayon_core/hosts/resolve/api/workio.py b/client/ayon_core/hosts/resolve/api/workio.py index 5e4865ddc5..b6c2f63432 100644 --- a/client/ayon_core/hosts/resolve/api/workio.py +++ b/client/ayon_core/hosts/resolve/api/workio.py @@ -79,7 +79,7 @@ def open_file(filepath): def current_file(): pm = get_project_manager() file_ext = file_extensions()[0] - workdir_path = os.getenv("AVALON_WORKDIR") + workdir_path = os.getenv("AYON_WORKDIR") project = pm.GetCurrentProject() project_name = project.GetName() file_name = project_name + file_ext @@ -93,4 +93,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/traypublisher/api/pipeline.py b/client/ayon_core/hosts/traypublisher/api/pipeline.py index 88fa3239a5..f4526ddf4b 100644 --- a/client/ayon_core/hosts/traypublisher/api/pipeline.py +++ b/client/ayon_core/hosts/traypublisher/api/pipeline.py @@ -22,7 +22,7 @@ class TrayPublisherHost(HostBase, IPublishHost): name = "traypublisher" def install(self): - os.environ["AVALON_APP"] = self.name + os.environ["AYON_HOST_NAME"] = self.name pyblish.api.register_host("traypublisher") pyblish.api.register_plugin_path(PUBLISH_PATH) @@ -40,7 +40,7 @@ class TrayPublisherHost(HostBase, IPublishHost): def set_project_name(self, project_name): # TODO Deregister project specific plugins and register new project # plugins - os.environ["AVALON_PROJECT"] = project_name + os.environ["AYON_PROJECT_NAME"] = project_name HostContext.set_project_name(project_name) diff --git a/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py b/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py index 20f8dd792a..cc1429901d 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py +++ b/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py @@ -8,7 +8,7 @@ log = Logger.get_logger(__name__) def initialize(): from ayon_core.hosts.traypublisher.api.plugin import SettingsCreator - project_name = os.environ["AVALON_PROJECT"] + project_name = os.environ["AYON_PROJECT_NAME"] project_settings = get_project_settings(project_name) simple_creators = project_settings["traypublisher"]["simple_creators"] diff --git a/client/ayon_core/hosts/tvpaint/api/pipeline.py b/client/ayon_core/hosts/tvpaint/api/pipeline.py index d636e68cfa..78a0c5270d 100644 --- a/client/ayon_core/hosts/tvpaint/api/pipeline.py +++ b/client/ayon_core/hosts/tvpaint/api/pipeline.py @@ -68,7 +68,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): log.info("AYON - Installing TVPaint integration") # Create workdir folder if does not exist yet - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") if not os.path.exists(workdir): os.makedirs(workdir) @@ -155,7 +155,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): return execute_george(george_script) def work_root(self, session): - return session["AVALON_WORKDIR"] + return session["AYON_WORKDIR"] def get_current_workfile(self): return execute_george("tv_GetProjectName") @@ -174,7 +174,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): # Setup project settings if its the template that's launched. # TODO also check for template creation when it's possible to define # templates - last_workfile = os.environ.get("AVALON_LAST_WORKFILE") + last_workfile = os.environ.get("AYON_LAST_WORKFILE") if not last_workfile or os.path.exists(last_workfile): return diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py index 05ceb143e9..a6b6f05dc9 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py @@ -85,8 +85,8 @@ class CollectWorkfileData(pyblish.api.ContextPlugin): if workfile_context: # Change current context with context from workfile key_map = ( - ("AVALON_ASSET", "asset_name"), - ("AVALON_TASK", "task_name") + ("AYON_FOLDER_PATH", "asset_name"), + ("AYON_TASK_NAME", "task_name") ) for env_key, key in key_map: os.environ[env_key] = workfile_context[key] diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py b/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py index be3259bfd8..5b42842717 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py @@ -6,7 +6,7 @@ class ValidateWorkfileProjectName(pyblish.api.ContextPlugin): """Validate project name stored in workfile metadata. It is not possible to publish from different project than is set in - environment variable "AVALON_PROJECT". + environment variable "AYON_PROJECT_NAME". """ label = "Validate Workfile Project Name" diff --git a/client/ayon_core/hosts/unreal/api/rendering.py b/client/ayon_core/hosts/unreal/api/rendering.py index 8717788732..4a15ceb89a 100644 --- a/client/ayon_core/hosts/unreal/api/rendering.py +++ b/client/ayon_core/hosts/unreal/api/rendering.py @@ -60,7 +60,7 @@ def start_rendering(): inst_data.append(data) try: - project = os.environ.get("AVALON_PROJECT") + project = os.environ.get("AYON_PROJECT_NAME") anatomy = Anatomy(project) root = anatomy.roots['renders'] except Exception as e: 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 4317844ca5..0eaa1adb84 100644 --- a/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py +++ b/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py @@ -146,7 +146,7 @@ class UnrealPrelaunchHook(PreLaunchHook): def execute(self): """Hook entry method.""" - workdir = self.launch_context.env["AVALON_WORKDIR"] + workdir = self.launch_context.env["AYON_WORKDIR"] executable = str(self.launch_context.executable) engine_version = self.app_name.split("/")[-1].replace("-", ".") try: diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index febdaacdd1..38a29d7991 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1740,15 +1740,15 @@ def prepare_context_environments(data, env_group=None, addons_manager=None): app = data["app"] context_env = { - "AVALON_PROJECT": project_doc["name"], - "AVALON_APP_NAME": app.full_name + "AYON_PROJECT_NAME": project_doc["name"], + "AYON_APP_NAME": app.full_name } if asset_doc: asset_name = get_asset_name_identifier(asset_doc) - context_env["AVALON_ASSET"] = asset_name + context_env["AYON_FOLDER_PATH"] = asset_name if task_name: - context_env["AVALON_TASK"] = task_name + context_env["AYON_TASK_NAME"] = task_name log.debug( "Context environments set:\n{}".format( @@ -1766,7 +1766,7 @@ def prepare_context_environments(data, env_group=None, addons_manager=None): if not app.is_host: return - data["env"]["AVALON_APP"] = app.host_name + data["env"]["AYON_HOST_NAME"] = app.host_name if not asset_doc or not task_name: # QUESTION replace with log.info and skip workfile discovery? @@ -1812,7 +1812,7 @@ def prepare_context_environments(data, env_group=None, addons_manager=None): "Couldn't create workdir because: {}".format(str(exc)) ) - data["env"]["AVALON_WORKDIR"] = workdir + data["env"]["AYON_WORKDIR"] = workdir _prepare_last_workfile(data, workdir, addons_manager) @@ -1929,7 +1929,7 @@ def _prepare_last_workfile(data, workdir, addons_manager): "Setting last workfile path: {}".format(last_workfile_path) ) - data["env"]["AVALON_LAST_WORKFILE"] = last_workfile_path + data["env"]["AYON_LAST_WORKFILE"] = last_workfile_path data["last_workfile_path"] = last_workfile_path diff --git a/client/ayon_core/lib/log.py b/client/ayon_core/lib/log.py index cbb1e41bae..36c39f9d84 100644 --- a/client/ayon_core/lib/log.py +++ b/client/ayon_core/lib/log.py @@ -257,7 +257,7 @@ class Logger: return cls._process_name # Get process name - process_name = os.environ.get("AVALON_APP_NAME") + process_name = os.environ.get("AYON_APP_NAME") if not process_name: try: import psutil diff --git a/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py b/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py index 19aa2ef195..f7dd1772b0 100644 --- a/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py +++ b/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py @@ -12,7 +12,7 @@ class ClockifyStart(LauncherAction): def is_compatible(self, session): """Return whether the action is compatible with the session""" - if "AVALON_TASK" in session: + if "AYON_TASK_NAME" in session: return True return False @@ -20,9 +20,9 @@ class ClockifyStart(LauncherAction): self.clockify_api.set_api() user_id = self.clockify_api.user_id workspace_id = self.clockify_api.workspace_id - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] description = asset_name # fetch asset docs diff --git a/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py b/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py index 30f5ae698f..5ef9033ffe 100644 --- a/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py +++ b/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py @@ -36,7 +36,7 @@ class ClockifySync(LauncherAction): raise ClockifyPermissionsCheckFailed( "Current CLockify user is missing permissions for this action!" ) - project_name = session.get("AVALON_PROJECT") or "" + project_name = session.get("AYON_PROJECT_NAME") or "" projects_to_sync = [] if project_name.strip(): diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py index 618b71bbaf..a4eb5b673c 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -80,11 +80,11 @@ class AfterEffectsSubmitDeadline( "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py index af864ace5b..e9e6ef083d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py @@ -102,11 +102,11 @@ class BlenderSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "IS_TEST" ] 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 7aa8546bb6..9c125db174 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 @@ -220,11 +220,11 @@ class FusionSubmitDeadline( "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", "IS_TEST", "AYON_BUNDLE_NAME", diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py index 4d375299fa..d3915ed16d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py @@ -273,11 +273,11 @@ class HarmonySubmitDeadline( "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS" "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index 96ee80c4d7..f6676da3d6 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -98,11 +98,11 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index d7a062c9a6..436f0d70ad 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -204,11 +204,11 @@ class HoudiniSubmitDeadline( "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py index 8908283164..4eaaedac34 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py @@ -106,11 +106,11 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py index 2b7a7cf698..1b86d74987 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -199,11 +199,11 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py index ed360d84ae..08ddbcf661 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py @@ -104,10 +104,10 @@ class MayaSubmitRemotePublishDeadline( if key in os.environ } - environment["AVALON_PROJECT"] = project_name - environment["AVALON_ASSET"] = instance.context.data["asset"] - environment["AVALON_TASK"] = instance.context.data["task"] - environment["AVALON_APP_NAME"] = os.environ.get("AVALON_APP_NAME") + environment["AYON_PROJECT_NAME"] = project_name + environment["AYON_FOLDER_PATH"] = instance.context.data["asset"] + environment["AYON_TASK_NAME"] = instance.context.data["task"] + environment["AYON_APP_NAME"] = os.environ.get("AYON_APP_NAME") environment["OPENPYPE_PUBLISH_SUBSET"] = instance.data["subset"] environment["AYON_LOG_NO_COLORS"] = "1" environment["AYON_USERNAME"] = instance.context.data["user"] 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 61a334e184..f48f9ba9b7 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 @@ -373,10 +373,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, keys = [ "PYTHONPATH", "PATH", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_APP_NAME", "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", 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 38ea31ab7b..522f19604b 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 @@ -68,7 +68,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "AVALON_APP_NAME", + "AYON_APP_NAME", "AYON_USERNAME", "OPENPYPE_SG_USER", "KITSU_LOGIN", @@ -126,9 +126,9 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, create_metadata_path(instance, anatomy) environment = { - "AVALON_PROJECT": instance.context.data["projectName"], - "AVALON_ASSET": instance.context.data["asset"], - "AVALON_TASK": instance.context.data["task"], + "AYON_PROJECT_NAME": instance.context.data["projectName"], + "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_TASK_NAME": instance.context.data["task"], "AYON_USERNAME": instance.context.data["user"], "AYON_LOG_NO_COLORS": "1", "IS_TEST": str(int(is_in_tests())), 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 c4ab6a2932..35b54d40ca 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 @@ -110,7 +110,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "AVALON_APP_NAME", + "AYON_APP_NAME", "AYON_USERNAME", "OPENPYPE_SG_USER", "KITSU_LOGIN", @@ -182,9 +182,9 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, create_metadata_path(instance, anatomy) environment = { - "AVALON_PROJECT": instance.context.data["projectName"], - "AVALON_ASSET": instance.context.data["asset"], - "AVALON_TASK": instance.context.data["task"], + "AYON_PROJECT_NAME": instance.context.data["projectName"], + "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_TASK_NAME": instance.context.data["task"], "AYON_USERNAME": instance.context.data["user"], "AYON_LOG_NO_COLORS": "1", "IS_TEST": str(int(is_in_tests())), diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 81aab00b93..8b539931fb 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -471,12 +471,21 @@ def inject_ayon_environment(deadlinePlugin): ] add_kwargs = { - "project": job.GetJobEnvironmentKeyValue("AVALON_PROJECT"), - "asset": job.GetJobEnvironmentKeyValue("AVALON_ASSET"), - "task": job.GetJobEnvironmentKeyValue("AVALON_TASK"), - "app": job.GetJobEnvironmentKeyValue("AVALON_APP_NAME"), "envgroup": "farm", } + # Support backwards compatible keys + for key, env_keys in { + "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], + "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], + "task": ["AYON_TASK_NAME", "AVALON_TASK"], + "app": ["AYON_APP_NAME", "AVALON_APP_NAME"], + }: + value = "" + for env_key in env_keys: + value = job.GetJobEnvironmentKeyValue(env_key) + if value: + break + add_kwargs[key] = value if job.GetJobEnvironmentKeyValue("IS_TEST"): args.append("--automatic-tests") @@ -486,8 +495,8 @@ def inject_ayon_environment(deadlinePlugin): args.extend(["--{}".format(key), value]) else: raise RuntimeError(( - "Missing required env vars: AVALON_PROJECT, AVALON_ASSET," - " AVALON_TASK, AVALON_APP_NAME" + "Missing required env vars: AYON_PROJECT_NAME," + " AYON_FOLDER_PATH, AYON_TASK_NAME, AYON_APP_NAME" )) environment = { diff --git a/client/ayon_core/modules/royalrender/lib.py b/client/ayon_core/modules/royalrender/lib.py index d985a39d24..2b26ec82e4 100644 --- a/client/ayon_core/modules/royalrender/lib.py +++ b/client/ayon_core/modules/royalrender/lib.py @@ -357,8 +357,8 @@ class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, if not all(add_kwargs.values()): raise RuntimeError(( - "Missing required env vars: AVALON_PROJECT, AVALON_ASSET," - " AVALON_TASK, AVALON_APP_NAME" + "Missing required env vars: AYON_PROJECT_NAME, AYON_FOLDER_PATH," + " AYON_TASK_NAME, AYON_APP_NAME" )) for key, value in add_kwargs.items(): diff --git a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index abc8d7dccd..910abfcb15 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -63,7 +63,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "AVALON_APP_NAME", + "AYON_APP_NAME", "AYON_USERNAME", "OPENPYPE_SG_USER", ] @@ -179,9 +179,9 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, anatomy_data = instance.context.data["anatomyData"] environment = RREnvList({ - "AVALON_PROJECT": anatomy_data["project"]["name"], - "AVALON_ASSET": instance.context.data["asset"], - "AVALON_TASK": anatomy_data["task"]["name"], + "AYON_PROJECT_NAME": anatomy_data["project"]["name"], + "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_TASK_NAME": anatomy_data["task"]["name"], "AYON_USERNAME": anatomy_data["user"] }) diff --git a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 7118c5ebef..cfec2622d9 100644 --- a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -136,10 +136,10 @@ class OpenPypeContextSelector: def run_publish(self): """Run publish process.""" - env = {"AVALON_PROJECT": str(self.context.get("project")), - "AVALON_ASSET": str(self.context.get("asset")), - "AVALON_TASK": str(self.context.get("task")), - # "AVALON_APP_NAME": str(self.context.get("app_name")) + env = {"AYON_PROJECT_NAME": str(self.context.get("project")), + "AYON_FOLDER_PATH": str(self.context.get("asset")), + "AYON_TASK_NAME": str(self.context.get("task")), + # "AYON_APP_NAME": str(self.context.get("app_name")) } print(">>> setting environment:") @@ -182,10 +182,18 @@ print("running selector") selector = OpenPypeContextSelector() # try to set context from environment -selector.context["project"] = os.getenv("AVALON_PROJECT") -selector.context["asset"] = os.getenv("AVALON_ASSET") -selector.context["task"] = os.getenv("AVALON_TASK") -# selector.context["app_name"] = os.getenv("AVALON_APP_NAME") +for key, env_keys in { + "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], + "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], + "task": ["AYON_TASK_NAME", "AVALON_TASK"], + # "app_name": ["AYON_APP_NAME", "AVALON_APP_NAME"] +}: + value = "" + for env_key in env_keys: + value = os.getenv(env_key) + if value: + break + selector.context[key] = value # if anything inside is None, scratch the whole thing and # ask user for context. diff --git a/client/ayon_core/pipeline/actions.py b/client/ayon_core/pipeline/actions.py index 1701498d10..8e0ce7e583 100644 --- a/client/ayon_core/pipeline/actions.py +++ b/client/ayon_core/pipeline/actions.py @@ -26,7 +26,7 @@ class LauncherAction(object): Args: session (dict[str, Union[str, None]]): Session data with - AVALON_PROJECT, AVALON_ASSET and AVALON_TASK. + AYON_PROJECT_NAME, AYON_FOLDER_PATH and AYON_TASK_NAME. """ return True diff --git a/client/ayon_core/pipeline/anatomy.py b/client/ayon_core/pipeline/anatomy.py index 86b7d92309..4864822aa1 100644 --- a/client/ayon_core/pipeline/anatomy.py +++ b/client/ayon_core/pipeline/anatomy.py @@ -423,7 +423,7 @@ class Anatomy(BaseAnatomy): def __init__(self, project_name=None, site_name=None): if not project_name: - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") if not project_name: raise ProjectNotSet(( diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 339ef9187f..5716793354 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -117,12 +117,12 @@ def install_host(host): addons_manager = _get_addons_manager() - project_name = os.getenv("AVALON_PROJECT") + project_name = os.getenv("AYON_PROJECT_NAME") # WARNING: This might be an issue # - commented out because 'traypublisher' does not have set project # if not project_name: # raise ValueError( - # "AVALON_PROJECT is missing in environment variables." + # "AYON_PROJECT_NAME is missing in environment variables." # ) log.info("Activating {}..".format(project_name)) @@ -152,7 +152,7 @@ def install_host(host): print("Registering pyblish target: automated") pyblish.api.register_target("automated") - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") # Give option to handle host installation for addon in addons_manager.get_enabled_addons(): @@ -172,7 +172,7 @@ def install_ayon_plugins(project_name=None, host_name=None): register_inventory_action_path(INVENTORY_PATH) if host_name is None: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") addons_manager = _get_addons_manager() publish_plugin_dirs = addons_manager.collect_publish_plugin_paths( @@ -196,7 +196,7 @@ def install_ayon_plugins(project_name=None, host_name=None): register_inventory_action_path(path) if project_name is None: - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") # Register studio specific plugins if project_name: @@ -331,7 +331,7 @@ def get_current_host_name(): """Current host name. Function is based on currently registered host integration or environment - variable 'AVALON_APP'. + variable 'AYON_HOST_NAME'. Returns: Union[str, None]: Name of host integration in current process or None. @@ -340,7 +340,7 @@ def get_current_host_name(): host = registered_host() if isinstance(host, HostBase): return host.name - return os.environ.get("AVALON_APP") + return os.environ.get("AYON_HOST_NAME") def get_global_context(): @@ -365,9 +365,9 @@ def get_global_context(): """ return { - "project_name": os.environ.get("AVALON_PROJECT"), - "asset_name": os.environ.get("AVALON_ASSET"), - "task_name": os.environ.get("AVALON_TASK"), + "project_name": os.environ.get("AYON_PROJECT_NAME"), + "asset_name": os.environ.get("AYON_FOLDER_PATH"), + "task_name": os.environ.get("AYON_TASK_NAME"), } @@ -474,10 +474,10 @@ def get_template_data_from_session(session=None, system_settings=None): """ if session is not None: - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - host_name = session["AVALON_APP"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] + host_name = session["AYON_HOST_NAME"] else: context = get_current_context() project_name = context["project_name"] @@ -525,8 +525,8 @@ def get_workdir_from_session(session=None, template_key=None): """ if session is not None: - project_name = session["AVALON_PROJECT"] - host_name = session["AVALON_APP"] + project_name = session["AYON_PROJECT_NAME"] + host_name = session["AYON_HOST_NAME"] else: project_name = get_current_project_name() host_name = get_current_host_name() @@ -566,10 +566,10 @@ def get_custom_workfile_template_from_session( """ if session is not None: - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - host_name = session["AVALON_APP"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] + host_name = session["AYON_HOST_NAME"] else: context = get_current_context() project_name = context["project_name"] @@ -616,10 +616,10 @@ def change_current_context(asset_doc, task_name, template_key=None): folder_path = get_asset_name_identifier(asset_doc) envs = { - "AVALON_PROJECT": project_name, - "AVALON_ASSET": folder_path, - "AVALON_TASK": task_name, - "AVALON_WORKDIR": workdir, + "AYON_PROJECT_NAME": project_name, + "AYON_FOLDER_PATH": folder_path, + "AYON_TASK_NAME": task_name, + "AYON_WORKDIR": workdir, } # Update the Session and environments. Pop from environments all keys with diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index be685ea2cc..b973c45097 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -1536,7 +1536,7 @@ class CreateContext: def host_name(self): if hasattr(self.host, "name"): return self.host.name - return os.environ["AVALON_APP"] + return os.environ["AYON_HOST_NAME"] def get_current_project_name(self): """Project name which was used as current context on context reset. diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index 08be32eed4..aab6b67e6f 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -45,7 +45,7 @@ class LegacyCreator(object): def apply_settings(cls, project_settings, system_settings): """Apply OpenPype settings to a plugin class.""" - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") plugin_type = "create" plugin_type_settings = ( project_settings diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 2973b1e54e..93a61b8b8b 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -128,13 +128,13 @@ def get_subset_name( return "" if not host_name: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") # Use only last part of class family value split by dot (`.`) family = family.rsplit(".", 1)[-1] if project_name is None: - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") asset_tasks = asset_doc.get("data", {}).get("tasks") or {} task_info = asset_tasks.get(task_name) or {} diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 9423d8501c..389d3d27ed 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -321,7 +321,7 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, """ representations = [] - host_name = os.environ.get("AVALON_APP", "") + host_name = os.environ.get("AYON_HOST_NAME", "") collections, remainders = clique.assemble(exp_files) log = Logger.get_logger("farm_publishing") @@ -541,7 +541,7 @@ def _create_instances_for_aov(instance, skeleton, aov_filter, additional_data, """ # TODO: this needs to be taking the task from context or instance - task = os.environ["AVALON_TASK"] + task = os.environ["AYON_TASK_NAME"] anatomy = instance.context.data["anatomy"] subset = skeleton["subset"] @@ -611,7 +611,7 @@ def _create_instances_for_aov(instance, skeleton, aov_filter, additional_data, log.info("Creating data for: {}".format(subset_name)) - app = os.environ.get("AVALON_APP", "") + app = os.environ.get("AYON_HOST_NAME", "") if isinstance(col, list): render_file_name = os.path.basename(col[0]) diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index fc64edf2ae..1d4627689f 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -38,7 +38,7 @@ class LoaderPlugin(list): @classmethod def apply_settings(cls, project_settings, system_settings): - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") plugin_type = "load" plugin_type_settings = ( project_settings diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 47f4be9e69..a62c2d9c5b 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -437,7 +437,7 @@ def filter_pyblish_plugins(plugins): # - kept becau on farm is probably used host 'shell' which propably # affect how settings are applied there host_name = pyblish.api.current_host() - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") project_settings = get_project_settings(project_name) system_settings = get_system_settings() diff --git a/client/ayon_core/pipeline/workfile/build_workfile.py b/client/ayon_core/pipeline/workfile/build_workfile.py index c62facaaa9..6b13eeeed6 100644 --- a/client/ayon_core/pipeline/workfile/build_workfile.py +++ b/client/ayon_core/pipeline/workfile/build_workfile.py @@ -229,8 +229,8 @@ class BuildWorkfile: def get_build_presets(self, task_name, asset_doc): """ Returns presets to build workfile for task name. - Presets are loaded for current project set in - io.Session["AVALON_PROJECT"], filtered by registered host + Presets are loaded for current project received by + 'get_current_project_name', filtered by registered host and entered task name. Args: diff --git a/client/ayon_core/pipeline/workfile/path_resolving.py b/client/ayon_core/pipeline/workfile/path_resolving.py index 95a0a03c60..2062705d3c 100644 --- a/client/ayon_core/pipeline/workfile/path_resolving.py +++ b/client/ayon_core/pipeline/workfile/path_resolving.py @@ -157,7 +157,7 @@ def get_workdir( task_name (str): Task name for which are workdir data preapred. host_name (str): Host which is used to workdir. This is required because workdir template may contain `{app}` key. In `Session` - is stored under `AVALON_APP` key. + is stored under `AYON_HOST_NAME` key. anatomy (Anatomy): Optional argument. Anatomy object is created using project name from `project_doc`. It is preferred to pass this argument as initialization of a new Anatomy object may be time diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 1afe26813f..9778e60d1b 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -103,7 +103,7 @@ class AbstractTemplateBuilder(object): if isinstance(host, HostBase): host_name = host.name else: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") self._host = host self._host_name = host_name @@ -129,19 +129,19 @@ class AbstractTemplateBuilder(object): def project_name(self): if isinstance(self._host, HostBase): return self._host.get_current_project_name() - return os.getenv("AVALON_PROJECT") + return os.getenv("AYON_PROJECT_NAME") @property def current_asset_name(self): if isinstance(self._host, HostBase): return self._host.get_current_asset_name() - return os.getenv("AVALON_ASSET") + return os.getenv("AYON_FOLDER_PATH") @property def current_task_name(self): if isinstance(self._host, HostBase): return self._host.get_current_task_name() - return os.getenv("AVALON_TASK") + return os.getenv("AYON_TASK_NAME") def get_current_context(self): if isinstance(self._host, HostBase): @@ -579,7 +579,7 @@ class AbstractTemplateBuilder(object): template_path (str): Fullpath for current task and host's template file. """ - last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE") + last_workfile_path = os.environ.get("AYON_LAST_WORKFILE") self.log.info("__ last_workfile_path: {}".format(last_workfile_path)) if os.path.exists(last_workfile_path): # ignore in case workfile existence diff --git a/client/ayon_core/plugins/actions/open_file_explorer.py b/client/ayon_core/plugins/actions/open_file_explorer.py index b29ed30258..fba3c231a5 100644 --- a/client/ayon_core/plugins/actions/open_file_explorer.py +++ b/client/ayon_core/plugins/actions/open_file_explorer.py @@ -22,14 +22,14 @@ class OpenTaskPath(LauncherAction): def is_compatible(self, session): """Return whether the action is compatible with the session""" - return bool(session.get("AVALON_ASSET")) + return bool(session.get("AYON_FOLDER_PATH")) def process(self, session, **kwargs): from qtpy import QtCore, QtWidgets - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session.get("AVALON_TASK", None) + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session.get("AYON_TASK_NAME", None) path = self._get_workdir(project_name, asset_name, task_name) if not path: diff --git a/client/ayon_core/plugins/load/delete_old_versions.py b/client/ayon_core/plugins/load/delete_old_versions.py index 6b3263e2b6..956b232e2b 100644 --- a/client/ayon_core/plugins/load/delete_old_versions.py +++ b/client/ayon_core/plugins/load/delete_old_versions.py @@ -359,7 +359,7 @@ # # if mongo_changes_bulk: # dbcon = AvalonMongoDB() -# dbcon.Session["AVALON_PROJECT"] = project_name +# dbcon.Session["AYON_PROJECT_NAME"] = project_name # dbcon.install() # dbcon.bulk_write(mongo_changes_bulk) # dbcon.uninstall() diff --git a/client/ayon_core/plugins/publish/collect_anatomy_context_data.py b/client/ayon_core/plugins/publish/collect_anatomy_context_data.py index 978ae5e1e1..fbdf26e76c 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_context_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_context_data.py @@ -4,9 +4,9 @@ Requires: context -> anatomy context -> projectEntity context -> assetEntity + context -> task context -> username context -> datetimeData - session -> AVALON_TASK Provides: context -> anatomyData diff --git a/client/ayon_core/plugins/publish/collect_context_entities.py b/client/ayon_core/plugins/publish/collect_context_entities.py index 8480435e21..30bb184ef5 100644 --- a/client/ayon_core/plugins/publish/collect_context_entities.py +++ b/client/ayon_core/plugins/publish/collect_context_entities.py @@ -1,7 +1,6 @@ """Collect Anatomy and global anatomy data. Requires: - session -> AVALON_ASSET context -> projectName context -> asset context -> task diff --git a/client/ayon_core/plugins/publish/collect_from_create_context.py b/client/ayon_core/plugins/publish/collect_from_create_context.py index d8e803a43c..edb5cc1654 100644 --- a/client/ayon_core/plugins/publish/collect_from_create_context.py +++ b/client/ayon_core/plugins/publish/collect_from_create_context.py @@ -57,9 +57,9 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() for key, value in ( - ("AVALON_PROJECT", project_name), - ("AVALON_ASSET", asset_name), - ("AVALON_TASK", task_name) + ("AYON_PROJECT_NAME", project_name), + ("AYON_FOLDER_PATH", asset_name), + ("AYON_TASK_NAME", task_name) ): os.environ[key] = value diff --git a/client/ayon_core/plugins/publish/collect_host_name.py b/client/ayon_core/plugins/publish/collect_host_name.py index 89e4e03c1a..e76579bbd2 100644 --- a/client/ayon_core/plugins/publish/collect_host_name.py +++ b/client/ayon_core/plugins/publish/collect_host_name.py @@ -24,13 +24,13 @@ class CollectHostName(pyblish.api.ContextPlugin): if host_name and app_name and app_label: return - # Use AVALON_APP to get host name if available + # Use AYON_HOST_NAME to get host name if available if not host_name: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") - # Use AVALON_APP_NAME to get full app name + # Use AYON_APP_NAME to get full app name if not app_name: - app_name = os.environ.get("AVALON_APP_NAME") + app_name = os.environ.get("AYON_APP_NAME") # Fill missing values based on app full name if (not host_name or not app_label) and app_name: diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index a7b6064b7a..9a316b69a4 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -179,14 +179,14 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): ) # Remap workdir if it's set - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") remapped_workdir = None if workdir: remapped_workdir = anatomy.roots_obj.path_remapper( - os.getenv("AVALON_WORKDIR") + os.getenv("AYON_WORKDIR") ) if remapped_workdir: - os.environ["AVALON_WORKDIR"] = remapped_workdir + os.environ["AYON_WORKDIR"] = remapped_workdir except Exception as e: self.log.error(e, exc_info=True) raise Exception("Error") from e diff --git a/client/ayon_core/scripts/non_python_host_launch.py b/client/ayon_core/scripts/non_python_host_launch.py index 97632e98ad..4c18fd0ccc 100644 --- a/client/ayon_core/scripts/non_python_host_launch.py +++ b/client/ayon_core/scripts/non_python_host_launch.py @@ -79,7 +79,7 @@ def main(argv): if after_script_idx is not None: launch_args = sys_args[after_script_idx:] - host_name = os.environ["AVALON_APP"].lower() + host_name = os.environ["AYON_HOST_NAME"].lower() if host_name == "photoshop": # TODO refactor launch logic according to AE from ayon_core.hosts.photoshop.api.lib import main @@ -90,7 +90,7 @@ def main(argv): else: title = "Unknown host name" message = ( - "BUG: Environment variable AVALON_APP contains unknown" + "BUG: Environment variable AYON_HOST_NAME contains unknown" " host name \"{}\"" ).format(host_name) show_error_messagebox(title, message) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index beae376b7c..717d3fba3a 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -240,15 +240,15 @@ def get_site_local_overrides(project_name, site_name, local_settings=None): def get_current_project_settings(): """Project settings for current context project. - Project name should be stored in environment variable `AVALON_PROJECT`. + Project name should be stored in environment variable `AYON_PROJECT_NAME`. This function should be used only in host context where environment variable must be set and should not happen that any part of process will change the value of the enviornment variable. """ - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") if not project_name: raise ValueError( - "Missing context project in environemt variable `AVALON_PROJECT`." + "Missing context project in environemt variable `AYON_PROJECT_NAME`." ) return get_project_settings(project_name) diff --git a/client/ayon_core/tools/experimental_tools/tools_def.py b/client/ayon_core/tools/experimental_tools/tools_def.py index 568c7032d0..be6762b239 100644 --- a/client/ayon_core/tools/experimental_tools/tools_def.py +++ b/client/ayon_core/tools/experimental_tools/tools_def.py @@ -139,7 +139,7 @@ class ExperimentalTools: def get_tools_for_host(self, host_name=None): if not host_name: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") tools = [] for tool in self.tools: if ( diff --git a/client/ayon_core/tools/launcher/models/actions.py b/client/ayon_core/tools/launcher/models/actions.py index 37024b5810..53d2b78dc3 100644 --- a/client/ayon_core/tools/launcher/models/actions.py +++ b/client/ayon_core/tools/launcher/models/actions.py @@ -69,9 +69,9 @@ class ApplicationAction(LauncherAction): _log = None required_session_keys = ( - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK" + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME" ) @property @@ -85,7 +85,7 @@ class ApplicationAction(LauncherAction): if not session.get(key): return False - project_name = session["AVALON_PROJECT"] + project_name = session["AYON_PROJECT_NAME"] project_entity = self.project_entities[project_name] apps = project_entity["attrib"].get("applications") if not apps or self.application.full_name not in apps: @@ -119,9 +119,9 @@ class ApplicationAction(LauncherAction): ApplicationLaunchFailed, ) - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] try: self.application.launch( project_name=project_name, @@ -416,6 +416,10 @@ class ActionsModel: task_name = task["name"] return { + "AYON_PROJECT_NAME": project_name, + "AYON_FOLDER_PATH": folder_path, + "AYON_TASK_NAME": task_name, + # Deprecated - kept for backwards compatibility "AVALON_PROJECT": project_name, "AVALON_ASSET": folder_path, "AVALON_TASK": task_name, diff --git a/client/ayon_core/tools/publisher/control.py b/client/ayon_core/tools/publisher/control.py index 988362fee4..5ccd428551 100644 --- a/client/ayon_core/tools/publisher/control.py +++ b/client/ayon_core/tools/publisher/control.py @@ -1807,9 +1807,9 @@ class PublisherController(BasePublisherController): context_title = self._host.get_context_title() if context_title is None: - context_title = os.environ.get("AVALON_APP_NAME") + context_title = os.environ.get("AYON_APP_NAME") if context_title is None: - context_title = os.environ.get("AVALON_APP") + context_title = os.environ.get("AYON_HOST_NAME") return context_title diff --git a/client/ayon_core/tools/texture_copy/app.py b/client/ayon_core/tools/texture_copy/app.py index 9b4406d8e7..eef648eaf9 100644 --- a/client/ayon_core/tools/texture_copy/app.py +++ b/client/ayon_core/tools/texture_copy/app.py @@ -132,8 +132,8 @@ class TextureCopy: def texture_copy(asset, project, path): t.echo("*** Running Texture tool ***") t.echo(">>> Initializing avalon session ...") - os.environ["AVALON_PROJECT"] = project - os.environ["AVALON_ASSET"] = asset + os.environ["AYON_PROJECT_NAME"] = project + os.environ["AYON_FOLDER_PATH"] = asset TextureCopy().process(asset, project, path) diff --git a/client/ayon_core/tools/workfile_template_build/window.py b/client/ayon_core/tools/workfile_template_build/window.py index ae4946d41d..feb11c5e75 100644 --- a/client/ayon_core/tools/workfile_template_build/window.py +++ b/client/ayon_core/tools/workfile_template_build/window.py @@ -27,7 +27,7 @@ class WorkfileBuildPlaceholderDialog(QtWidgets.QDialog): host_name = getattr(self._host, "name", None) if not host_name: - host_name = os.getenv("AVALON_APP") or "NA" + host_name = os.getenv("AYON_HOST_NAME") or "NA" self._host_name = host_name plugins_combo = QtWidgets.QComboBox(self) From 31460538f9b557921bfc18dcfd02f5322ca7a7b2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:17:51 +0100 Subject: [PATCH 027/149] fix session requirement --- client/ayon_core/hosts/maya/plugins/publish/collect_render.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index 7daab19f4a..4ea91ccb0d 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -8,13 +8,12 @@ publishing on farm. Requires: instance -> families instance -> setMembers + instance -> asset context -> currentFile context -> workspaceDir context -> user - session -> AYON_FOLDER_PATH - Optional: Provides: From 27512a06a121f76f8c7d0705ee317b11a062032a Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Mon, 12 Feb 2024 15:34:21 +0000 Subject: [PATCH 028/149] Removed references to `AYON_SERVER_ENABLED` --- client/ayon_core/hosts/blender/api/render_lib.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/blender/api/render_lib.py b/client/ayon_core/hosts/blender/api/render_lib.py index 9b43c14568..e1d0e2ae67 100644 --- a/client/ayon_core/hosts/blender/api/render_lib.py +++ b/client/ayon_core/hosts/blender/api/render_lib.py @@ -2,7 +2,6 @@ from pathlib import Path import bpy -from ayon_core import AYON_SERVER_ENABLED from ayon_core.settings import get_project_settings from ayon_core.pipeline import get_current_project_name @@ -166,14 +165,13 @@ def set_render_passes(settings, renderer): aovs_names = [aov.name for aov in vl.aovs] for cp in custom_passes: - cp_name = cp["attribute"] if AYON_SERVER_ENABLED else cp[0] + cp_name = cp["attribute"] if cp_name not in aovs_names: aov = vl.aovs.add() aov.name = cp_name else: aov = vl.aovs[cp_name] - aov.type = (cp["value"] - if AYON_SERVER_ENABLED else cp[1].get("type", "VALUE")) + aov.type = cp["value"] return aov_list, custom_passes From a0b18c91cd06ba18adb102f211ed4e7e30e00042 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Mon, 12 Feb 2024 15:39:40 +0000 Subject: [PATCH 029/149] Cast aov_list to set to improve performance --- client/ayon_core/hosts/blender/api/render_lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/blender/api/render_lib.py b/client/ayon_core/hosts/blender/api/render_lib.py index e1d0e2ae67..73d327b1a8 100644 --- a/client/ayon_core/hosts/blender/api/render_lib.py +++ b/client/ayon_core/hosts/blender/api/render_lib.py @@ -100,7 +100,7 @@ def set_render_format(ext, multilayer): def set_render_passes(settings, renderer): - aov_list = settings["blender"]["RenderSettings"]["aov_list"] + aov_list = set(settings["blender"]["RenderSettings"]["aov_list"]) custom_passes = settings["blender"]["RenderSettings"]["custom_passes"] # Common passes for both renderers @@ -173,7 +173,7 @@ def set_render_passes(settings, renderer): aov = vl.aovs[cp_name] aov.type = cp["value"] - return aov_list, custom_passes + return list(aov_list), custom_passes def _create_aov_slot(name, aov_sep, slots, rpass_name, multi_exr, output_path): From 6e30f4a6f54c840d4105aedc9b1d3a50ad6f6026 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Feb 2024 22:35:18 +0100 Subject: [PATCH 030/149] fix env auto fix --- .../repository/custom/plugins/GlobalJobPreLoad.py | 12 ++++++------ .../perjob/m50__openpype_publish_render.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 8b539931fb..330bf5b0c9 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -474,12 +474,12 @@ def inject_ayon_environment(deadlinePlugin): "envgroup": "farm", } # Support backwards compatible keys - for key, env_keys in { - "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], - "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], - "task": ["AYON_TASK_NAME", "AVALON_TASK"], - "app": ["AYON_APP_NAME", "AVALON_APP_NAME"], - }: + for key, env_keys in ( + ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), + ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"], + ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), + ("app", ["AYON_APP_NAME", "AVALON_APP_NAME"]), + ): value = "" for env_key in env_keys: value = job.GetJobEnvironmentKeyValue(env_key) diff --git a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index cfec2622d9..778052778f 100644 --- a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -182,12 +182,12 @@ print("running selector") selector = OpenPypeContextSelector() # try to set context from environment -for key, env_keys in { - "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], - "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], - "task": ["AYON_TASK_NAME", "AVALON_TASK"], - # "app_name": ["AYON_APP_NAME", "AVALON_APP_NAME"] -}: +for key, env_keys in ( + ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), + ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"]), + ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), + # ("app_name", ["AYON_APP_NAME", "AVALON_APP_NAME"]) +): value = "" for env_key in env_keys: value = os.getenv(env_key) From 97e4a3f93edd1af0f612c5f17b408c9abb2e6006 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 13 Feb 2024 19:21:25 +0800 Subject: [PATCH 031/149] clean up the unneccessary logs and code in collect members and collect workfiles --- .../max/plugins/create/create_workfile.py | 18 +++++------------ .../max/plugins/publish/collect_members.py | 3 +-- .../max/plugins/publish/collect_workfile.py | 20 ++++++------------- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/create/create_workfile.py b/client/ayon_core/hosts/max/plugins/create/create_workfile.py index 5b51391749..e5fec5f437 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_workfile.py +++ b/client/ayon_core/hosts/max/plugins/create/create_workfile.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Creator plugin for creating workfiles.""" -from ayon_core import AYON_SERVER_ENABLED from ayon_core.pipeline import CreatedInstance, AutoCreator from ayon_core.client import get_asset_by_name, get_asset_name_identifier from ayon_core.hosts.max.api import plugin @@ -31,10 +30,8 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): if current_instance is None: current_instance_asset = None - elif AYON_SERVER_ENABLED: - current_instance_asset = current_instance["folderPath"] - else: - current_instance_asset = current_instance["asset"] + + current_instance_asset = current_instance["folderPath"] if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) @@ -45,10 +42,8 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): "task": task_name, "variant": variant } - if AYON_SERVER_ENABLED: - data["folderPath"] = asset_name - else: - data["asset"] = asset_name + + data["folderPath"] = asset_name data.update( self.get_dynamic_data( @@ -74,10 +69,7 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): ) asset_name = get_asset_name_identifier(asset_doc) - if AYON_SERVER_ENABLED: - current_instance["folderPath"] = asset_name - else: - current_instance["asset"] = asset_name + current_instance["folderPath"] = asset_name current_instance["task"] = task_name current_instance["subset"] = subset_name diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_members.py b/client/ayon_core/hosts/max/plugins/publish/collect_members.py index 7cd646e0e7..f3fde00fe0 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_members.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_members.py @@ -13,8 +13,7 @@ class CollectMembers(pyblish.api.InstancePlugin): def process(self, instance): if instance.data["family"] == "workfile": - self.log.debug("Skipping Actions for workfile family.") - self.log.debug("{}".format(instance.data["subset"])) + self.log.debug("Skipping Collecting Members for workfile family.") return if instance.data.get("instance_node"): container = rt.GetNodeByName(instance.data["instance_node"]) diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py index 446175c0ed..4dbaf28bf7 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py @@ -29,15 +29,8 @@ class CollectWorkfile(pyblish.api.InstancePlugin): data = {} # create instance - subset = instance.data["subset"] data.update({ - "subset": subset, - "asset": context.data["asset"], - "label": subset, - "publish": True, - "family": 'workfile', - "families": ['workfile'], "setMembers": [current_file], "frameStart": context.data['frameStart'], "frameEnd": context.data['frameEnd'], @@ -46,15 +39,14 @@ class CollectWorkfile(pyblish.api.InstancePlugin): }) data['representations'] = [{ - 'name': ext.lstrip("."), - 'ext': ext.lstrip("."), + 'name': ext, + 'ext': ext, 'files': file, "stagingDir": folder, }] instance.data.update(data) - self.log.info('Collected data: {}'.format(data)) - self.log.info('Collected instance: {}'.format(file)) - self.log.info('Scene path: {}'.format(current_file)) - self.log.info('staging Dir: {}'.format(folder)) - self.log.info('subset: {}'.format(subset)) + self.log.debug('Collected data: {}'.format(data)) + self.log.debug('Collected instance: {}'.format(file)) + self.log.debug('Scene path: {}'.format(current_file)) + self.log.debug('staging Dir: {}'.format(folder)) From c932042168d2a87691da6a5f6a0146e4f0116394 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 12:53:59 +0100 Subject: [PATCH 032/149] make sure old keys are removed --- client/ayon_core/cli_commands.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index 31429c488b..7e652950eb 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -84,6 +84,8 @@ class Commands: ): if src_key in os.environ and dst_key not in os.environ: os.environ[dst_key] = os.environ[src_key] + # Remove old keys, so we're sure they're not used + os.environ.pop(src_key, None) log = Logger.get_logger("CLI-publish") From 0ca94aa3c03acf63d177dde49099d1c99e08ed2d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 13:11:03 +0100 Subject: [PATCH 033/149] bump version of global pre load plugin --- .../deadline/repository/custom/plugins/GlobalJobPreLoad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 0b44c8dce3..818424b5fc 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -14,7 +14,7 @@ from Deadline.Scripting import ( DirectoryUtils, ProcessUtils, ) -__version__ = "1.0.0" +__version__ = "1.0.1" VERSION_REGEX = re.compile( r"(?P0|[1-9]\d*)" r"\.(?P0|[1-9]\d*)" From 5a185f4a2ad376c013aa2a5cd8ab8748f9f888bd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 15:03:42 +0100 Subject: [PATCH 034/149] move asset icon functions to assets widget --- .../tools/publisher/widgets/assets_widget.py | 2 +- client/ayon_core/tools/utils/__init__.py | 8 --- client/ayon_core/tools/utils/assets_widget.py | 59 ++++++++++++++++++- client/ayon_core/tools/utils/lib.py | 56 ------------------ 4 files changed, 59 insertions(+), 66 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/assets_widget.py b/client/ayon_core/tools/publisher/widgets/assets_widget.py index faad37104d..1c5016de99 100644 --- a/client/ayon_core/tools/publisher/widgets/assets_widget.py +++ b/client/ayon_core/tools/publisher/widgets/assets_widget.py @@ -5,13 +5,13 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core.tools.utils import ( PlaceholderLineEdit, RecursiveSortFilterProxyModel, - get_asset_icon, ) from ayon_core.tools.utils.assets_widget import ( SingleSelectAssetsWidget, ASSET_ID_ROLE, ASSET_NAME_ROLE, ASSET_PATH_ROLE, + get_asset_icon, ) diff --git a/client/ayon_core/tools/utils/__init__.py b/client/ayon_core/tools/utils/__init__.py index 7be0ea5e9f..445b4d9b97 100644 --- a/client/ayon_core/tools/utils/__init__.py +++ b/client/ayon_core/tools/utils/__init__.py @@ -37,10 +37,6 @@ from .lib import ( get_qt_app, get_ayon_qt_app, get_openpype_qt_app, - get_asset_icon, - get_asset_icon_by_name, - get_asset_icon_name_from_doc, - get_asset_icon_color_from_doc, ) from .models import ( @@ -100,10 +96,6 @@ __all__ = ( "get_qt_app", "get_ayon_qt_app", "get_openpype_qt_app", - "get_asset_icon", - "get_asset_icon_by_name", - "get_asset_icon_name_from_doc", - "get_asset_icon_color_from_doc", "RecursiveSortFilterProxyModel", diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index 7bacf3291d..a97a289737 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -10,6 +10,7 @@ from ayon_core.client import ( ) from ayon_core.style import ( get_default_tools_icon_color, + get_default_entity_icon_color, ) from ayon_core.tools.flickcharm import FlickCharm @@ -21,7 +22,7 @@ from .widgets import PlaceholderLineEdit from .models import RecursiveSortFilterProxyModel from .lib import ( DynamicQThread, - get_asset_icon + get_qta_icon_by_name_and_color ) ASSET_ID_ROLE = QtCore.Qt.UserRole + 1 @@ -31,6 +32,62 @@ ASSET_UNDERLINE_COLORS_ROLE = QtCore.Qt.UserRole + 4 ASSET_PATH_ROLE = QtCore.Qt.UserRole + 5 +def get_default_asset_icon_name(has_children): + if has_children: + return "fa.folder" + return "fa.folder-o" + + +def get_asset_icon_color_from_doc(asset_doc): + if asset_doc: + return asset_doc["data"].get("color") + return None + + +def get_asset_icon_name_from_doc(asset_doc): + if asset_doc: + return asset_doc["data"].get("icon") + return None + + +def get_asset_icon_color(asset_doc): + icon_color = get_asset_icon_color_from_doc(asset_doc) + if icon_color: + return icon_color + return get_default_entity_icon_color() + + +def get_asset_icon_by_name(icon_name, icon_color, has_children=False): + if not icon_name: + icon_name = get_default_asset_icon_name(has_children) + + if icon_color: + icon_color = QtGui.QColor(icon_color) + else: + icon_color = get_default_entity_icon_color() + icon = get_qta_icon_by_name_and_color(icon_name, icon_color) + if icon is not None: + return icon + return get_qta_icon_by_name_and_color( + get_default_asset_icon_name(has_children), + icon_color + ) + + +def get_asset_icon_name(asset_doc, has_children=True): + icon_name = get_asset_icon_name_from_doc(asset_doc) + if icon_name: + return icon_name + return get_default_asset_icon_name(has_children) + + +def get_asset_icon(asset_doc, has_children=False): + icon_name = get_asset_icon_name(asset_doc, has_children) + icon_color = get_asset_icon_color(asset_doc) + + return get_qta_icon_by_name_and_color(icon_name, icon_color) + + class _AssetsView(TreeViewSpinner, DeselectableTreeView): """Asset items view. diff --git a/client/ayon_core/tools/utils/lib.py b/client/ayon_core/tools/utils/lib.py index b7edd6be71..e785cec390 100644 --- a/client/ayon_core/tools/utils/lib.py +++ b/client/ayon_core/tools/utils/lib.py @@ -234,62 +234,6 @@ def get_qta_icon_by_name_and_color(icon_name, icon_color): return icon -def get_asset_icon_name(asset_doc, has_children=True): - icon_name = get_asset_icon_name_from_doc(asset_doc) - if icon_name: - return icon_name - return get_default_asset_icon_name(has_children) - - -def get_asset_icon_color(asset_doc): - icon_color = get_asset_icon_color_from_doc(asset_doc) - if icon_color: - return icon_color - return get_default_entity_icon_color() - - -def get_default_asset_icon_name(has_children): - if has_children: - return "fa.folder" - return "fa.folder-o" - - -def get_asset_icon_name_from_doc(asset_doc): - if asset_doc: - return asset_doc["data"].get("icon") - return None - - -def get_asset_icon_color_from_doc(asset_doc): - if asset_doc: - return asset_doc["data"].get("color") - return None - - -def get_asset_icon_by_name(icon_name, icon_color, has_children=False): - if not icon_name: - icon_name = get_default_asset_icon_name(has_children) - - if icon_color: - icon_color = QtGui.QColor(icon_color) - else: - icon_color = get_default_entity_icon_color() - icon = get_qta_icon_by_name_and_color(icon_name, icon_color) - if icon is not None: - return icon - return get_qta_icon_by_name_and_color( - get_default_asset_icon_name(has_children), - icon_color - ) - - -def get_asset_icon(asset_doc, has_children=False): - icon_name = get_asset_icon_name(asset_doc, has_children) - icon_color = get_asset_icon_color(asset_doc) - - return get_qta_icon_by_name_and_color(icon_name, icon_color) - - def get_default_task_icon(color=None): if color is None: color = get_default_entity_icon_color() From 9d7dd0d75a4220f4677403e7e7da9ec75fec1c78 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:41:42 +0100 Subject: [PATCH 035/149] remove settings conversion for timers manager --- client/ayon_core/settings/ayon_settings.py | 33 ++++++---------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index cea0158159..0fe4095a92 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -96,26 +96,6 @@ def _convert_kitsu_system_settings( output["modules"]["kitsu"] = kitsu_settings -def _convert_timers_manager_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("timers_manager") is not None - manager_settings = default_settings["modules"]["timers_manager"] - manager_settings["enabled"] = enabled - if enabled: - ayon_manager = ayon_settings["timers_manager"] - manager_settings.update({ - key: ayon_manager[key] - for key in { - "auto_stop", - "full_time", - "message_time", - "disregard_publishing" - } - }) - output["modules"]["timers_manager"] = manager_settings - - def _convert_clockify_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -167,21 +147,24 @@ def _convert_modules_system( # TODO add 'enabled' values for func in ( _convert_kitsu_system_settings, - _convert_timers_manager_system_settings, _convert_clockify_system_settings, _convert_deadline_system_settings, _convert_royalrender_system_settings, ): func(ayon_settings, output, addon_versions, default_settings) + for key in { + "timers_manager", + }: + if addon_versions.get(key): + output[key] = ayon_settings + else: + output.pop(key, None) + modules_settings = output["modules"] for module_name in ( "sync_server", - "log_viewer", - "standalonepublish_tool", - "project_manager", "job_queue", - "avalon", "addon_paths", ): settings = default_settings["modules"][module_name] From 221cd01ae2b6759bb6312819b1cd68ff52e02be1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:42:01 +0100 Subject: [PATCH 036/149] use 'AYONAddon' for times manager addon --- .../modules/timers_manager/timers_manager.py | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/modules/timers_manager/timers_manager.py b/client/ayon_core/modules/timers_manager/timers_manager.py index daba0cead9..f8f0e4a526 100644 --- a/client/ayon_core/modules/timers_manager/timers_manager.py +++ b/client/ayon_core/modules/timers_manager/timers_manager.py @@ -3,8 +3,8 @@ import platform from ayon_core.client import get_asset_by_name -from ayon_core.modules import ( - OpenPypeModule, +from ayon_core.addon import ( + AYONAddon, ITrayService, IPluginPaths ) @@ -76,7 +76,7 @@ class ExampleTimersManagerConnector: class TimersManager( - OpenPypeModule, + AYONAddon, ITrayService, IPluginPaths ): @@ -99,23 +99,27 @@ class TimersManager( "start_timer" ) - def initialize(self, modules_settings): - timers_settings = modules_settings[self.name] + def initialize(self, studio_settings): + timers_settings = studio_settings.get(self.name) + enabled = timers_settings is not None - self.enabled = timers_settings["enabled"] + auto_stop = False + full_time = 0 + message_time = 0 + if enabled: + # When timer will stop if idle manager is running (minutes) + full_time = int(timers_settings["full_time"] * 60) + # How many minutes before the timer is stopped will popup the message + message_time = int(timers_settings["message_time"] * 60) - # When timer will stop if idle manager is running (minutes) - full_time = int(timers_settings["full_time"] * 60) - # How many minutes before the timer is stopped will popup the message - message_time = int(timers_settings["message_time"] * 60) - - auto_stop = timers_settings["auto_stop"] - platform_name = platform.system().lower() - # Turn of auto stop on MacOs because pynput requires root permissions - # and on linux can cause thread locks on application close - if full_time <= 0 or platform_name in ("darwin", "linux"): - auto_stop = False + auto_stop = timers_settings["auto_stop"] + platform_name = platform.system().lower() + # Turn of auto stop on MacOs because pynput requires root permissions + # and on linux can cause thread locks on application close + if full_time <= 0 or platform_name in ("darwin", "linux"): + auto_stop = False + self.enabled = enabled self.auto_stop = auto_stop self.time_show_message = full_time - message_time self.time_stop_timer = full_time From 8bb4db39d0eed4dac6e56b2281d5bcb2b611376c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:11:02 +0100 Subject: [PATCH 037/149] fix missing bracket Co-authored-by: Mustafa Taher --- .../deadline/repository/custom/plugins/GlobalJobPreLoad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 818424b5fc..1565b2c496 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -476,7 +476,7 @@ def inject_ayon_environment(deadlinePlugin): # Support backwards compatible keys for key, env_keys in ( ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), - ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"], + ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"]), ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), ("app", ["AYON_APP_NAME", "AVALON_APP_NAME"]), ): From de643a13d837de57d88e8598dcaccd48f23aff74 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:21:41 +0100 Subject: [PATCH 038/149] removed outdated shotgrid conversion --- client/ayon_core/settings/ayon_settings.py | 28 ---------------------- 1 file changed, 28 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index fe54714f75..dd079bec84 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -600,33 +600,6 @@ def _convert_kitsu_project_settings(ayon_settings, output): output["kitsu"] = ayon_kitsu_settings -def _convert_shotgrid_project_settings(ayon_settings, output): - if "shotgrid" not in ayon_settings: - return - - ayon_shotgrid = ayon_settings["shotgrid"] - # This means that a different variant of addon is used - if "leecher_backend_url" not in ayon_shotgrid: - return - - for key in { - "leecher_backend_url", - "filter_projects_by_login", - "shotgrid_settings", - "leecher_manager_url", - }: - ayon_shotgrid.pop(key) - - asset_field = ayon_shotgrid["fields"]["asset"] - asset_field["type"] = asset_field.pop("asset_type") - - task_field = ayon_shotgrid["fields"]["task"] - if "task" in task_field: - task_field["step"] = task_field.pop("task") - - output["shotgrid"] = ayon_settings["shotgrid"] - - def _convert_slack_project_settings(ayon_settings, output): if "slack" not in ayon_settings: return @@ -848,7 +821,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_royalrender_project_settings(ayon_settings, output) _convert_kitsu_project_settings(ayon_settings, output) - _convert_shotgrid_project_settings(ayon_settings, output) _convert_slack_project_settings(ayon_settings, output) _convert_global_project_settings(ayon_settings, output, default_settings) From 4e2ee7aaac2c9f00b328204e4463a7d10671b4b8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:30:39 +0100 Subject: [PATCH 039/149] removed webpublisher settings conversion --- client/ayon_core/settings/ayon_settings.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index dd079bec84..ff97d9726b 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -560,15 +560,6 @@ def _convert_webpublisher_project_settings(ayon_settings, output): ayon_webpublisher = ayon_settings["webpublisher"] _convert_host_imageio(ayon_webpublisher) - - ayon_publish = ayon_webpublisher["publish"] - - ayon_collect_files = ayon_publish["CollectPublishedFiles"] - ayon_collect_files["task_type_to_family"] = { - item["name"]: item["value"] - for item in ayon_collect_files["task_type_to_family"] - } - output["webpublisher"] = ayon_webpublisher From 342c84784a275b3b2d98a235f5c17811a6e6ec7f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:33:39 +0100 Subject: [PATCH 040/149] removed kitsu settings conversion --- client/ayon_core/settings/ayon_settings.py | 32 ---------------------- 1 file changed, 32 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index ff97d9726b..2978202b51 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -82,20 +82,6 @@ def _convert_general(ayon_settings, output, default_settings): } -def _convert_kitsu_system_settings( - ayon_settings, output, addon_versions, default_settings -): - if "kitsu" in ayon_settings: - output["kitsu"] = ayon_settings["kitsu"] - - enabled = addon_versions.get("kitsu") is not None - kitsu_settings = default_settings["modules"]["kitsu"] - kitsu_settings["enabled"] = enabled - if enabled: - kitsu_settings["server"] = ayon_settings["kitsu"]["server"] - output["modules"]["kitsu"] = kitsu_settings - - def _convert_timers_manager_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -166,7 +152,6 @@ def _convert_modules_system( # TODO add all modules # TODO add 'enabled' values for func in ( - _convert_kitsu_system_settings, _convert_timers_manager_system_settings, _convert_clockify_system_settings, _convert_deadline_system_settings, @@ -575,22 +560,6 @@ def _convert_royalrender_project_settings(ayon_settings, output): } -def _convert_kitsu_project_settings(ayon_settings, output): - if "kitsu" not in ayon_settings: - return - - ayon_kitsu_settings = ayon_settings["kitsu"] - ayon_kitsu_settings.pop("server") - - integrate_note = ayon_kitsu_settings["publish"]["IntegrateKitsuNote"] - status_change_conditions = integrate_note["status_change_conditions"] - if "product_type_requirements" in status_change_conditions: - status_change_conditions["family_requirements"] = ( - status_change_conditions.pop("product_type_requirements")) - - output["kitsu"] = ayon_kitsu_settings - - def _convert_slack_project_settings(ayon_settings, output): if "slack" not in ayon_settings: return @@ -811,7 +780,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_webpublisher_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) - _convert_kitsu_project_settings(ayon_settings, output) _convert_slack_project_settings(ayon_settings, output) _convert_global_project_settings(ayon_settings, output, default_settings) From a1a325002804e4fa6a131bcae3e202c3ed9ec868 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:34:07 +0100 Subject: [PATCH 041/149] removed slack settings conversion --- client/ayon_core/settings/ayon_settings.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 2978202b51..19a32520b8 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -560,19 +560,6 @@ def _convert_royalrender_project_settings(ayon_settings, output): } -def _convert_slack_project_settings(ayon_settings, output): - if "slack" not in ayon_settings: - return - - ayon_slack = ayon_settings["slack"] - ayon_slack.pop("enabled", None) - for profile in ayon_slack["publish"]["CollectSlackFamilies"]["profiles"]: - profile["tasks"] = profile.pop("task_names") - profile["subsets"] = profile.pop("subset_names") - - output["slack"] = ayon_slack - - def _convert_global_project_settings(ayon_settings, output, default_settings): if "core" not in ayon_settings: return @@ -780,7 +767,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_webpublisher_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) - _convert_slack_project_settings(ayon_settings, output) _convert_global_project_settings(ayon_settings, output, default_settings) From ad74bafc4d32476ca38ffe79fb6d8c287fe9197d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:56:19 +0100 Subject: [PATCH 042/149] removed '_convert_host_imageio' --- client/ayon_core/settings/ayon_settings.py | 38 ---------------------- 1 file changed, 38 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index fe54714f75..27f38fbb5e 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -52,26 +52,6 @@ def _convert_color(color_value): return color_value -def _convert_host_imageio(host_settings): - if "imageio" not in host_settings: - return - - # --- imageio --- - ayon_imageio = host_settings["imageio"] - # TODO remove when fixed on server - if "ocio_config" in ayon_imageio["ocio_config"]: - ayon_imageio["ocio_config"]["filepath"] = ( - ayon_imageio["ocio_config"].pop("ocio_config") - ) - # Convert file rules - imageio_file_rules = ayon_imageio["file_rules"] - new_rules = {} - for rule in imageio_file_rules["rules"]: - name = rule.pop("name") - new_rules[name] = rule - imageio_file_rules["rules"] = new_rules - - def _convert_general(ayon_settings, output, default_settings): output["core"] = ayon_settings["core"] version_check_interval = ( @@ -242,7 +222,6 @@ def _convert_blender_project_settings(ayon_settings, output): if "blender" not in ayon_settings: return ayon_blender = ayon_settings["blender"] - _convert_host_imageio(ayon_blender) output["blender"] = ayon_blender @@ -252,7 +231,6 @@ def _convert_celaction_project_settings(ayon_settings, output): return ayon_celaction = ayon_settings["celaction"] - _convert_host_imageio(ayon_celaction) output["celaction"] = ayon_celaction @@ -263,7 +241,6 @@ def _convert_flame_project_settings(ayon_settings, output): ayon_flame = ayon_settings["flame"] - _convert_host_imageio(ayon_flame) output["flame"] = ayon_flame @@ -272,7 +249,6 @@ def _convert_fusion_project_settings(ayon_settings, output): return ayon_fusion = ayon_settings["fusion"] - _convert_host_imageio(ayon_fusion) output["fusion"] = ayon_fusion @@ -283,8 +259,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - _convert_host_imageio(ayon_maya) - output["maya"] = ayon_maya @@ -294,8 +268,6 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_max = ayon_settings["max"] - _convert_host_imageio(ayon_max) - output["max"] = ayon_max @@ -442,7 +414,6 @@ def _convert_nuke_project_settings(ayon_settings, output): # --- ImageIO --- # NOTE 'monitorOutLut' is maybe not yet in v3 (ut should be) - _convert_host_imageio(ayon_nuke) ayon_imageio = ayon_nuke["imageio"] # workfile @@ -491,7 +462,6 @@ def _convert_hiero_project_settings(ayon_settings, output): return ayon_hiero = ayon_settings["hiero"] - _convert_host_imageio(ayon_hiero) new_gui_filters = {} for item in ayon_hiero.pop("filters", []): @@ -521,7 +491,6 @@ def _convert_photoshop_project_settings(ayon_settings, output): return ayon_photoshop = ayon_settings["photoshop"] - _convert_host_imageio(ayon_photoshop) output["photoshop"] = ayon_photoshop @@ -530,7 +499,6 @@ def _convert_substancepainter_project_settings(ayon_settings, output): return ayon_substance_painter = ayon_settings["substancepainter"] - _convert_host_imageio(ayon_substance_painter) output["substancepainter"] = ayon_substance_painter @@ -539,7 +507,6 @@ def _convert_tvpaint_project_settings(ayon_settings, output): return ayon_tvpaint = ayon_settings["tvpaint"] - _convert_host_imageio(ayon_tvpaint) output["tvpaint"] = ayon_tvpaint @@ -549,8 +516,6 @@ def _convert_traypublisher_project_settings(ayon_settings, output): ayon_traypublisher = ayon_settings["traypublisher"] - _convert_host_imageio(ayon_traypublisher) - output["traypublisher"] = ayon_traypublisher @@ -559,7 +524,6 @@ def _convert_webpublisher_project_settings(ayon_settings, output): return ayon_webpublisher = ayon_settings["webpublisher"] - _convert_host_imageio(ayon_webpublisher) ayon_publish = ayon_webpublisher["publish"] @@ -646,7 +610,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_core = ayon_settings["core"] - _convert_host_imageio(ayon_core) # Publish conversion ayon_publish = ayon_core["publish"] @@ -830,7 +793,6 @@ def convert_project_settings(ayon_settings, default_settings): for key in exact_match: if key in ayon_settings: output[key] = ayon_settings[key] - _convert_host_imageio(output[key]) _convert_blender_project_settings(ayon_settings, output) _convert_celaction_project_settings(ayon_settings, output) From 62a6e6c3afbba1f9953052550b3633cd94922148 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:59:18 +0100 Subject: [PATCH 043/149] modified code to use new imageio structure --- client/ayon_core/pipeline/colorspace.py | 45 +++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index d77f301498..70b7678d0a 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -254,7 +254,7 @@ def get_imageio_file_rules_colorspace_from_filepath( # match file rule from path colorspace_name = None - for file_rule in file_rules.values(): + for file_rule in file_rules: pattern = file_rule["pattern"] extension = file_rule["ext"] ext_match = re.match( @@ -281,7 +281,7 @@ def get_config_file_rules_colorspace_from_filepath(config_path, filepath): filepath (str): path leading to a file Returns: - Any[str, None]: matching colorspace name + Union[str, None]: matching colorspace name """ if not compatibility_check(): # python environment is not compatible with PyOpenColorIO @@ -837,13 +837,13 @@ def get_imageio_config( if override_global_config: config_data = _get_config_data( - host_ocio_config["filepath"], formatting_data, env + host_ocio_config["ocio_config"], formatting_data, env ) else: # get config path from global config_global = imageio_global["ocio_config"] config_data = _get_config_data( - config_global["filepath"], formatting_data, env + config_global["ocio_config"], formatting_data, env ) if not config_data: @@ -918,28 +918,13 @@ def get_imageio_file_rules(project_name, host_name, project_settings=None): Defaults to None. Returns: - dict: file rules data + list[dict[str, Any]]: file rules data """ project_settings = project_settings or get_project_settings(project_name) imageio_global, imageio_host = _get_imageio_settings( project_settings, host_name) - # get file rules from global and host_name - frules_global = imageio_global["file_rules"] - activate_global_rules = ( - frules_global.get("activate_global_file_rules", False) - # TODO: remove this in future - backward compatibility - or frules_global.get("enabled") - ) - global_rules = frules_global["rules"] - - if not activate_global_rules: - log.info( - "Colorspace global file rules are disabled." - ) - global_rules = {} - # host is optional, some might not have any settings frules_host = imageio_host.get("file_rules", {}) @@ -949,8 +934,24 @@ def get_imageio_file_rules(project_name, host_name, project_settings=None): # TODO: remove this in future - backward compatibility activate_host_rules = frules_host.get("enabled", False) - # return host rules if activated or global rules - return frules_host["rules"] if activate_host_rules else global_rules + if activate_host_rules: + return frules_host["rules"] + + # get file rules from global and host_name + frules_global = imageio_global["file_rules"] + activate_global_rules = ( + frules_global.get("activate_global_file_rules", False) + # TODO: remove this in future - backward compatibility + or frules_global.get("enabled") + ) + + if not activate_global_rules: + log.info( + "Colorspace global file rules are disabled." + ) + return [] + + return frules_global["rules"] def get_remapped_colorspace_to_native( From 85f8392ca8137c4ad002d7963d6e35df53d44af8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:08:10 +0100 Subject: [PATCH 044/149] fix key used to get ocio config path --- client/ayon_core/pipeline/colorspace.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index 70b7678d0a..1b795e1c39 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -837,13 +837,13 @@ def get_imageio_config( if override_global_config: config_data = _get_config_data( - host_ocio_config["ocio_config"], formatting_data, env + host_ocio_config["filepath"], formatting_data, env ) else: # get config path from global config_global = imageio_global["ocio_config"] config_data = _get_config_data( - config_global["ocio_config"], formatting_data, env + config_global["filepath"], formatting_data, env ) if not config_data: From 2f462dac7aa5475a8b0eb2802ebf4cfbafc5317d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:42:10 +0100 Subject: [PATCH 045/149] keep only 'get_asset_icon' as public function --- client/ayon_core/tools/utils/assets_widget.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index a97a289737..4af932a054 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -32,26 +32,26 @@ ASSET_UNDERLINE_COLORS_ROLE = QtCore.Qt.UserRole + 4 ASSET_PATH_ROLE = QtCore.Qt.UserRole + 5 -def get_default_asset_icon_name(has_children): +def _get_default_asset_icon_name(has_children): if has_children: return "fa.folder" return "fa.folder-o" -def get_asset_icon_color_from_doc(asset_doc): +def _get_asset_icon_color_from_doc(asset_doc): if asset_doc: return asset_doc["data"].get("color") return None -def get_asset_icon_name_from_doc(asset_doc): +def _get_asset_icon_name_from_doc(asset_doc): if asset_doc: return asset_doc["data"].get("icon") return None -def get_asset_icon_color(asset_doc): - icon_color = get_asset_icon_color_from_doc(asset_doc) +def _get_asset_icon_color(asset_doc): + icon_color = _get_asset_icon_color_from_doc(asset_doc) if icon_color: return icon_color return get_default_entity_icon_color() @@ -74,16 +74,16 @@ def get_asset_icon_by_name(icon_name, icon_color, has_children=False): ) -def get_asset_icon_name(asset_doc, has_children=True): - icon_name = get_asset_icon_name_from_doc(asset_doc) +def _get_asset_icon_name(asset_doc, has_children=True): + icon_name = _get_asset_icon_name_from_doc(asset_doc) if icon_name: return icon_name - return get_default_asset_icon_name(has_children) + return _get_default_asset_icon_name(has_children) def get_asset_icon(asset_doc, has_children=False): - icon_name = get_asset_icon_name(asset_doc, has_children) - icon_color = get_asset_icon_color(asset_doc) + icon_name = _get_asset_icon_name(asset_doc, has_children) + icon_color = _get_asset_icon_color(asset_doc) return get_qta_icon_by_name_and_color(icon_name, icon_color) From 9156bd08bd5744a06f828425c44ee350903eaba3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:42:20 +0100 Subject: [PATCH 046/149] removed unused 'get_asset_icon_by_name' --- client/ayon_core/tools/utils/assets_widget.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index 4af932a054..694675d877 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -57,23 +57,6 @@ def _get_asset_icon_color(asset_doc): return get_default_entity_icon_color() -def get_asset_icon_by_name(icon_name, icon_color, has_children=False): - if not icon_name: - icon_name = get_default_asset_icon_name(has_children) - - if icon_color: - icon_color = QtGui.QColor(icon_color) - else: - icon_color = get_default_entity_icon_color() - icon = get_qta_icon_by_name_and_color(icon_name, icon_color) - if icon is not None: - return icon - return get_qta_icon_by_name_and_color( - get_default_asset_icon_name(has_children), - icon_color - ) - - def _get_asset_icon_name(asset_doc, has_children=True): icon_name = _get_asset_icon_name_from_doc(asset_doc) if icon_name: From e3b0bb98afd21c6ad69fdbd202128461b6949822 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:42:29 +0100 Subject: [PATCH 047/149] added docstring to 'get_asset_icon' --- client/ayon_core/tools/utils/assets_widget.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index 694675d877..7c3fd8d97c 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -65,6 +65,20 @@ def _get_asset_icon_name(asset_doc, has_children=True): def get_asset_icon(asset_doc, has_children=False): + """Get asset icon. + + Deprecated: + This function will be removed in future releases. Use on your own + risk. + + Args: + asset_doc (dict): Asset document. + has_children (Optional[bool]): Asset has children assets. + + Returns: + QIcon: Asset icon. + + """ icon_name = _get_asset_icon_name(asset_doc, has_children) icon_color = _get_asset_icon_color(asset_doc) From b9e01b254ddca1d402c8a0a4570be2834b43aeda Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:58:25 +0100 Subject: [PATCH 048/149] addons can define their openpype alias name --- client/ayon_core/addon/base.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/ayon_core/addon/base.py b/client/ayon_core/addon/base.py index a3920c4acb..3b35476aed 100644 --- a/client/ayon_core/addon/base.py +++ b/client/ayon_core/addon/base.py @@ -788,6 +788,7 @@ class AddonsManager: addon_classes.append(modules_item) + aliased_names = [] for addon_cls in addon_classes: name = addon_cls.__name__ if issubclass(addon_cls, OpenPypeModule): @@ -807,6 +808,13 @@ class AddonsManager: self._addons.append(addon) self._addons_by_id[addon.id] = addon self._addons_by_name[addon.name] = addon + # NOTE This will be removed with release 1.0.0 of ayon-core + # please use carefully. + # Gives option to use alias name for addon for cases when + # name in OpenPype was not the same as in AYON. + name_alias = getattr(addon, "openpype_alias", None) + if name_alias: + aliased_names.append((name_alias, addon)) enabled_str = "X" if not addon.enabled: enabled_str = " " @@ -822,6 +830,17 @@ class AddonsManager: exc_info=True ) + for item in aliased_names: + name_alias, addon = item + if name_alias not in self._addons_by_name: + self._addons_by_name[name_alias] = addon + continue + self.log.warning( + "Alias name '{}' of addon '{}' is already assigned.".format( + name_alias, addon.name + ) + ) + if self._report is not None: report[self._report_total_key] = time.time() - time_start self._report["Initialization"] = report From 66cb5336d354b501f7c467854d74e37ec9faffcc Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 13 Feb 2024 18:03:44 +0000 Subject: [PATCH 049/149] Added an option to disable composite output --- .../ayon_core/hosts/blender/api/render_lib.py | 29 ++++++++++++++----- .../server/settings/render_settings.py | 4 +++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/hosts/blender/api/render_lib.py b/client/ayon_core/hosts/blender/api/render_lib.py index 73d327b1a8..91913f7913 100644 --- a/client/ayon_core/hosts/blender/api/render_lib.py +++ b/client/ayon_core/hosts/blender/api/render_lib.py @@ -55,6 +55,14 @@ def get_renderer(settings): ["renderer"]) +def get_compositing(settings): + """Get compositing from blender settings.""" + + return (settings["blender"] + ["RenderSettings"] + ["compositing"]) + + def get_render_product(output_path, name, aov_sep): """ Generate the path to the render product. Blender interprets the `#` @@ -184,7 +192,9 @@ def _create_aov_slot(name, aov_sep, slots, rpass_name, multi_exr, output_path): return slot, filepath -def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): +def set_node_tree( + output_path, render_product, name, aov_sep, ext, multilayer, compositing +): # Set the scene to use the compositor node tree to render bpy.context.scene.use_nodes = True @@ -250,11 +260,12 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): name, aov_sep, slots, pass_name, multi_exr, output_path) tree.links.new(render_layer_node.outputs["Image"], slot) - # Create a new socket for the composite output - pass_name = "composite" - comp_socket, filepath = _create_aov_slot( - name, aov_sep, slots, pass_name, multi_exr, output_path) - aov_file_products.append(("Composite", filepath)) + if compositing: + # Create a new socket for the composite output + pass_name = "composite" + comp_socket, filepath = _create_aov_slot( + name, aov_sep, slots, pass_name, multi_exr, output_path) + aov_file_products.append(("Composite", filepath)) # For each active render pass, we add a new socket to the output node # and link it @@ -278,7 +289,7 @@ def set_node_tree(output_path, render_product, name, aov_sep, ext, multilayer): tree.links.remove(link) # If there's a composite node, we connect its input with the new output - if composite_node: + if compositing and composite_node: for link in tree.links: if link.to_node == composite_node: tree.links.new(link.from_socket, comp_socket) @@ -321,6 +332,7 @@ def prepare_rendering(asset_group): ext = get_image_format(settings) multilayer = get_multilayer(settings) renderer = get_renderer(settings) + compositing = get_compositing(settings) set_render_format(ext, multilayer) bpy.context.scene.render.engine = renderer @@ -330,7 +342,8 @@ def prepare_rendering(asset_group): render_product = get_render_product(output_path, name, aov_sep) aov_file_product = set_node_tree( - output_path, render_product, name, aov_sep, ext, multilayer) + output_path, render_product, name, aov_sep, + ext, multilayer, compositing) # Clear the render filepath, so that the output is handled only by the # output node in the compositor. diff --git a/server_addon/blender/server/settings/render_settings.py b/server_addon/blender/server/settings/render_settings.py index a1f6d3114a..f992ea6fcc 100644 --- a/server_addon/blender/server/settings/render_settings.py +++ b/server_addon/blender/server/settings/render_settings.py @@ -127,6 +127,9 @@ class RenderSettingsModel(BaseSettingsModel): title="Renderer", enum_resolver=renderers_enum ) + compositing: bool = SettingsField( + title="Enable Compositing" + ) aov_list: list[str] = SettingsField( default_factory=list, enum_resolver=aov_list_enum, @@ -149,6 +152,7 @@ DEFAULT_RENDER_SETTINGS = { "image_format": "exr", "multilayer_exr": True, "renderer": "CYCLES", + "compositing": True, "aov_list": ["combined"], "custom_passes": [] } From f0eaf0c128b78fd8977c3eae60921b6290d947bd Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 15:19:56 +0800 Subject: [PATCH 050/149] code tweaks on workfile creators to make sure there is no error out --- .../ayon_core/hosts/max/plugins/create/create_workfile.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/create/create_workfile.py b/client/ayon_core/hosts/max/plugins/create/create_workfile.py index e5fec5f437..cb47a36678 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_workfile.py +++ b/client/ayon_core/hosts/max/plugins/create/create_workfile.py @@ -30,8 +30,8 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): if current_instance is None: current_instance_asset = None - - current_instance_asset = current_instance["folderPath"] + else: + current_instance_asset = current_instance["folderPath"] if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) @@ -39,12 +39,11 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): variant, task_name, asset_doc, project_name, host_name ) data = { + "folderPath": asset_name, "task": task_name, "variant": variant } - data["folderPath"] = asset_name - data.update( self.get_dynamic_data( variant, task_name, asset_doc, From d80ba2bac486711a41d1f889d4e0be3386c463cf Mon Sep 17 00:00:00 2001 From: Sponge96 Date: Wed, 14 Feb 2024 08:50:08 +0000 Subject: [PATCH 051/149] fix: removed artifact syntax Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- client/ayon_core/hosts/max/plugins/publish/save_scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/client/ayon_core/hosts/max/plugins/publish/save_scene.py index 37ff38bc59..7961631b2a 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scene.py +++ b/client/ayon_core/hosts/max/plugins/publish/save_scene.py @@ -20,4 +20,4 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): self.log.info(f"Saving current file: {current_file}") host.save_workfile(current_file) else: - self.log.debug("No unsaved changes, skipping file save..")") \ No newline at end of file + self.log.debug("No unsaved changes, skipping file save..") \ No newline at end of file From e43e2344195d57e53a064d2422e547f47a730f67 Mon Sep 17 00:00:00 2001 From: Sponge96 Date: Wed, 14 Feb 2024 08:50:45 +0000 Subject: [PATCH 052/149] refactor: replaced OP imports with ayon-core Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- client/ayon_core/hosts/max/plugins/publish/save_scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/client/ayon_core/hosts/max/plugins/publish/save_scene.py index 7961631b2a..1c59335ceb 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scene.py +++ b/client/ayon_core/hosts/max/plugins/publish/save_scene.py @@ -1,5 +1,5 @@ import pyblish.api -from openpype.pipeline import registered_host +from ayon_core.pipeline import registered_host class SaveCurrentScene(pyblish.api.ContextPlugin): From c9ddd6c9a270545d556fab4d391819c493c03666 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 17:06:41 +0800 Subject: [PATCH 053/149] clean up the code for current_instance['folderPath'] --- .../ayon_core/hosts/maya/plugins/create/create_workfile.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/create/create_workfile.py b/client/ayon_core/hosts/maya/plugins/create/create_workfile.py index 396ad6ffbb..dee574018f 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_workfile.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_workfile.py @@ -29,11 +29,6 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name - if current_instance is None: - current_instance_asset = None - else: - current_instance_asset = current_instance["folderPath"] - if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -55,7 +50,7 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): ) self._add_instance_to_context(current_instance) elif ( - current_instance_asset != asset_name + current_instance["folderPath"] != asset_name or current_instance["task"] != task_name ): # Update instance context if is not the same From 9615a02aace1ad2aa6433c4172d6b42bb1f75746 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 17:10:27 +0800 Subject: [PATCH 054/149] clean up the code of current_instance['folderPath'] --- .../ayon_core/hosts/max/plugins/create/create_workfile.py | 7 +------ .../ayon_core/hosts/maya/plugins/create/create_workfile.py | 7 ++++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/create/create_workfile.py b/client/ayon_core/hosts/max/plugins/create/create_workfile.py index cb47a36678..ce4d8b976d 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_workfile.py +++ b/client/ayon_core/hosts/max/plugins/create/create_workfile.py @@ -28,11 +28,6 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name - if current_instance is None: - current_instance_asset = None - else: - current_instance_asset = current_instance["folderPath"] - if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -58,7 +53,7 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): self._add_instance_to_context(current_instance) imprint(instance_node.name, current_instance.data) elif ( - current_instance_asset != asset_name + current_instance["folderPath"] != asset_name or current_instance["task"] != task_name ): # Update instance context if is not the same diff --git a/client/ayon_core/hosts/maya/plugins/create/create_workfile.py b/client/ayon_core/hosts/maya/plugins/create/create_workfile.py index dee574018f..396ad6ffbb 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_workfile.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_workfile.py @@ -29,6 +29,11 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name + if current_instance is None: + current_instance_asset = None + else: + current_instance_asset = current_instance["folderPath"] + if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -50,7 +55,7 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): ) self._add_instance_to_context(current_instance) elif ( - current_instance["folderPath"] != asset_name + current_instance_asset != asset_name or current_instance["task"] != task_name ): # Update instance context if is not the same From a36bd63da7645d2afe90d27c170de4d66fca574a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 17:15:05 +0800 Subject: [PATCH 055/149] some style tweaks on pipeline --- client/ayon_core/hosts/max/api/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index c9b74cea9e..c26e697429 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -59,9 +59,9 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): rt.callbacks.addScript(rt.Name('filePostOpen'), lib.check_colorspace) - + rt.callbacks.addScript(rt.Name('postWorkspaceChange'), - self._deferred_menu_creation) + self._deferred_menu_creation) def workfile_has_unsaved_changes(self): return rt.getSaveRequired() From ecd69f0a511890e6356769e092ca4143c4c862f6 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 17:58:10 +0800 Subject: [PATCH 056/149] Separating collect current files from the collect workfile --- .../plugins/publish/collect_current_file.py | 22 ++++++++++++ .../max/plugins/publish/collect_workfile.py | 34 ++++++++----------- 2 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 client/ayon_core/hosts/max/plugins/publish/collect_current_file.py diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py b/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py new file mode 100644 index 0000000000..b10f3d51bc --- /dev/null +++ b/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py @@ -0,0 +1,22 @@ +import os +import pyblish.api + +from pymxs import runtime as rt + + +class CollectCurrentFile(pyblish.api.ContextPlugin): + """Inject the current working file.""" + + order = pyblish.api.CollectorOrder - 0.4 + label = "Max Current File" + hosts = ['max'] + + def process(self, context): + """Inject the current working file""" + folder = rt.maxFilePath + file = rt.maxFileName + if not folder or not file: + self.log.error("Scene is not saved.") + current_file = os.path.join(folder, file) + + context.data["currentFile"] = current_file diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py index 4dbaf28bf7..775e22ff0e 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py @@ -12,6 +12,7 @@ class CollectWorkfile(pyblish.api.InstancePlugin): order = pyblish.api.CollectorOrder - 0.01 label = "Collect 3dsmax Workfile" hosts = ['max'] + families = ["workfile"] def process(self, instance): """Inject the current working file.""" @@ -20,33 +21,28 @@ class CollectWorkfile(pyblish.api.InstancePlugin): file = rt.maxFileName if not folder or not file: self.log.error("Scene is not saved.") - current_file = os.path.join(folder, file) - - context.data['currentFile'] = current_file - ext = os.path.splitext(file)[-1].lstrip(".") data = {} - # create instance - data.update({ - "setMembers": [current_file], - "frameStart": context.data['frameStart'], - "frameEnd": context.data['frameEnd'], - "handleStart": context.data['handleStart'], - "handleEnd": context.data['handleEnd'] + "setMembers": context.data["currentFile"], + "frameStart": context.data["frameStart"], + "frameEnd": context.data["frameEnd"], + "handleStart": context.data["handleStart"], + "handleEnd": context.data["handleEnd"] }) - data['representations'] = [{ - 'name': ext, - 'ext': ext, - 'files': file, + data["representations"] = [{ + "name": ext, + "ext": ext, + "files": file, "stagingDir": folder, }] instance.data.update(data) - self.log.debug('Collected data: {}'.format(data)) - self.log.debug('Collected instance: {}'.format(file)) - self.log.debug('Scene path: {}'.format(current_file)) - self.log.debug('staging Dir: {}'.format(folder)) + self.log.debug("Collected data: {}".format(data)) + self.log.debug("Collected instance: {}".format(file)) + self.log.debug("Scene path: {}".format( + context.data["currentFile"])) + self.log.debug("staging Dir: {}".format(folder)) From e86555b2cc6eeb799118f9ea7f16fad5ad676c12 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 11:43:23 +0100 Subject: [PATCH 057/149] use correct dirmap key in nuke --- client/ayon_core/hosts/nuke/api/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/api/pipeline.py b/client/ayon_core/hosts/nuke/api/pipeline.py index 7483d404ec..735426240e 100644 --- a/client/ayon_core/hosts/nuke/api/pipeline.py +++ b/client/ayon_core/hosts/nuke/api/pipeline.py @@ -179,7 +179,7 @@ def add_nuke_callbacks(): nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) - if nuke_settings["nuke_dirmap"]["enabled"]: + if nuke_settings["dirmap"]["enabled"]: log.info("Added Nuke's dir-mapping callback ...") # Add dirmap for file paths. nuke.addFilenameFilter(dirmap_file_name_filter) From 4d947d7ac77300de276d2819876d423284607221 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 12:12:29 +0100 Subject: [PATCH 058/149] removed clockify conversion --- client/ayon_core/settings/ayon_settings.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 8795fd0650..2577a3af06 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -76,19 +76,6 @@ def _convert_kitsu_system_settings( output["modules"]["kitsu"] = kitsu_settings -def _convert_clockify_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("clockify") is not None - clockify_settings = default_settings["modules"]["clockify"] - clockify_settings["enabled"] = enabled - if enabled: - clockify_settings["workspace_name"] = ( - ayon_settings["clockify"]["workspace_name"] - ) - output["modules"]["clockify"] = clockify_settings - - def _convert_deadline_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -127,7 +114,6 @@ def _convert_modules_system( # TODO add 'enabled' values for func in ( _convert_kitsu_system_settings, - _convert_clockify_system_settings, _convert_deadline_system_settings, _convert_royalrender_system_settings, ): @@ -135,6 +121,7 @@ def _convert_modules_system( for key in { "timers_manager", + "clockify", }: if addon_versions.get(key): output[key] = ayon_settings From fa55d1556215fe00b5ed73366db148a1a2b18983 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 12:13:03 +0100 Subject: [PATCH 059/149] modified clockify addon to use AYON settings --- .../modules/clockify/clockify_module.py | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/modules/clockify/clockify_module.py b/client/ayon_core/modules/clockify/clockify_module.py index adb7eb66af..58407bfe94 100644 --- a/client/ayon_core/modules/clockify/clockify_module.py +++ b/client/ayon_core/modules/clockify/clockify_module.py @@ -2,22 +2,27 @@ import os import threading import time -from ayon_core.modules import OpenPypeModule, ITrayModule, IPluginPaths +from ayon_core.modules import AYONAddon, ITrayModule, IPluginPaths from ayon_core.client import get_asset_by_name from .constants import CLOCKIFY_FTRACK_USER_PATH, CLOCKIFY_FTRACK_SERVER_PATH -class ClockifyModule(OpenPypeModule, ITrayModule, IPluginPaths): +class ClockifyModule(AYONAddon, ITrayModule, IPluginPaths): name = "clockify" - def initialize(self, modules_settings): - clockify_settings = modules_settings[self.name] - self.enabled = clockify_settings["enabled"] - self.workspace_name = clockify_settings["workspace_name"] + def initialize(self, studio_settings): + enabled = self.name in studio_settings + workspace_name = None + if enabled: + clockify_settings = studio_settings[self.name] + workspace_name = clockify_settings["workspace_name"] - if self.enabled and not self.workspace_name: - raise Exception("Clockify Workspace is not set in settings.") + if enabled and workspace_name: + self.log.warning("Clockify Workspace is not set in settings.") + enabled = False + self.enabled = enabled + self.workspace_name = workspace_name self.timer_manager = None self.MessageWidgetClass = None From 4be12c71efe3dcb65e4e8887eeaf1a775f73014d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 19:47:05 +0800 Subject: [PATCH 060/149] move debug msg of scene path into colelct current file --- .../ayon_core/hosts/max/plugins/publish/collect_current_file.py | 1 + client/ayon_core/hosts/max/plugins/publish/collect_workfile.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py b/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py index b10f3d51bc..689a357c53 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py @@ -20,3 +20,4 @@ class CollectCurrentFile(pyblish.api.ContextPlugin): current_file = os.path.join(folder, file) context.data["currentFile"] = current_file + self.log.debug("Scene path: {}".format(current_file)) diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py index 775e22ff0e..6eec0f7292 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py @@ -43,6 +43,4 @@ class CollectWorkfile(pyblish.api.InstancePlugin): instance.data.update(data) self.log.debug("Collected data: {}".format(data)) self.log.debug("Collected instance: {}".format(file)) - self.log.debug("Scene path: {}".format( - context.data["currentFile"])) self.log.debug("staging Dir: {}".format(folder)) From 32dde5f02e94fcd8091877eea7ddb003d3b807da Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 13:30:06 +0100 Subject: [PATCH 061/149] 'get_ayon_settings' is in settings functions --- client/ayon_core/settings/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/settings/__init__.py b/client/ayon_core/settings/__init__.py index ed3aaef7d4..f0e5c95efe 100644 --- a/client/ayon_core/settings/__init__.py +++ b/client/ayon_core/settings/__init__.py @@ -9,6 +9,7 @@ from .lib import ( get_current_project_settings, get_local_settings, ) +from .ayon_settings import get_ayon_settings __all__ = ( @@ -20,4 +21,6 @@ __all__ = ( "get_project_settings", "get_current_project_settings", "get_local_settings", + + "get_ayon_settings", ) From 731a4d7b29f97742ffa2c2647e753d9aa553b908 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 13:43:04 +0100 Subject: [PATCH 062/149] simplify project settings conversion --- client/ayon_core/settings/ayon_settings.py | 110 --------------------- 1 file changed, 110 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 2577a3af06..6fdeec574f 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -188,59 +188,6 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions): # --------- Project settings --------- -def _convert_blender_project_settings(ayon_settings, output): - if "blender" not in ayon_settings: - return - ayon_blender = ayon_settings["blender"] - - output["blender"] = ayon_blender - - -def _convert_celaction_project_settings(ayon_settings, output): - if "celaction" not in ayon_settings: - return - - ayon_celaction = ayon_settings["celaction"] - - output["celaction"] = ayon_celaction - - -def _convert_flame_project_settings(ayon_settings, output): - if "flame" not in ayon_settings: - return - - ayon_flame = ayon_settings["flame"] - - output["flame"] = ayon_flame - - -def _convert_fusion_project_settings(ayon_settings, output): - if "fusion" not in ayon_settings: - return - - ayon_fusion = ayon_settings["fusion"] - - output["fusion"] = ayon_fusion - - -def _convert_maya_project_settings(ayon_settings, output): - if "maya" not in ayon_settings: - return - - ayon_maya = ayon_settings["maya"] - - output["maya"] = ayon_maya - - -def _convert_3dsmax_project_settings(ayon_settings, output): - if "max" not in ayon_settings: - return - - ayon_max = ayon_settings["max"] - - output["max"] = ayon_max - - def _convert_nuke_knobs(knobs): new_knobs = [] for knob in knobs: @@ -456,39 +403,6 @@ def _convert_hiero_project_settings(ayon_settings, output): output["hiero"] = ayon_hiero -def _convert_photoshop_project_settings(ayon_settings, output): - if "photoshop" not in ayon_settings: - return - - ayon_photoshop = ayon_settings["photoshop"] - output["photoshop"] = ayon_photoshop - - -def _convert_substancepainter_project_settings(ayon_settings, output): - if "substancepainter" not in ayon_settings: - return - - ayon_substance_painter = ayon_settings["substancepainter"] - output["substancepainter"] = ayon_substance_painter - - -def _convert_tvpaint_project_settings(ayon_settings, output): - if "tvpaint" not in ayon_settings: - return - - ayon_tvpaint = ayon_settings["tvpaint"] - output["tvpaint"] = ayon_tvpaint - - -def _convert_traypublisher_project_settings(ayon_settings, output): - if "traypublisher" not in ayon_settings: - return - - ayon_traypublisher = ayon_settings["traypublisher"] - - output["traypublisher"] = ayon_traypublisher - - def _convert_webpublisher_project_settings(ayon_settings, output): if "webpublisher" not in ayon_settings: return @@ -747,35 +661,11 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): def convert_project_settings(ayon_settings, default_settings): - # Missing settings - # - standalonepublisher default_settings = copy.deepcopy(default_settings) output = {} - exact_match = { - "aftereffects", - "harmony", - "houdini", - "resolve", - "unreal", - "applications", - "deadline", - } - for key in exact_match: - if key in ayon_settings: - output[key] = ayon_settings[key] - _convert_blender_project_settings(ayon_settings, output) - _convert_celaction_project_settings(ayon_settings, output) - _convert_flame_project_settings(ayon_settings, output) - _convert_fusion_project_settings(ayon_settings, output) - _convert_maya_project_settings(ayon_settings, output) - _convert_3dsmax_project_settings(ayon_settings, output) _convert_nuke_project_settings(ayon_settings, output) _convert_hiero_project_settings(ayon_settings, output) - _convert_photoshop_project_settings(ayon_settings, output) - _convert_substancepainter_project_settings(ayon_settings, output) - _convert_tvpaint_project_settings(ayon_settings, output) - _convert_traypublisher_project_settings(ayon_settings, output) _convert_webpublisher_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) From 6b1b4367bbb5f62b9e9d03e22d82f21675d104bf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 13:43:19 +0100 Subject: [PATCH 063/149] simplify system settings conversion --- client/ayon_core/settings/ayon_settings.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 6fdeec574f..7e9fad314c 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -164,9 +164,6 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions): output = { "modules": {} } - if "applications" in ayon_settings: - output["applications"] = ayon_settings["applications"] - if "core" in ayon_settings: _convert_general(ayon_settings, output, default_settings) From 8324b971a8a023dce4f25f9ce2d5196d35ad1f8c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 14:01:47 +0100 Subject: [PATCH 064/149] handle additional applications correctly --- client/ayon_core/lib/applications.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 70aa9811c7..2b0b855c81 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -419,7 +419,14 @@ class ApplicationManager: # Prepare known applications app_defs = applications_addon_settings["applications"] additional_apps = app_defs.pop("additional_apps") - app_defs.update(additional_apps) + for additional_app in additional_apps: + app_name = additional_app.pop("name") + if app_name in app_defs: + self.log.warning(( + "Additional application '{}' is already" + " in built-in applications." + ).format(app_name)) + app_defs[app_name] = additional_app for group_name, variant_defs in app_defs.items(): group = ApplicationGroup(group_name, variant_defs, self) From 4113ff7bf0b4dc396aa829352161aca6fdef9eec Mon Sep 17 00:00:00 2001 From: Oscar Domingo Date: Wed, 14 Feb 2024 14:52:18 +0000 Subject: [PATCH 065/149] Add `rez` packages generation for `server_addons` Allow to generate `rez` compatible packages for the `server_addons`, will create a `package.py` which then is also included in the `.zip`. --- server_addon/create_ayon_addons.py | 68 +++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index 08443d6588..f9f31dd9b0 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -144,11 +144,18 @@ def create_addon_zip( output_dir: Path, addon_name: str, addon_version: str, - keep_source: bool + keep_source: bool, + rez_package: bool, ): zip_filepath = output_dir / f"{addon_name}-{addon_version}.zip" + + if rez_package: + zip_filepath = output_dir / f"{addon_name}-{addon_version}-rez.zip" + addon_output_dir = output_dir / addon_name / addon_version with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf: + # TODO: Decide if we want to keep this for first pass checking without + # executing any python. Otherwiseh we can be removed zipf.writestr( "manifest.json", json.dumps({ @@ -168,8 +175,14 @@ def create_addon_zip( src_path = os.path.join(root, filename) if rel_root: dst_path = os.path.join("addon", rel_root, filename) + if rez_package: + dst_path = os.path.join(rel_root, filename) else: dst_path = os.path.join("addon", filename) + + if rez_package: + dst_path = filename + zipf.write(src_path, dst_path) if not keep_source: @@ -180,7 +193,8 @@ def create_addon_package( addon_dir: Path, output_dir: Path, create_zip: bool, - keep_source: bool + keep_source: bool, + rez_package: bool, ): server_dir = addon_dir / "server" addon_version = get_addon_version(addon_dir) @@ -191,22 +205,37 @@ def create_addon_package( addon_output_dir.mkdir(parents=True) # Copy server content - src_root = os.path.normpath(str(server_dir.absolute())) - src_root_offset = len(src_root) + 1 - for root, _, filenames in os.walk(str(server_dir)): - dst_root = addon_output_dir - if root != src_root: - rel_root = root[src_root_offset:] - dst_root = dst_root / rel_root + if not rez_package: + src_root = os.path.normpath(str(server_dir.absolute())) + src_root_offset = len(src_root) + 1 + for root, _, filenames in os.walk(str(server_dir)): + dst_root = addon_output_dir + if root != src_root: + rel_root = root[src_root_offset:] + dst_root = dst_root / rel_root - dst_root.mkdir(parents=True, exist_ok=True) - for filename in filenames: - src_path = os.path.join(root, filename) - shutil.copy(src_path, str(dst_root)) + dst_root.mkdir(parents=True, exist_ok=True) + for filename in filenames: + src_path = os.path.join(root, filename) + shutil.copy(src_path, str(dst_root)) + else: + package_py = addon_output_dir / "package.py" + + with open(package_py, "w+") as pkg_py: + pkg_py.write( + f"""name = "{addon_dir.name}" +version = "{addon_version}" +plugin_for = ["ayon_server"] +build_command = "python {{root}}/rezbuild.py" +""" + ) + shutil.copytree( + server_dir, addon_output_dir / "server", dirs_exist_ok=True + ) if create_zip: create_addon_zip( - output_dir, addon_dir.name, addon_version, keep_source + output_dir, addon_dir.name, addon_version, keep_source, rez_package ) @@ -216,6 +245,7 @@ def main( keep_source=False, clear_output_dir=False, addons=None, + rez_package=False, ): current_dir = Path(os.path.dirname(os.path.abspath(__file__))) root_dir = current_dir.parent @@ -250,7 +280,7 @@ def main( continue create_addon_package( - addon_dir, output_dir, create_zip, keep_source + addon_dir, output_dir, create_zip, keep_source, rez_package ) print(f"- package '{addon_dir.name}' created") @@ -300,6 +330,13 @@ if __name__ == "__main__": action="append", help="Limit addon creation to given addon name", ) + parser.add_argument( + "-r", + "--rez", + dest="rez_package", + action="store_true", + help="Make it a Rez-compatible package", + ) args = parser.parse_args(sys.argv[1:]) main( @@ -308,4 +345,5 @@ if __name__ == "__main__": args.keep_sources, args.clear_output_dir, args.addons, + args.rez_package, ) From 0744c27c91d8eac2d9742827f6dd1a687f1189bf Mon Sep 17 00:00:00 2001 From: Oscar Domingo Date: Wed, 14 Feb 2024 14:56:52 +0000 Subject: [PATCH 066/149] `package.py` Ensure we require the correct `ayon_server` version For more info on `rez` package requests syntax check: https://rez.readthedocs.io/en/latest/basic_concepts.html#package-requests-concept --- package.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.py b/package.py index d7266d852b..3b451e0078 100644 --- a/package.py +++ b/package.py @@ -5,4 +5,7 @@ version = "0.2.1-dev.1" client_dir = "ayon_core" plugin_for = ["ayon_server"] -ayon_version = ">=1.0.3,<2.0.0" +requires = [ + "~ayon_server-1.0.3+<2.0.0", +] + From 4c0651f593213838e2a2b21a34ccebba81bea732 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 18:18:02 +0100 Subject: [PATCH 067/149] create only rez packages --- server_addon/create_ayon_addons.py | 77 ++++++++---------------------- 1 file changed, 19 insertions(+), 58 deletions(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index f9f31dd9b0..5e06d8ee8a 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -40,6 +40,11 @@ IGNORED_HOSTS = [ IGNORED_MODULES = [] +PACKAGE_PY_TEMPLATE = """name = "{addon_name}" +version = "{addon_version}" +plugin_for = ["ayon_server"] +""" + class ZipFileLongPaths(zipfile.ZipFile): """Allows longer paths in zip files. @@ -145,24 +150,11 @@ def create_addon_zip( addon_name: str, addon_version: str, keep_source: bool, - rez_package: bool, ): zip_filepath = output_dir / f"{addon_name}-{addon_version}.zip" - if rez_package: - zip_filepath = output_dir / f"{addon_name}-{addon_version}-rez.zip" - addon_output_dir = output_dir / addon_name / addon_version with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf: - # TODO: Decide if we want to keep this for first pass checking without - # executing any python. Otherwiseh we can be removed - zipf.writestr( - "manifest.json", - json.dumps({ - "addon_name": addon_name, - "addon_version": addon_version - }) - ) # Add client code content to zip src_root = os.path.normpath(str(addon_output_dir.absolute())) src_root_offset = len(src_root) + 1 @@ -174,14 +166,9 @@ def create_addon_zip( for filename in filenames: src_path = os.path.join(root, filename) if rel_root: - dst_path = os.path.join("addon", rel_root, filename) - if rez_package: - dst_path = os.path.join(rel_root, filename) + dst_path = os.path.join(rel_root, filename) else: - dst_path = os.path.join("addon", filename) - - if rez_package: - dst_path = filename + dst_path = filename zipf.write(src_path, dst_path) @@ -194,9 +181,7 @@ def create_addon_package( output_dir: Path, create_zip: bool, keep_source: bool, - rez_package: bool, ): - server_dir = addon_dir / "server" addon_version = get_addon_version(addon_dir) addon_output_dir = output_dir / addon_dir.name / addon_version @@ -205,37 +190,22 @@ def create_addon_package( addon_output_dir.mkdir(parents=True) # Copy server content - if not rez_package: - src_root = os.path.normpath(str(server_dir.absolute())) - src_root_offset = len(src_root) + 1 - for root, _, filenames in os.walk(str(server_dir)): - dst_root = addon_output_dir - if root != src_root: - rel_root = root[src_root_offset:] - dst_root = dst_root / rel_root + package_py = addon_output_dir / "package.py" + package_py_content = PACKAGE_PY_TEMPLATE.format( + addon_name=addon_dir.name, addon_version=addon_version + ) - dst_root.mkdir(parents=True, exist_ok=True) - for filename in filenames: - src_path = os.path.join(root, filename) - shutil.copy(src_path, str(dst_root)) - else: - package_py = addon_output_dir / "package.py" + with open(package_py, "w+") as pkg_py: + pkg_py.write(package_py_content) - with open(package_py, "w+") as pkg_py: - pkg_py.write( - f"""name = "{addon_dir.name}" -version = "{addon_version}" -plugin_for = ["ayon_server"] -build_command = "python {{root}}/rezbuild.py" -""" - ) - shutil.copytree( - server_dir, addon_output_dir / "server", dirs_exist_ok=True - ) + server_dir = addon_dir / "server" + shutil.copytree( + server_dir, addon_output_dir / "server", dirs_exist_ok=True + ) if create_zip: create_addon_zip( - output_dir, addon_dir.name, addon_version, keep_source, rez_package + output_dir, addon_dir.name, addon_version, keep_source ) @@ -245,7 +215,6 @@ def main( keep_source=False, clear_output_dir=False, addons=None, - rez_package=False, ): current_dir = Path(os.path.dirname(os.path.abspath(__file__))) root_dir = current_dir.parent @@ -280,7 +249,7 @@ def main( continue create_addon_package( - addon_dir, output_dir, create_zip, keep_source, rez_package + addon_dir, output_dir, create_zip, keep_source ) print(f"- package '{addon_dir.name}' created") @@ -330,13 +299,6 @@ if __name__ == "__main__": action="append", help="Limit addon creation to given addon name", ) - parser.add_argument( - "-r", - "--rez", - dest="rez_package", - action="store_true", - help="Make it a Rez-compatible package", - ) args = parser.parse_args(sys.argv[1:]) main( @@ -345,5 +307,4 @@ if __name__ == "__main__": args.keep_sources, args.clear_output_dir, args.addons, - args.rez_package, ) From 40a9788536fd06a40d54f351e9a55f8c5d96a580 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 18:32:09 +0100 Subject: [PATCH 068/149] fix applications settings --- server_addon/applications/server/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server_addon/applications/server/__init__.py b/server_addon/applications/server/__init__.py index e782e8a591..d5c2de3df3 100644 --- a/server_addon/applications/server/__init__.py +++ b/server_addon/applications/server/__init__.py @@ -92,8 +92,9 @@ class ApplicationsAddon(BaseServerAddon): settings_model = ApplicationsAddonSettings async def get_default_settings(self): - applications_path = os.path.join(self.addon_dir, "applications.json") - tools_path = os.path.join(self.addon_dir, "tools.json") + server_dir = os.path.join(self.addon_dir, "server") + applications_path = os.path.join(server_dir, "applications.json") + tools_path = os.path.join(server_dir, "tools.json") default_values = copy.deepcopy(DEFAULT_VALUES) with open(applications_path, "r") as stream: default_values.update(json.load(stream)) From 1d72cd102356bb5d0b4ae0f8555dec46433311cd Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Feb 2024 16:47:05 +0800 Subject: [PATCH 069/149] bug fix remove items not working in scene inventory manager --- client/ayon_core/hosts/max/api/pipeline.py | 17 +++++++++++++++++ .../hosts/max/plugins/load/load_camera_fbx.py | 8 ++++---- .../hosts/max/plugins/load/load_max_scene.py | 9 +++++---- .../hosts/max/plugins/load/load_model.py | 8 +++++--- .../hosts/max/plugins/load/load_model_fbx.py | 9 +++++---- .../hosts/max/plugins/load/load_model_obj.py | 6 +++--- .../hosts/max/plugins/load/load_model_usd.py | 5 +++-- .../hosts/max/plugins/load/load_pointcache.py | 5 +++-- .../plugins/load/load_pointcache_ornatrix.py | 5 +++-- .../hosts/max/plugins/load/load_pointcloud.py | 6 +++--- .../max/plugins/load/load_redshift_proxy.py | 6 +++--- .../hosts/max/plugins/load/load_tycache.py | 9 ++++----- 12 files changed, 58 insertions(+), 35 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index c26e697429..106c29fd26 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -242,3 +242,20 @@ def get_previous_loaded_object(container: str): if str(obj) in sel_list: node_list.append(obj) return node_list + + +def remove_container_data(container: str): + """Function to remove container data after updating, switching or deleting it. + + Args: + container (str): container + """ + if container.modifiers[0].name == "OP Data": + all_set_members_names = [ + member.node for member + in container.modifiers[0].openPypeData.all_handles] + for current_set_member in all_set_members_names: + rt.Delete(current_set_member) + rt.deleteModifier(container, container.modifiers[0]) + + rt.Delete(container) diff --git a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py index 34b120c179..d7eebdbc3a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py @@ -1,6 +1,6 @@ import os -from ayon_core.hosts.max.api import lib, maintained_selection +from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( unique_namespace, get_namespace, @@ -9,7 +9,8 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -94,6 +95,5 @@ class FbxLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py index 7267d7a59e..81f3af089f 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py +++ b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py @@ -7,8 +7,10 @@ from ayon_core.hosts.max.api.lib import ( object_transform_set ) from ayon_core.hosts.max.api.pipeline import ( - containerise, get_previous_loaded_object, - update_custom_attribute_data + containerise, + get_previous_loaded_object, + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -93,6 +95,5 @@ class MaxSceneLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model.py b/client/ayon_core/hosts/max/plugins/load/load_model.py index 796e1b80ad..28ec7be01f 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model.py @@ -2,11 +2,13 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object + get_previous_loaded_object, + remove_container_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( - maintained_selection, unique_namespace + maintained_selection, + unique_namespace ) @@ -99,7 +101,7 @@ class ModelAbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py index 827cf63b39..81ad84546a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py @@ -1,8 +1,10 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( - containerise, get_previous_loaded_object, - update_custom_attribute_data + containerise, + get_previous_loaded_object, + update_custom_attribute_data, + remove_container_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -92,6 +94,5 @@ class FbxModelLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py index 22d3d4b58a..1023b67f0c 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py @@ -11,7 +11,8 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -84,6 +85,5 @@ class ObjLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py index 8d42219217..6a08bebf5a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py @@ -13,7 +13,8 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -114,4 +115,4 @@ class ModelUSDLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py index a92fa66757..d7267afb7d 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py @@ -10,7 +10,8 @@ from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import unique_namespace from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object + get_previous_loaded_object, + remove_container_data ) @@ -105,7 +106,7 @@ class AbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py index 27b2e271d2..5b48e5d189 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py @@ -4,7 +4,8 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.hosts.max.api.lib import ( @@ -105,4 +106,4 @@ class OxAbcLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) \ No newline at end of file diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py index 45e3da5621..7f4fba50b3 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py @@ -8,7 +8,8 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -63,6 +64,5 @@ class PointCloudLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py index 3f73210c24..3ccc5cc5e1 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py @@ -9,7 +9,8 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, update_custom_attribute_data, - get_previous_loaded_object + get_previous_loaded_object, + remove_container_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -72,6 +73,5 @@ class RedshiftProxyLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_tycache.py b/client/ayon_core/hosts/max/plugins/load/load_tycache.py index 48fb5c447a..97f41026b4 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_tycache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_tycache.py @@ -1,13 +1,13 @@ import os from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import ( - unique_namespace, - + unique_namespace ) from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -59,6 +59,5 @@ class TyCacheLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) From 8e9fd531d0935aa56d20efaacd3b91088a01c4a5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 10:23:56 +0100 Subject: [PATCH 070/149] change color types back to their previous type --- .../plugins/publish/extract_sequence.py | 2 +- server/settings/publish_plugins.py | 18 +- server_addon/maya/server/settings/loaders.py | 192 ++++++++++-------- .../maya/server/settings/publish_playblast.py | 44 ++-- .../server/settings/publish_plugins.py | 13 +- 5 files changed, 157 insertions(+), 112 deletions(-) diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py b/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py index 6d54d8ec32..0ab9fbd038 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py @@ -31,7 +31,7 @@ class ExtractSequence(pyblish.api.Extractor): families = ["review", "render"] # Modifiable with settings - review_bg = [255, 255, 255, 255] + review_bg = [255, 255, 255, 1.0] def process(self, instance): self.log.info( diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index c01fb92b9c..9b5f3ae571 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -387,14 +387,22 @@ class ExtractReviewOutputDefModel(BaseSettingsModel): "Crop input overscan. See the documentation for more information." ) ) - overscan_color: ColorRGB_uint8 = SettingsField( - (0, 0, 0), + overscan_color: ColorRGBA_uint8 = SettingsField( + (0, 0, 0, 0.0), title="Overscan color", description=( "Overscan color is used when input aspect ratio is not" " same as output aspect ratio." ) ) + # overscan_color: ColorRGB_uint8 = SettingsField( + # (0, 0, 0), + # title="Overscan color", + # description=( + # "Overscan color is used when input aspect ratio is not" + # " same as output aspect ratio." + # ) + # ) width: int = SettingsField( 0, ge=0, @@ -901,7 +909,8 @@ DEFAULT_PUBLISH_VALUES = { "single_frame_filter": "single_frame" }, "overscan_crop": "", - "overscan_color": [0, 0, 0], + # "overscan_color": [0, 0, 0], + "overscan_color": [0, 0, 0, 0.0], "width": 1920, "height": 1080, "scale_pixel_aspect": True, @@ -946,7 +955,8 @@ DEFAULT_PUBLISH_VALUES = { "single_frame_filter": "multi_frame" }, "overscan_crop": "", - "overscan_color": [0, 0, 0], + # "overscan_color": [0, 0, 0], + "overscan_color": [0, 0, 0, 0.0], "width": 0, "height": 0, "scale_pixel_aspect": True, diff --git a/server_addon/maya/server/settings/loaders.py b/server_addon/maya/server/settings/loaders.py index b8264a56ef..3e8d368a6b 100644 --- a/server_addon/maya/server/settings/loaders.py +++ b/server_addon/maya/server/settings/loaders.py @@ -3,70 +3,86 @@ from ayon_server.types import ColorRGB_float class ColorsSetting(BaseSettingsModel): - model: ColorRGB_float = SettingsField( - (0.82, 0.52, 0.12), - title="Model:" - ) - rig: ColorRGB_float = SettingsField( - (0.23, 0.89, 0.92), - title="Rig:" - ) - pointcache: ColorRGB_float = SettingsField( - (0.37, 0.82, 0.12), - title="Pointcache:" - ) - animation: ColorRGB_float = SettingsField( - (0.37, 0.82, 0.12), - title="Animation:" - ) - ass: ColorRGB_float = SettingsField( - (0.98, 0.53, 0.21), - title="Arnold StandIn:" - ) - camera: ColorRGB_float = SettingsField( - (0.53, 0.45, 0.96), - title="Camera:" - ) - fbx: ColorRGB_float = SettingsField( - (0.84, 0.65, 1.0), - title="FBX:" - ) - mayaAscii: ColorRGB_float = SettingsField( - (0.26, 0.68, 1.0), - title="Maya Ascii:" - ) - mayaScene: ColorRGB_float = SettingsField( - (0.26, 0.68, 1.0), - title="Maya Scene:" - ) - setdress: ColorRGB_float = SettingsField( - (1.0, 0.98, 0.35), - title="Set Dress:" - ) - layout: ColorRGB_float = SettingsField( - (1.0, 0.98, 0.35), - title="Layout:" - ) - vdbcache: ColorRGB_float = SettingsField( - (0.98, 0.21, 0.0), - title="VDB Cache:" - ) - vrayproxy: ColorRGB_float = SettingsField( - (1.0, 0.59, 0.05), - title="VRay Proxy:" - ) - vrayscene_layer: ColorRGB_float = SettingsField( - (1.0, 0.59, 0.05), - title="VRay Scene:" - ) - yeticache: ColorRGB_float = SettingsField( - (0.39, 0.81, 0.86), - title="Yeti Cache:" - ) - yetiRig: ColorRGB_float = SettingsField( - (0.0, 0.80, 0.49), - title="Yeti Rig:" - ) + model: ColorRGBA_uint8 = SettingsField( + (209, 132, 30, 1.0), title="Model:") + rig: ColorRGBA_uint8 = SettingsField( + (59, 226, 235, 1.0), title="Rig:") + pointcache: ColorRGBA_uint8 = SettingsField( + (94, 209, 30, 1.0), title="Pointcache:") + animation: ColorRGBA_uint8 = SettingsField( + (94, 209, 30, 1.0), title="Animation:") + ass: ColorRGBA_uint8 = SettingsField( + (249, 135, 53, 1.0), title="Arnold StandIn:") + camera: ColorRGBA_uint8 = SettingsField( + (136, 114, 244, 1.0), title="Camera:") + fbx: ColorRGBA_uint8 = SettingsField( + (215, 166, 255, 1.0), title="FBX:") + mayaAscii: ColorRGBA_uint8 = SettingsField( + (67, 174, 255, 1.0), title="Maya Ascii:") + mayaScene: ColorRGBA_uint8 = SettingsField( + (67, 174, 255, 1.0), title="Maya Scene:") + setdress: ColorRGBA_uint8 = SettingsField( + (255, 250, 90, 1.0), title="Set Dress:") + layout: ColorRGBA_uint8 = SettingsField(( + 255, 250, 90, 1.0), title="Layout:") + vdbcache: ColorRGBA_uint8 = SettingsField( + (249, 54, 0, 1.0), title="VDB Cache:") + vrayproxy: ColorRGBA_uint8 = SettingsField( + (255, 150, 12, 1.0), title="VRay Proxy:") + vrayscene_layer: ColorRGBA_uint8 = SettingsField( + (255, 150, 12, 1.0), title="VRay Scene:") + yeticache: ColorRGBA_uint8 = SettingsField( + (99, 206, 220, 1.0), title="Yeti Cache:") + yetiRig: ColorRGBA_uint8 = SettingsField( + (0, 205, 125, 1.0), title="Yeti Rig:") + # model: ColorRGB_float = SettingsField( + # (0.82, 0.52, 0.12), title="Model:" + # ) + # rig: ColorRGB_float = SettingsField( + # (0.23, 0.89, 0.92), title="Rig:" + # ) + # pointcache: ColorRGB_float = SettingsField( + # (0.37, 0.82, 0.12), title="Pointcache:" + # ) + # animation: ColorRGB_float = SettingsField( + # (0.37, 0.82, 0.12), title="Animation:" + # ) + # ass: ColorRGB_float = SettingsField( + # (0.98, 0.53, 0.21), title="Arnold StandIn:" + # ) + # camera: ColorRGB_float = SettingsField( + # (0.53, 0.45, 0.96), title="Camera:" + # ) + # fbx: ColorRGB_float = SettingsField( + # (0.84, 0.65, 1.0), title="FBX:" + # ) + # mayaAscii: ColorRGB_float = SettingsField( + # (0.26, 0.68, 1.0), title="Maya Ascii:" + # ) + # mayaScene: ColorRGB_float = SettingsField( + # (0.26, 0.68, 1.0), title="Maya Scene:" + # ) + # setdress: ColorRGB_float = SettingsField( + # (1.0, 0.98, 0.35), title="Set Dress:" + # ) + # layout: ColorRGB_float = SettingsField( + # (1.0, 0.98, 0.35), title="Layout:" + # ) + # vdbcache: ColorRGB_float = SettingsField( + # (0.98, 0.21, 0.0), title="VDB Cache:" + # ) + # vrayproxy: ColorRGB_float = SettingsField( + # (1.0, 0.59, 0.05), title="VRay Proxy:" + # ) + # vrayscene_layer: ColorRGB_float = SettingsField( + # (1.0, 0.59, 0.05), title="VRay Scene:" + # ) + # yeticache: ColorRGB_float = SettingsField( + # (0.39, 0.81, 0.86), title="Yeti Cache:" + # ) + # yetiRig: ColorRGB_float = SettingsField( + # (0.0, 0.80, 0.49), title="Yeti Rig:" + # ) class ReferenceLoaderModel(BaseSettingsModel): @@ -99,22 +115,38 @@ class LoadersModel(BaseSettingsModel): DEFAULT_LOADERS_SETTING = { "colors": { - "model": [0.82, 0.52, 0.12], - "rig": [0.23, 0.89, 0.92], - "pointcache": [0.37, 0.82, 0.12], - "animation": [0.37, 0.82, 0.12], - "ass": [0.98, 0.53, 0.21], - "camera":[0.53, 0.45, 0.96], - "fbx": [0.84, 0.65, 1.0], - "mayaAscii": [0.26, 0.68, 1.0], - "mayaScene": [0.26, 0.68, 1.0], - "setdress": [1.0, 0.98, 0.35], - "layout": [1.0, 0.98, 0.35], - "vdbcache": [0.98, 0.21, 0.0], - "vrayproxy": [1.0, 0.59, 0.05], - "vrayscene_layer": [1.0, 0.59, 0.05], - "yeticache": [0.39, 0.81, 0.86], - "yetiRig": [0.0, 0.80, 0.49], + "model": [209, 132, 30, 1.0], + "rig": [59, 226, 235, 1.0], + "pointcache": [94, 209, 30, 1.0], + "animation": [94, 209, 30, 1.0], + "ass": [249, 135, 53, 1.0], + "camera": [136, 114, 244, 1.0], + "fbx": [215, 166, 255, 1.0], + "mayaAscii": [67, 174, 255, 1.0], + "mayaScene": [67, 174, 255, 1.0], + "setdress": [255, 250, 90, 1.0], + "layout": [255, 250, 90, 1.0], + "vdbcache": [249, 54, 0, 1.0], + "vrayproxy": [255, 150, 12, 1.0], + "vrayscene_layer": [255, 150, 12, 1.0], + "yeticache": [99, 206, 220, 1.0], + "yetiRig": [0, 205, 125, 1.0] + # "model": [0.82, 0.52, 0.12], + # "rig": [0.23, 0.89, 0.92], + # "pointcache": [0.37, 0.82, 0.12], + # "animation": [0.37, 0.82, 0.12], + # "ass": [0.98, 0.53, 0.21], + # "camera":[0.53, 0.45, 0.96], + # "fbx": [0.84, 0.65, 1.0], + # "mayaAscii": [0.26, 0.68, 1.0], + # "mayaScene": [0.26, 0.68, 1.0], + # "setdress": [1.0, 0.98, 0.35], + # "layout": [1.0, 0.98, 0.35], + # "vdbcache": [0.98, 0.21, 0.0], + # "vrayproxy": [1.0, 0.59, 0.05], + # "vrayscene_layer": [1.0, 0.59, 0.05], + # "yeticache": [0.39, 0.81, 0.86], + # "yetiRig": [0.0, 0.80, 0.49], }, "reference_loader": { "namespace": "{folder[name]}_{product[name]}_##_", diff --git a/server_addon/maya/server/settings/publish_playblast.py b/server_addon/maya/server/settings/publish_playblast.py index dcedf3ccc9..39f48bacbe 100644 --- a/server_addon/maya/server/settings/publish_playblast.py +++ b/server_addon/maya/server/settings/publish_playblast.py @@ -6,7 +6,7 @@ from ayon_server.settings import ( ensure_unique_names, task_types_enum, ) -from ayon_server.types import ColorRGB_float +from ayon_server.types import ColorRGBA_uint8, ColorRGB_float def hardware_falloff_enum(): @@ -54,18 +54,27 @@ class DisplayOptionsSetting(BaseSettingsModel): override_display: bool = SettingsField( True, title="Override display options" ) - background: ColorRGB_float = SettingsField( - (0.5, 0.5, 0.5), title="Background Color" + background: ColorRGBA_uint8 = SettingsField( + (125, 125, 125, 1.0), title="Background Color" ) + # background: ColorRGB_float = SettingsField( + # (0.5, 0.5, 0.5), title="Background Color" + # ) displayGradient: bool = SettingsField( True, title="Display background gradient" ) - backgroundTop: ColorRGB_float = SettingsField( - (0.5, 0.5, 0.5), title="Background Top" + backgroundTop: ColorRGBA_uint8 = SettingsField( + (125, 125, 125, 1.0), title="Background Top" ) - backgroundBottom: ColorRGB_float = SettingsField( - (0.5, 0.5, 0.5), title="Background Bottom" + backgroundBottom: ColorRGBA_uint8 = SettingsField( + (125, 125, 125, 1.0), title="Background Bottom" ) + # backgroundTop: ColorRGB_float = SettingsField( + # (0.5, 0.5, 0.5), title="Background Top" + # ) + # backgroundBottom: ColorRGB_float = SettingsField( + # (0.5, 0.5, 0.5), title="Background Bottom" + # ) class GenericSetting(BaseSettingsModel): @@ -282,21 +291,12 @@ DEFAULT_PLAYBLAST_SETTING = { }, "DisplayOptions": { "override_display": True, - "background": [ - 0.5, - 0.5, - 0.5 - ], - "backgroundBottom": [ - 0.5, - 0.5, - 0.5 - ], - "backgroundTop": [ - 0.5, - 0.5, - 0.5 - ], + "background": [125, 125, 125, 1.0], + "backgroundBottom": [125, 125, 125, 1.0], + "backgroundTop": [125, 125, 125, 1.0], + # "background": [0.5, 0.5, 0.5], + # "backgroundBottom": [0.5, 0.5, 0.5], + # "backgroundTop": [0.5, 0.5, 0.5], "displayGradient": True }, "Generic": { diff --git a/server_addon/tvpaint/server/settings/publish_plugins.py b/server_addon/tvpaint/server/settings/publish_plugins.py index 37ad3e0e70..0d978e5714 100644 --- a/server_addon/tvpaint/server/settings/publish_plugins.py +++ b/server_addon/tvpaint/server/settings/publish_plugins.py @@ -1,5 +1,5 @@ from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ColorRGB_uint8 +from ayon_server.types import ColorRGBA_uint8, ColorRGB_uint8 class CollectRenderInstancesModel(BaseSettingsModel): @@ -10,10 +10,12 @@ class CollectRenderInstancesModel(BaseSettingsModel): class ExtractSequenceModel(BaseSettingsModel): """Review BG color is used for whole scene review and for thumbnails.""" - # TODO Use alpha color - review_bg: ColorRGB_uint8 = SettingsField( - (255, 255, 255), + review_bg: ColorRGBA_uint8 = SettingsField( + (255, 255, 255, 1.0), title="Review BG color") + # review_bg: ColorRGB_uint8 = SettingsField( + # (255, 255, 255), + # title="Review BG color") class ValidatePluginModel(BaseSettingsModel): @@ -100,7 +102,8 @@ DEFAULT_PUBLISH_SETTINGS = { "ignore_render_pass_transparency": False }, "ExtractSequence": { - "review_bg": [255, 255, 255] + # "review_bg": [255, 255, 255] + "review_bg": [255, 255, 255, 1.0] }, "ValidateProjectSettings": { "enabled": True, From a811ef9a0ce9c79b99a1a41bd9f5730d35e4a93c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Feb 2024 17:58:05 +0800 Subject: [PATCH 071/149] remove unrelated code --- client/ayon_core/hosts/max/api/pipeline.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index 106c29fd26..c26e697429 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -242,20 +242,3 @@ def get_previous_loaded_object(container: str): if str(obj) in sel_list: node_list.append(obj) return node_list - - -def remove_container_data(container: str): - """Function to remove container data after updating, switching or deleting it. - - Args: - container (str): container - """ - if container.modifiers[0].name == "OP Data": - all_set_members_names = [ - member.node for member - in container.modifiers[0].openPypeData.all_handles] - for current_set_member in all_set_members_names: - rt.Delete(current_set_member) - rt.deleteModifier(container, container.modifiers[0]) - - rt.Delete(container) From 87df73da2242ac3ba32378f681d979ab6a011ed2 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Feb 2024 18:12:32 +0800 Subject: [PATCH 072/149] restored unrelated code --- client/ayon_core/hosts/max/api/pipeline.py | 17 ----------------- .../hosts/max/plugins/load/load_camera_fbx.py | 8 ++++---- .../hosts/max/plugins/load/load_max_scene.py | 9 ++++----- .../hosts/max/plugins/load/load_model.py | 8 +++----- .../hosts/max/plugins/load/load_model_fbx.py | 9 ++++----- .../hosts/max/plugins/load/load_model_obj.py | 6 +++--- .../hosts/max/plugins/load/load_model_usd.py | 5 ++--- .../hosts/max/plugins/load/load_pointcache.py | 5 ++--- .../plugins/load/load_pointcache_ornatrix.py | 5 ++--- .../hosts/max/plugins/load/load_pointcloud.py | 6 +++--- .../max/plugins/load/load_redshift_proxy.py | 6 +++--- .../hosts/max/plugins/load/load_tycache.py | 9 +++++---- 12 files changed, 35 insertions(+), 58 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index 106c29fd26..c26e697429 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -242,20 +242,3 @@ def get_previous_loaded_object(container: str): if str(obj) in sel_list: node_list.append(obj) return node_list - - -def remove_container_data(container: str): - """Function to remove container data after updating, switching or deleting it. - - Args: - container (str): container - """ - if container.modifiers[0].name == "OP Data": - all_set_members_names = [ - member.node for member - in container.modifiers[0].openPypeData.all_handles] - for current_set_member in all_set_members_names: - rt.Delete(current_set_member) - rt.deleteModifier(container, container.modifiers[0]) - - rt.Delete(container) diff --git a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py index d7eebdbc3a..34b120c179 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py @@ -1,6 +1,6 @@ import os -from ayon_core.hosts.max.api import lib +from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import ( unique_namespace, get_namespace, @@ -9,8 +9,7 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -95,5 +94,6 @@ class FbxLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py index 81f3af089f..7267d7a59e 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py +++ b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py @@ -7,10 +7,8 @@ from ayon_core.hosts.max.api.lib import ( object_transform_set ) from ayon_core.hosts.max.api.pipeline import ( - containerise, - get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + containerise, get_previous_loaded_object, + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -95,5 +93,6 @@ class MaxSceneLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model.py b/client/ayon_core/hosts/max/plugins/load/load_model.py index 28ec7be01f..796e1b80ad 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model.py @@ -2,13 +2,11 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object, - remove_container_data + get_previous_loaded_object ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( - maintained_selection, - unique_namespace + maintained_selection, unique_namespace ) @@ -101,7 +99,7 @@ class ModelAbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py index 81ad84546a..827cf63b39 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py @@ -1,10 +1,8 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( - containerise, - get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + containerise, get_previous_loaded_object, + update_custom_attribute_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -94,5 +92,6 @@ class FbxModelLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py index 1023b67f0c..22d3d4b58a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py @@ -11,8 +11,7 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -85,5 +84,6 @@ class ObjLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py index 6a08bebf5a..8d42219217 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py @@ -13,8 +13,7 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -115,4 +114,4 @@ class ModelUSDLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py index d7267afb7d..a92fa66757 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py @@ -10,8 +10,7 @@ from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import unique_namespace from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object, - remove_container_data + get_previous_loaded_object ) @@ -106,7 +105,7 @@ class AbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py index 5b48e5d189..27b2e271d2 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py @@ -4,8 +4,7 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.hosts.max.api.lib import ( @@ -106,4 +105,4 @@ class OxAbcLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) \ No newline at end of file + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py index 7f4fba50b3..45e3da5621 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py @@ -8,8 +8,7 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -64,5 +63,6 @@ class PointCloudLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py index 3ccc5cc5e1..3f73210c24 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py @@ -9,8 +9,7 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, update_custom_attribute_data, - get_previous_loaded_object, - remove_container_data + get_previous_loaded_object ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -73,5 +72,6 @@ class RedshiftProxyLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.getNodeByName(container["instance_node"]) - remove_container_data(node) + rt.delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_tycache.py b/client/ayon_core/hosts/max/plugins/load/load_tycache.py index 97f41026b4..48fb5c447a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_tycache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_tycache.py @@ -1,13 +1,13 @@ import os from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import ( - unique_namespace + unique_namespace, + ) from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -59,5 +59,6 @@ class TyCacheLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) From 3c726393fc64789ea4988009fda701d6e0969eb8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 14:27:48 +0100 Subject: [PATCH 073/149] bump version to 0.2.1 --- client/ayon_core/version.py | 2 +- package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/version.py b/client/ayon_core/version.py index 914e415b8c..46dc6c6876 100644 --- a/client/ayon_core/version.py +++ b/client/ayon_core/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON core addon version.""" -__version__ = "0.2.1-dev.1" +__version__ = "0.2.1" diff --git a/package.py b/package.py index 3b451e0078..5a1376c209 100644 --- a/package.py +++ b/package.py @@ -1,6 +1,6 @@ name = "core" title = "Core" -version = "0.2.1-dev.1" +version = "0.2.1" client_dir = "ayon_core" From 6baba8633f80698639ee0fa8e0493924830e8d3a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 14:33:59 +0100 Subject: [PATCH 074/149] bump version to '0.3.0-dev.1' --- client/ayon_core/version.py | 2 +- package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/version.py b/client/ayon_core/version.py index 46dc6c6876..f3ad9713d5 100644 --- a/client/ayon_core/version.py +++ b/client/ayon_core/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON core addon version.""" -__version__ = "0.2.1" +__version__ = "0.3.0-dev.1" diff --git a/package.py b/package.py index 5a1376c209..470bbf256b 100644 --- a/package.py +++ b/package.py @@ -1,6 +1,6 @@ name = "core" title = "Core" -version = "0.2.1" +version = "0.3.0-dev.1" client_dir = "ayon_core" From 32094aa148629f98799992302cf06de43f4c2d91 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:15:28 +0100 Subject: [PATCH 075/149] fix missing import in maya addon --- server_addon/maya/server/settings/loaders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/maya/server/settings/loaders.py b/server_addon/maya/server/settings/loaders.py index 3e8d368a6b..418a7046ae 100644 --- a/server_addon/maya/server/settings/loaders.py +++ b/server_addon/maya/server/settings/loaders.py @@ -1,5 +1,5 @@ from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ColorRGB_float +from ayon_server.types import ColorRGB_float, ColorRGBA_uint8 class ColorsSetting(BaseSettingsModel): From 33d6f54c2d0d169f0820a8340673622c5e052258 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:24:55 +0100 Subject: [PATCH 076/149] ExtractBurnin are using AYON settings --- .../plugins/publish/extract_burnin.py | 89 +++++++++++-------- client/ayon_core/settings/ayon_settings.py | 40 --------- 2 files changed, 51 insertions(+), 78 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 2b76527d5f..4da158343e 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -65,8 +65,8 @@ class ExtractBurnin(publish.Extractor): # Default options for burnins for cases that are not set in presets. default_options = { "font_size": 42, - "font_color": [255, 255, 255, 255], - "bg_color": [0, 0, 0, 127], + "font_color": [255, 255, 255, 1.0], + "bg_color": [0, 0, 0, 0.5], "bg_padding": 5, "x_offset": 5, "y_offset": 5 @@ -96,7 +96,9 @@ class ExtractBurnin(publish.Extractor): instance.data["representations"].remove(repre) def _get_burnins_per_representations(self, instance, src_burnin_defs): - self.log.debug("Filtering of representations and their burnins starts") + self.log.debug( + "Filtering of representations and their burnins starts" + ) filtered_repres = [] repres = instance.data.get("representations") or [] @@ -116,11 +118,11 @@ class ExtractBurnin(publish.Extractor): ) # Filter output definition by `burnin` represetation key - repre_linked_burnins = { - name: output - for name, output in burnin_defs.items() - if name in repre_burnin_links - } + repre_linked_burnins = [ + burnin_def + for burnin_def in burnin_defs.items() + if burnin_def["name"] in repre_burnin_links + ] self.log.debug( "repre_linked_burnins: {}".format(repre_linked_burnins) ) @@ -154,19 +156,21 @@ class ExtractBurnin(publish.Extractor): filtering_criteria = { "hosts": host_name, - "families": family, + "product_types": family, + "product_names": subset, "task_names": task_name, "task_types": task_type, - "subset": subset } - profile = filter_profiles(self.profiles, filtering_criteria, - logger=self.log) - + profile = filter_profiles( + self.profiles, + filtering_criteria, + logger=self.log + ) if not profile: self.log.debug(( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" - " | Task type \"{}\" | Subset \"{}\" " + " Host: \"{}\" | Product type: \"{}\" | Task name \"{}\"" + " | Task type \"{}\" | Product name \"{}\" " ).format(host_name, family, task_name, task_type, subset)) return @@ -175,7 +179,7 @@ class ExtractBurnin(publish.Extractor): if not burnin_defs: self.log.debug(( "Skipped instance. Burnin definitions are not set for profile" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" + " Host: \"{}\" | Product type: \"{}\" | Task name \"{}\"" " | Profile \"{}\"" ).format(host_name, family, task_name, profile)) return @@ -275,7 +279,8 @@ class ExtractBurnin(publish.Extractor): # it in review? # burnin_data["fps"] = fps - for filename_suffix, burnin_def in repre_burnin_defs.items(): + for burnin_def in repre_burnin_defs: + filename_suffix = burnin_def["name"] new_repre = copy.deepcopy(repre) new_repre["stagingDir"] = src_repre_staging_dir @@ -288,16 +293,28 @@ class ExtractBurnin(publish.Extractor): burnin_values = {} for key in self.positions: value = burnin_def.get(key) - if value: - burnin_values[key] = value.replace( - "{task}", "{task[name]}" - ) + if not value: + continue + # TODO remove replacements + burnin_values[key] = ( + value + .replace("{task}", "{task[name]}") + .replace("{product[name]}", "{subset}") + .replace("{Product[name]}", "{Subset}") + .replace("{PRODUCT[NAME]}", "{SUBSET}") + .replace("{product[type]}", "{family}") + .replace("{Product[type]}", "{Family}") + .replace("{PRODUCT[TYPE]}", "{FAMILY}") + .replace("{folder[name]}", "{asset}") + .replace("{Folder[name]}", "{Asset}") + .replace("{FOLDER[NAME]}", "{ASSET}") + ) # Remove "delete" tag from new representation if "delete" in new_repre["tags"]: new_repre["tags"].remove("delete") - if len(repre_burnin_defs.keys()) > 1: + if len(repre_burnin_defs) > 1: # Update name and outputName to be # able have multiple outputs in case of more burnin presets # Join previous "outputName" with filename suffix @@ -401,8 +418,7 @@ class ExtractBurnin(publish.Extractor): bg_color_hex = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( bg_red, bg_green, bg_blue ) - bg_color_alpha = float(bg_alpha) / 255 - burnin_options["bg_opacity"] = bg_color_alpha + burnin_options["bg_opacity"] = bg_alpha burnin_options["bg_color"] = bg_color_hex # FG Color @@ -412,8 +428,7 @@ class ExtractBurnin(publish.Extractor): fg_color_hex = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( fg_red, fg_green, fg_blue ) - fg_color_alpha = float(fg_alpha) / 255 - burnin_options["opacity"] = fg_color_alpha + burnin_options["opacity"] = fg_alpha burnin_options["font_color"] = fg_color_hex # Define font filepath @@ -543,15 +558,16 @@ class ExtractBurnin(publish.Extractor): Burnin definitions without tags filter are marked as valid. Args: - outputs (list): Contain list of burnin definitions from presets. + burnin_defs (list): Burnin definitions. tags (list): Tags of processed representation. Returns: list: Containg all burnin definitions matching entered tags. + """ - filtered_burnins = {} + filtered_burnins = [] repre_tags_low = set(tag.lower() for tag in tags) - for filename_suffix, burnin_def in burnin_defs.items(): + for burnin_def in burnin_defs: valid = True tag_filters = burnin_def["filter"]["tags"] if tag_filters: @@ -561,8 +577,7 @@ class ExtractBurnin(publish.Extractor): valid = bool(repre_tags_low & tag_filters_low) if valid: - filtered_burnins[filename_suffix] = burnin_def - + filtered_burnins.append(burnin_def) return filtered_burnins def input_output_paths( @@ -724,7 +739,7 @@ class ExtractBurnin(publish.Extractor): Returns: list: Containg all valid output definitions. """ - filtered_burnin_defs = {} + filtered_burnin_defs = [] burnin_defs = profile.get("burnins") if not burnin_defs: @@ -732,13 +747,11 @@ class ExtractBurnin(publish.Extractor): families = self.families_from_instance(instance) - for filename_suffix, orig_burnin_def in burnin_defs.items(): + for orig_burnin_def in burnin_defs: burnin_def = copy.deepcopy(orig_burnin_def) - def_filter = burnin_def.get("filter", None) or {} - for key in ("families", "tags"): - if key not in def_filter: - def_filter[key] = [] + filename_suffix = burnin_def["name"] + def_filter = burnin_def["filter"] families_filters = def_filter["families"] if not self.families_filter_validation( families, families_filters @@ -769,7 +782,7 @@ class ExtractBurnin(publish.Extractor): burnin_values["filter"] = def_filter - filtered_burnin_defs[filename_suffix] = burnin_values + filtered_burnin_defs.append(burnin_values) self.log.debug(( "Burnin definition \"{}\" passed first filtering." diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 190970b908..f74e6129db 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -449,46 +449,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): new_outputs[name] = profile_output profile["outputs"] = new_outputs - # Extract Burnin plugin - extract_burnin = ayon_publish["ExtractBurnin"] - extract_burnin_options = extract_burnin["options"] - for color_key in ("font_color", "bg_color"): - extract_burnin_options[color_key] = _convert_color( - extract_burnin_options[color_key] - ) - - for profile in extract_burnin["profiles"]: - extract_burnin_defs = profile["burnins"] - if "product_names" in profile: - profile["subsets"] = profile.pop("product_names") - profile["families"] = profile.pop("product_types") - - for burnin_def in extract_burnin_defs: - for key in ( - "TOP_LEFT", - "TOP_CENTERED", - "TOP_RIGHT", - "BOTTOM_LEFT", - "BOTTOM_CENTERED", - "BOTTOM_RIGHT", - ): - burnin_def[key] = ( - burnin_def[key] - .replace("{product[name]}", "{subset}") - .replace("{Product[name]}", "{Subset}") - .replace("{PRODUCT[NAME]}", "{SUBSET}") - .replace("{product[type]}", "{family}") - .replace("{Product[type]}", "{Family}") - .replace("{PRODUCT[TYPE]}", "{FAMILY}") - .replace("{folder[name]}", "{asset}") - .replace("{Folder[name]}", "{Asset}") - .replace("{FOLDER[NAME]}", "{ASSET}") - ) - profile["burnins"] = { - extract_burnin_def.pop("name"): extract_burnin_def - for extract_burnin_def in extract_burnin_defs - } - if "IntegrateProductGroup" in ayon_publish: subset_group = ayon_publish.pop("IntegrateProductGroup") subset_group_profiles = subset_group.pop("product_grouping_profiles") From 7669e8ff2b3b17fef8498afc47925ff5a33893d4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:30:37 +0100 Subject: [PATCH 077/149] 'ExtractOIIOTranscode is using AYON settings --- .../publish/extract_color_transcode.py | 12 ++++++---- client/ayon_core/settings/ayon_settings.py | 23 ------------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_color_transcode.py b/client/ayon_core/plugins/publish/extract_color_transcode.py index 66ba8ad2be..77c4673bca 100644 --- a/client/ayon_core/plugins/publish/extract_color_transcode.py +++ b/client/ayon_core/plugins/publish/extract_color_transcode.py @@ -81,6 +81,7 @@ class ExtractOIIOTranscode(publish.Extractor): if not profile: return + profile_output_defs = profile["outputs"] new_representations = [] repres = instance.data["representations"] for idx, repre in enumerate(list(repres)): @@ -98,7 +99,8 @@ class ExtractOIIOTranscode(publish.Extractor): self.log.warning("Config file doesn't exist, skipping") continue - for output_name, output_def in profile.get("outputs", {}).items(): + for output_def in profile_output_defs: + output_name = output_def["name"] new_repre = copy.deepcopy(repre) original_staging_dir = new_repre["stagingDir"] @@ -318,10 +320,10 @@ class ExtractOIIOTranscode(publish.Extractor): subset = instance.data["subset"] filtering_criteria = { "hosts": host_name, - "families": family, + "product_types": family, + "product_names": subset, "task_names": task_name, "task_types": task_type, - "subsets": subset } profile = filter_profiles(self.profiles, filtering_criteria, logger=self.log) @@ -329,8 +331,8 @@ class ExtractOIIOTranscode(publish.Extractor): if not profile: self.log.debug(( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" - " | Task type \"{}\" | Subset \"{}\" " + " Host: \"{}\" | Product types: \"{}\" | Task \"{}\"" + " | Task type \"{}\" | Product names: \"{}\" " ).format(host_name, family, task_name, task_type, subset)) return profile diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index f74e6129db..81a0fde844 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -426,29 +426,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_extract_thumbnail["background_color"] ) - # ExtractOIIOTranscode plugin - extract_oiio_transcode = ayon_publish["ExtractOIIOTranscode"] - extract_oiio_transcode_profiles = extract_oiio_transcode["profiles"] - for profile in extract_oiio_transcode_profiles: - new_outputs = {} - name_counter = {} - if "product_names" in profile: - profile["subsets"] = profile.pop("product_names") - for profile_output in profile["outputs"]: - if "name" in profile_output: - name = profile_output.pop("name") - else: - # Backwards compatibility for setting without 'name' in model - name = profile_output["extension"] - if name in new_outputs: - name_counter[name] += 1 - name = "{}_{}".format(name, name_counter[name]) - else: - name_counter[name] = 0 - - new_outputs[name] = profile_output - profile["outputs"] = new_outputs - if "IntegrateProductGroup" in ayon_publish: subset_group = ayon_publish.pop("IntegrateProductGroup") subset_group_profiles = subset_group.pop("product_grouping_profiles") From 266eb53769e7fbc5ac54661652e3676777f80a86 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:32:45 +0100 Subject: [PATCH 078/149] IntegrateProductGroup is using AYON settings --- ...ubset_group.py => integrate_product_group.py} | 16 ++++++++-------- client/ayon_core/settings/ayon_settings.py | 8 -------- 2 files changed, 8 insertions(+), 16 deletions(-) rename client/ayon_core/plugins/publish/{integrate_subset_group.py => integrate_product_group.py} (87%) diff --git a/client/ayon_core/plugins/publish/integrate_subset_group.py b/client/ayon_core/plugins/publish/integrate_product_group.py similarity index 87% rename from client/ayon_core/plugins/publish/integrate_subset_group.py rename to client/ayon_core/plugins/publish/integrate_product_group.py index c2f1eac9e3..f7c96893ca 100644 --- a/client/ayon_core/plugins/publish/integrate_subset_group.py +++ b/client/ayon_core/plugins/publish/integrate_product_group.py @@ -17,24 +17,24 @@ from ayon_core.lib import ( ) -class IntegrateSubsetGroup(pyblish.api.InstancePlugin): +class IntegrateProductGroup(pyblish.api.InstancePlugin): """Integrate Subset Group for publish.""" # Run after CollectAnatomyInstanceData order = pyblish.api.IntegratorOrder - 0.1 - label = "Subset Group" + label = "Product Group" # Attributes set by settings - subset_grouping_profiles = None + product_grouping_profiles = None def process(self, instance): """Look into subset group profiles set by settings. - Attribute 'subset_grouping_profiles' is defined by settings. + Attribute 'product_grouping_profiles' is defined by settings. """ - # Skip if 'subset_grouping_profiles' is empty - if not self.subset_grouping_profiles: + # Skip if 'product_grouping_profiles' is empty + if not self.product_grouping_profiles: return if instance.data.get("subsetGroup"): @@ -47,7 +47,7 @@ class IntegrateSubsetGroup(pyblish.api.InstancePlugin): # Skip if there is no matching profile filter_criteria = self.get_profile_filter_criteria(instance) profile = filter_profiles( - self.subset_grouping_profiles, + self.product_grouping_profiles, filter_criteria, logger=self.log ) @@ -91,7 +91,7 @@ class IntegrateSubsetGroup(pyblish.api.InstancePlugin): # Return filter criteria return { - "families": anatomy_data["family"], + "product_types": anatomy_data["family"], "tasks": task.get("name"), "hosts": instance.context.data["hostName"], "task_types": task.get("type") diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 81a0fde844..9c8deecab0 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -426,14 +426,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_extract_thumbnail["background_color"] ) - if "IntegrateProductGroup" in ayon_publish: - subset_group = ayon_publish.pop("IntegrateProductGroup") - subset_group_profiles = subset_group.pop("product_grouping_profiles") - for profile in subset_group_profiles: - profile["families"] = profile.pop("product_types") - subset_group["subset_grouping_profiles"] = subset_group_profiles - ayon_publish["IntegrateSubsetGroup"] = subset_group - # Cleanup plugin ayon_cleanup = ayon_publish["CleanUp"] if "patterns" in ayon_cleanup: From 508997c7f472d7560ed74a08e8a469738eb3daed Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:38:32 +0100 Subject: [PATCH 079/149] get_subset_name is using AYON settings --- .../plugins/create/create_render.py | 6 ++--- .../photoshop/plugins/create/create_image.py | 4 ++-- .../ayon_core/pipeline/create/subset_name.py | 24 ++++++++++++++----- client/ayon_core/settings/ayon_settings.py | 19 --------------- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py b/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py index 78aa49a562..bd005f5d4f 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py +++ b/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py @@ -194,13 +194,13 @@ class RenderCreator(Creator): name into created subset name. Position of composition name could be set in - `project_settings/global/tools/creator/subset_name_profiles` with some - form of '{composition}' placeholder. + `project_settings/global/tools/creator/product_name_profiles` with + some form of '{composition}' placeholder. Composition name will be used implicitly if multiple composition should be handled at same time. - If {composition} placeholder is not us 'subset_name_profiles' + If {composition} placeholder is not us 'product_name_profiles' composition name will be capitalized and set at the end of subset name if necessary. diff --git a/client/ayon_core/hosts/photoshop/plugins/create/create_image.py b/client/ayon_core/hosts/photoshop/plugins/create/create_image.py index a28872bba1..2ef746fc94 100644 --- a/client/ayon_core/hosts/photoshop/plugins/create/create_image.py +++ b/client/ayon_core/hosts/photoshop/plugins/create/create_image.py @@ -209,8 +209,8 @@ class ImageCreator(Creator): 'Use layer name in subset' will explicitly add layer name into subset name. Position of this name is configurable in - `project_settings/global/tools/creator/subset_name_profiles`. - If layer placeholder ({layer}) is not used in `subset_name_profiles` + `project_settings/global/tools/creator/product_name_profiles`. + If layer placeholder ({layer}) is not used in `product_name_profiles` but layer name should be used (set explicitly in UI or implicitly if multiple images should be created), it is added in capitalized form as a suffix to subset name. diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 93a61b8b8b..81967ffd99 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -48,9 +48,9 @@ def get_subset_name_template( if project_settings is None: project_settings = get_project_settings(project_name) tools_settings = project_settings["global"]["tools"] - profiles = tools_settings["creator"]["subset_name_profiles"] + profiles = tools_settings["creator"]["product_name_profiles"] filtering_criteria = { - "families": family, + "product_types": family, "hosts": host_name, "tasks": task_name, "task_types": task_type @@ -59,7 +59,19 @@ def get_subset_name_template( matching_profile = filter_profiles(profiles, filtering_criteria) template = None if matching_profile: - template = matching_profile["template"] + # TODO remove formatting keys replacement + template = ( + matching_profile["template"] + .replace("{task[name]}", "{task}") + .replace("{Task[name]}", "{Task}") + .replace("{TASK[NAME]}", "{TASK}") + .replace("{product[type]}", "{family}") + .replace("{Product[type]}", "{Family}") + .replace("{PRODUCT[TYPE]}", "{FAMILY}") + .replace("{folder[name]}", "{asset}") + .replace("{Folder[name]}", "{Asset}") + .replace("{FOLDER[NAME]}", "{ASSET}") + ) # Make sure template is set (matching may have empty string) if not template: @@ -82,9 +94,9 @@ def get_subset_name( """Calculate subset name based on passed context and OpenPype settings. Subst name templates are defined in `project_settings/global/tools/creator - /subset_name_profiles` where are profiles with host name, family, task name - and task type filters. If context does not match any profile then - `DEFAULT_SUBSET_TEMPLATE` is used as default template. + /product_name_profiles` where are profiles with host name, family, + task name and task type filters. If context does not match any profile + then `DEFAULT_SUBSET_TEMPLATE` is used as default template. That's main reason why so many arguments are required to calculate subset name. diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 9c8deecab0..43bf8ca471 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -442,26 +442,7 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Tools settings ayon_tools = ayon_core["tools"] ayon_create_tool = ayon_tools["creator"] - if "product_name_profiles" in ayon_create_tool: - product_name_profiles = ayon_create_tool.pop("product_name_profiles") - for profile in product_name_profiles: - profile["families"] = profile.pop("product_types") - ayon_create_tool["subset_name_profiles"] = product_name_profiles - for profile in ayon_create_tool["subset_name_profiles"]: - template = profile["template"] - profile["template"] = ( - template - .replace("{task[name]}", "{task}") - .replace("{Task[name]}", "{Task}") - .replace("{TASK[NAME]}", "{TASK}") - .replace("{product[type]}", "{family}") - .replace("{Product[type]}", "{Family}") - .replace("{PRODUCT[TYPE]}", "{FAMILY}") - .replace("{folder[name]}", "{asset}") - .replace("{Folder[name]}", "{Asset}") - .replace("{FOLDER[NAME]}", "{ASSET}") - ) product_smart_select_key = "families_smart_select" if "product_types_smart_select" in ayon_create_tool: From 7beef914f768010e8f00e1e94ccede97add31d1f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:39:00 +0100 Subject: [PATCH 080/149] smart family select is using AYON settings --- client/ayon_core/settings/ayon_settings.py | 8 -------- client/ayon_core/tools/creator/window.py | 12 +++++++----- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 43bf8ca471..8943debba5 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -444,15 +444,7 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_create_tool = ayon_tools["creator"] - product_smart_select_key = "families_smart_select" - if "product_types_smart_select" in ayon_create_tool: - product_smart_select_key = "product_types_smart_select" - new_smart_select_families = { - item["name"]: item["task_names"] - for item in ayon_create_tool.pop(product_smart_select_key) - } - ayon_create_tool["families_smart_select"] = new_smart_select_families ayon_loader_tool = ayon_tools["loader"] if "product_type_filter_profiles" in ayon_loader_tool: diff --git a/client/ayon_core/tools/creator/window.py b/client/ayon_core/tools/creator/window.py index 676e1c3959..5862725076 100644 --- a/client/ayon_core/tools/creator/window.py +++ b/client/ayon_core/tools/creator/window.py @@ -377,23 +377,25 @@ class CreatorWindow(QtWidgets.QDialog): self._creators_model.reset() - pype_project_setting = ( + product_types_smart_select = ( get_current_project_settings() ["global"] ["tools"] ["creator"] - ["families_smart_select"] + ["product_types_smart_select"] ) current_index = None family = None task_name = get_current_task_name() or None lowered_task_name = task_name.lower() if task_name: - for _family, _task_names in pype_project_setting.items(): - _low_task_names = {name.lower() for name in _task_names} + for smart_item in product_types_smart_select: + _low_task_names = { + name.lower() for name in smart_item["task_names"] + } for _task_name in _low_task_names: if _task_name in lowered_task_name: - family = _family + family = smart_item["name"] break if family: break From eecabc7c89becb1f9c6f4ac6b0199aa0116373eb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:42:33 +0100 Subject: [PATCH 081/149] template name profiles are using AYON settings --- client/ayon_core/pipeline/publish/lib.py | 2 +- client/ayon_core/settings/ayon_settings.py | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index a62c2d9c5b..a14651551f 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -138,7 +138,7 @@ def get_publish_template_name( template = None filter_criteria = { "hosts": host_name, - "families": family, + "product_types": family, "task_names": task_name, "task_types": task_type, } diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 8943debba5..1c173e438f 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -456,15 +456,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_loader_tool["family_filter_profiles"] = ( product_type_filter_profiles) - ayon_publish_tool = ayon_tools["publish"] - for profile in ayon_publish_tool["hero_template_name_profiles"]: - if "product_types" in profile: - profile["families"] = profile.pop("product_types") - - for profile in ayon_publish_tool["template_name_profiles"]: - if "product_types" in profile: - profile["families"] = profile.pop("product_types") - ayon_core["sync_server"] = ( default_settings["global"]["sync_server"] ) From 698e60f2d57ddbbc6fc528d11931d6e5bdc281b3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:42:45 +0100 Subject: [PATCH 082/149] removed conversion of unused settings --- client/ayon_core/settings/ayon_settings.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 1c173e438f..3362fd2c3e 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -440,22 +440,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): )) # Tools settings - ayon_tools = ayon_core["tools"] - ayon_create_tool = ayon_tools["creator"] - - - - - ayon_loader_tool = ayon_tools["loader"] - if "product_type_filter_profiles" in ayon_loader_tool: - product_type_filter_profiles = ( - ayon_loader_tool.pop("product_type_filter_profiles")) - for profile in product_type_filter_profiles: - profile["filter_families"] = profile.pop("filter_product_types") - - ayon_loader_tool["family_filter_profiles"] = ( - product_type_filter_profiles) - ayon_core["sync_server"] = ( default_settings["global"]["sync_server"] ) From b390a7f3b5da5658d418d7642d3db7c6e8894146 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:44:11 +0100 Subject: [PATCH 083/149] CleanUp plugin is using AYON settings --- client/ayon_core/plugins/publish/cleanup.py | 20 ++++++++++---------- client/ayon_core/settings/ayon_settings.py | 5 ----- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/plugins/publish/cleanup.py b/client/ayon_core/plugins/publish/cleanup.py index df68af7e57..db73d28e7a 100644 --- a/client/ayon_core/plugins/publish/cleanup.py +++ b/client/ayon_core/plugins/publish/cleanup.py @@ -40,7 +40,7 @@ class CleanUp(pyblish.api.InstancePlugin): active = True # Presets - paterns = None # list of regex paterns + patterns = None # list of regex patterns remove_temp_renders = True def process(self, instance): @@ -115,10 +115,10 @@ class CleanUp(pyblish.api.InstancePlugin): src = os.path.normpath(src) dest = os.path.normpath(dest) - # add src dir into clearing dir paths (regex paterns) + # add src dir into clearing dir paths (regex patterns) transfers_dirs.append(os.path.dirname(src)) - # add dest dir into clearing dir paths (regex paterns) + # add dest dir into clearing dir paths (regex patterns) transfers_dirs.append(os.path.dirname(dest)) if src in skip_cleanup_filepaths: @@ -141,13 +141,13 @@ class CleanUp(pyblish.api.InstancePlugin): # add dir for cleanup dirnames.append(os.path.dirname(src)) - # clean by regex paterns + # clean by regex patterns # make unique set transfers_dirs = set(transfers_dirs) self.log.debug("__ transfers_dirs: `{}`".format(transfers_dirs)) - self.log.debug("__ self.paterns: `{}`".format(self.paterns)) - if self.paterns: + self.log.debug("__ self.patterns: `{}`".format(self.patterns)) + if self.patterns: files = list() # get list of all available content of dirs for _dir in transfers_dirs: @@ -159,14 +159,14 @@ class CleanUp(pyblish.api.InstancePlugin): self.log.debug("__ files: `{}`".format(files)) - # remove all files which match regex patern + # remove all files which match regex pattern for f in files: if os.path.normpath(f) in skip_cleanup_filepaths: continue - for p in self.paterns: - patern = re.compile(p) - if not patern.findall(f): + for p in self.patterns: + pattern = re.compile(p) + if not pattern.findall(f): continue if not os.path.exists(f): continue diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 3362fd2c3e..5c4813f3aa 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -426,11 +426,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_extract_thumbnail["background_color"] ) - # Cleanup plugin - ayon_cleanup = ayon_publish["CleanUp"] - if "patterns" in ayon_cleanup: - ayon_cleanup["paterns"] = ayon_cleanup.pop("patterns") - # Project root settings - json string to dict ayon_core["project_environments"] = json.loads( ayon_core["project_environments"] From 6566900f805f19825b000023c395b358625e55ab Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:09:17 +0100 Subject: [PATCH 084/149] fix addon name in package.py for royal render --- server_addon/create_ayon_addons.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index 5e06d8ee8a..9553980f5d 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -191,8 +191,11 @@ def create_addon_package( # Copy server content package_py = addon_output_dir / "package.py" + addon_name = addon_dir.name + if addon_name == "royal_render": + addon_name = "royalrender" package_py_content = PACKAGE_PY_TEMPLATE.format( - addon_name=addon_dir.name, addon_version=addon_version + addon_name=addon_name, addon_version=addon_version ) with open(package_py, "w+") as pkg_py: From 6499962cb42e868cb92d39cbe8862cff0c60cb60 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:21:50 +0100 Subject: [PATCH 085/149] implemented simple folders widget as possible replacement of AssetsWidget --- .../tools/ayon_utils/widgets/__init__.py | 2 + .../ayon_utils/widgets/folders_widget.py | 112 ++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/client/ayon_core/tools/ayon_utils/widgets/__init__.py b/client/ayon_core/tools/ayon_utils/widgets/__init__.py index f58de17c4a..b1b7dd7527 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/__init__.py +++ b/client/ayon_core/tools/ayon_utils/widgets/__init__.py @@ -9,6 +9,7 @@ from .folders_widget import ( FoldersWidget, FoldersQtModel, FOLDERS_MODEL_SENDER_NAME, + SimpleFoldersWidget, ) from .tasks_widget import ( @@ -31,6 +32,7 @@ __all__ = ( "FoldersWidget", "FoldersQtModel", "FOLDERS_MODEL_SENDER_NAME", + "SimpleFoldersWidget", "TasksWidget", "TasksQtModel", diff --git a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py index 1e395b0368..6ca5264a8d 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py +++ b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py @@ -2,6 +2,11 @@ import collections from qtpy import QtWidgets, QtGui, QtCore +from ayon_core.lib.events import QueuedEventSystem +from ayon_core.tools.ayon_utils.models import ( + HierarchyModel, + HierarchyExpectedSelection, +) from ayon_core.tools.utils import ( RecursiveSortFilterProxyModel, TreeView, @@ -514,3 +519,110 @@ class FoldersWidget(QtWidgets.QWidget): if folder_id is not None: self.set_selected_folder(folder_id) self._controller.expected_folder_selected(folder_id) + + +class SimpleSelectionModel(object): + """Model handling selection changes. + + Triggering events: + - "selection.project.changed" + - "selection.folder.changed" + """ + + event_source = "selection.model" + + def __init__(self, controller): + self._controller = controller + + self._project_name = None + self._folder_id = None + self._task_id = None + self._task_name = None + + def get_selected_project_name(self): + return self._project_name + + def set_selected_project(self, project_name): + self._project_name = project_name + self._controller.emit_event( + "selection.project.changed", + {"project_name": project_name}, + self.event_source + ) + + def get_selected_folder_id(self): + return self._folder_id + + def set_selected_folder(self, folder_id): + if folder_id == self._folder_id: + return + self._folder_id = folder_id + self._controller.emit_event( + "selection.folder.changed", + { + "project_name": self._project_name, + "folder_id": folder_id, + }, + self.event_source + ) + + +class SimpleFoldersController(object): + def __init__(self): + self._event_system = self._create_event_system() + self._hierarchy_model = HierarchyModel(self) + self._selection_model = SimpleSelectionModel(self) + self._expected_selection = HierarchyExpectedSelection( + self, handle_project=False, handle_folder=True, handle_task=False + ) + + def emit_event(self, topic, data=None, source=None): + """Use implemented event system to trigger event.""" + + if data is None: + data = {} + self._event_system.emit(topic, data, source) + + def register_event_callback(self, topic, callback): + self._event_system.add_callback(topic, callback) + + # Model functions + def get_folder_items(self, project_name, sender=None): + return self._hierarchy_model.get_folder_items(project_name, sender) + + def set_selected_project(self, project_name): + self._selection_model.set_selected_project(project_name) + + def set_selected_folder(self, folder_id): + self._selection_model.set_selected_folder(folder_id) + + def get_expected_selection_data(self): + self._expected_selection.get_expected_selection_data() + + def expected_folder_selected(self, folder_id): + self._expected_selection.expected_folder_selected(folder_id) + + def _create_event_system(self): + return QueuedEventSystem() + + +class SimpleFoldersWidget(FoldersWidget): + def __init__(self, controller=None, *args, **kwargs): + if controller is None: + controller = SimpleFoldersController() + super(SimpleFoldersWidget, self).__init__(controller, *args, **kwargs) + + def set_project_name(self, project_name): + self._controller.set_selected_project(project_name) + super(SimpleFoldersWidget, self).set_project_name(project_name) + + def _on_project_selection_change(self, event): + """Ignore project selection change from controller. + + Only who can trigger project change is this widget with + 'set_project_name' which already cares about project change. + + Args: + event (Event): Triggered event. + """ + pass From 4744ff329ed90d010400c6a3f1943e248e376eb8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:28:27 +0100 Subject: [PATCH 086/149] added 'get_selected_folder_path' --- .../tools/ayon_utils/widgets/folders_widget.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py index 6ca5264a8d..cf81d1c8ff 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py +++ b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py @@ -395,6 +395,15 @@ class FoldersWidget(QtWidgets.QWidget): return self._get_selected_item_id() + def get_selected_folder_path(self): + """Get selected folder id. + + Returns: + Union[str, None]: Folder path which is selected. + """ + + return self._get_selected_item_value(FOLDER_PATH_ROLE) + def get_selected_folder_label(self): """Selected folder label. @@ -478,9 +487,12 @@ class FoldersWidget(QtWidgets.QWidget): self.refreshed.emit() def _get_selected_item_id(self): + return self._get_selected_item_value(FOLDER_ID_ROLE) + + def _get_selected_item_value(self, role): selection_model = self._folders_view.selectionModel() for index in selection_model.selectedIndexes(): - item_id = index.data(FOLDER_ID_ROLE) + item_id = index.data(role) if item_id is not None: return item_id return None From 8331c90fcfe3e66dea703af0023ee0cefa81563b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:52:05 +0100 Subject: [PATCH 087/149] ExtractThumbnail uses AYON settings --- client/ayon_core/lib/transcoding.py | 9 +++-- .../plugins/publish/extract_thumbnail.py | 39 ++++++++++++------- client/ayon_core/settings/ayon_settings.py | 20 ---------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/client/ayon_core/lib/transcoding.py b/client/ayon_core/lib/transcoding.py index 6c6837dcf9..08e0bc9237 100644 --- a/client/ayon_core/lib/transcoding.py +++ b/client/ayon_core/lib/transcoding.py @@ -1385,23 +1385,26 @@ def _get_image_dimensions(application, input_path, log): def convert_color_values(application, color_value): """Get color mapping for ffmpeg and oiiotool. + Args: application (str): Application for which command should be created. - color_value (list[int]): List of 8bit int values for RGBA. + color_value (tuple[int, int, int, float]): List of 8bit int values + for RGBA. + Returns: str: ffmpeg returns hex string, oiiotool is string with floats. + """ red, green, blue, alpha = color_value if application == "ffmpeg": return "{0:0>2X}{1:0>2X}{2:0>2X}@{3}".format( - red, green, blue, (alpha / 255.0) + red, green, blue, alpha ) elif application == "oiiotool": red = float(red / 255) green = float(green / 255) blue = float(blue / 255) - alpha = float(alpha / 255) return "{0:.3f},{1:.3f},{2:.3f},{3:.3f}".format( red, green, blue, alpha) diff --git a/client/ayon_core/plugins/publish/extract_thumbnail.py b/client/ayon_core/plugins/publish/extract_thumbnail.py index 3874ddc13c..e392ce630a 100644 --- a/client/ayon_core/plugins/publish/extract_thumbnail.py +++ b/client/ayon_core/plugins/publish/extract_thumbnail.py @@ -42,15 +42,27 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): integrate_thumbnail = False target_size = { - "type": "resize", - "width": 1920, - "height": 1080 + "type": "source", + "resize": { + "width": 1920, + "height": 1080 + } } - background_color = None + background_color = (0, 0, 0, 0.0) duration_split = 0.5 # attribute presets from settings - oiiotool_defaults = None - ffmpeg_args = None + oiiotool_defaults = { + "type": "colorspace", + "colorspace": "color_picking", + "display_and_view": { + "display": "default", + "view": "sRGB" + } + } + ffmpeg_args = { + "input": [], + "output": [] + } product_names = [] def process(self, instance): @@ -369,7 +381,6 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): repre_display = colorspace_data.get("display") repre_view = colorspace_data.get("view") - oiio_default_type = None oiio_default_display = None oiio_default_view = None oiio_default_colorspace = None @@ -387,11 +398,12 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): # oiiotool_defaults elif self.oiiotool_defaults: oiio_default_type = self.oiiotool_defaults["type"] - if "colorspace" in oiio_default_type: + if "colorspace" == oiio_default_type: oiio_default_colorspace = self.oiiotool_defaults["colorspace"] else: - oiio_default_display = self.oiiotool_defaults["display"] - oiio_default_view = self.oiiotool_defaults["view"] + display_and_view = self.oiiotool_defaults["display_and_view"] + oiio_default_display = display_and_view["display"] + oiio_default_view = display_and_view["view"] try: convert_colorspace( @@ -507,11 +519,12 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): input_path, ): # get settings - if self.target_size.get("type") == "source": + if self.target_size["type"] == "source": return [] - target_width = self.target_size["width"] - target_height = self.target_size["height"] + resize = self.target_size["resize"] + target_width = resize["width"] + target_height = resize["height"] # form arg string per application return get_rescaled_command_arguments( diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 5c4813f3aa..12d4833469 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -406,26 +406,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Publish conversion ayon_publish = ayon_core["publish"] - # ExtractThumbnail plugin - ayon_extract_thumbnail = ayon_publish["ExtractThumbnail"] - # fix display and view at oiio defaults - ayon_default_oiio = copy.deepcopy( - ayon_extract_thumbnail["oiiotool_defaults"]) - display_and_view = ayon_default_oiio.pop("display_and_view") - ayon_default_oiio["display"] = display_and_view["display"] - ayon_default_oiio["view"] = display_and_view["view"] - ayon_extract_thumbnail["oiiotool_defaults"] = ayon_default_oiio - # fix target size - ayon_default_resize = copy.deepcopy(ayon_extract_thumbnail["target_size"]) - resize = ayon_default_resize.pop("resize") - ayon_default_resize["width"] = resize["width"] - ayon_default_resize["height"] = resize["height"] - ayon_extract_thumbnail["target_size"] = ayon_default_resize - # fix background color - ayon_extract_thumbnail["background_color"] = _convert_color( - ayon_extract_thumbnail["background_color"] - ) - # Project root settings - json string to dict ayon_core["project_environments"] = json.loads( ayon_core["project_environments"] From c8ec6ad2b83ba32a9467f31ccb4bcf1ed4969c52 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:58:39 +0100 Subject: [PATCH 088/149] 'project_environments' are loaded correctly --- client/ayon_core/lib/applications.py | 1 + client/ayon_core/settings/ayon_settings.py | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 60ef2a6708..d79f18a707 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1658,6 +1658,7 @@ def apply_project_environments_value( env_value = project_settings["global"]["project_environments"] if env_value: + env_value = json.loads(env_value) parsed_value = parse_environments(env_value, env_group) env.update(acre.compute( _merge_env(parsed_value, env), diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 12d4833469..6d2163ee6e 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -406,14 +406,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Publish conversion ayon_publish = ayon_core["publish"] - # Project root settings - json string to dict - ayon_core["project_environments"] = json.loads( - ayon_core["project_environments"] - ) - ayon_core["project_folder_structure"] = json.dumps(json.loads( - ayon_core["project_folder_structure"] - )) - # Tools settings ayon_core["sync_server"] = ( default_settings["global"]["sync_server"] From ad6472e9bf55ffea5e00d91e169a991f16089d35 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:59:20 +0100 Subject: [PATCH 089/149] removed core settings conversion --- client/ayon_core/hosts/nuke/api/plugin.py | 2 +- client/ayon_core/lib/applications.py | 6 +++--- client/ayon_core/pipeline/colorspace.py | 2 +- client/ayon_core/pipeline/context_tools.py | 4 ++-- .../ayon_core/pipeline/create/legacy_create.py | 2 +- .../ayon_core/pipeline/create/subset_name.py | 2 +- client/ayon_core/pipeline/load/plugins.py | 2 +- client/ayon_core/pipeline/project_folders.py | 2 +- client/ayon_core/pipeline/publish/lib.py | 8 ++++---- client/ayon_core/pipeline/version_start.py | 2 +- .../pipeline/workfile/lock_workfile.py | 2 +- .../pipeline/workfile/path_resolving.py | 4 ++-- .../plugins/publish/collect_comment.py | 2 +- client/ayon_core/settings/ayon_settings.py | 18 ------------------ client/ayon_core/tools/pyblish_pype/control.py | 2 +- 15 files changed, 21 insertions(+), 39 deletions(-) diff --git a/client/ayon_core/hosts/nuke/api/plugin.py b/client/ayon_core/hosts/nuke/api/plugin.py index 4b8ddac167..d9be3fad17 100644 --- a/client/ayon_core/hosts/nuke/api/plugin.py +++ b/client/ayon_core/hosts/nuke/api/plugin.py @@ -493,7 +493,7 @@ def get_colorspace_from_node(node): def get_review_presets_config(): settings = get_current_project_settings() review_profiles = ( - settings["global"] + settings["core"] ["publish"] ["ExtractReview"] ["profiles"] diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index d79f18a707..a4e2d9c89d 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1656,7 +1656,7 @@ def apply_project_environments_value( if project_settings is None: project_settings = get_project_settings(project_name) - env_value = project_settings["global"]["project_environments"] + env_value = project_settings["core"]["project_environments"] if env_value: env_value = json.loads(env_value) parsed_value = parse_environments(env_value, env_group) @@ -1917,7 +1917,7 @@ def should_start_last_workfile( project_settings = get_project_settings(project_name) profiles = ( project_settings - ["global"] + ["core"] ["tools"] ["Workfiles"] ["last_workfile_on_startup"] @@ -1967,7 +1967,7 @@ def should_workfile_tool_start( project_settings = get_project_settings(project_name) profiles = ( project_settings - ["global"] + ["core"] ["tools"] ["Workfiles"] ["open_workfile_tool_on_startup"] diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index 1b795e1c39..7100984217 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -1018,7 +1018,7 @@ def _get_imageio_settings(project_settings, host_name): tuple[dict, dict]: image io settings for global and host """ # get image io from global and host_name - imageio_global = project_settings["global"]["imageio"] + imageio_global = project_settings["core"]["imageio"] # host is optional, some might not have any settings imageio_host = project_settings.get(host_name, {}).get("imageio", {}) diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 730852ff4a..7c0db0be27 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -208,8 +208,8 @@ def install_ayon_plugins(project_name=None, host_name=None): platform_name = platform.system().lower() project_plugins = ( project_settings - .get("global", {}) - .get("project_plugins", {}) + ["core"] + ["project_plugins"] .get(platform_name) ) or [] for path in project_plugins: diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index aab6b67e6f..2ab8b8e3e5 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -54,7 +54,7 @@ class LegacyCreator(object): ) global_type_settings = ( project_settings - .get("global", {}) + .get("core", {}) .get(plugin_type, {}) ) if not global_type_settings and not plugin_type_settings: diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 81967ffd99..5925ec0f2b 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -47,7 +47,7 @@ def get_subset_name_template( if project_settings is None: project_settings = get_project_settings(project_name) - tools_settings = project_settings["global"]["tools"] + tools_settings = project_settings["core"]["tools"] profiles = tools_settings["creator"]["product_name_profiles"] filtering_criteria = { "product_types": family, diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index 1d4627689f..962417c6f2 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -47,7 +47,7 @@ class LoaderPlugin(list): ) global_type_settings = ( project_settings - .get("global", {}) + .get("core", {}) .get(plugin_type, {}) ) if not global_type_settings and not plugin_type_settings: diff --git a/client/ayon_core/pipeline/project_folders.py b/client/ayon_core/pipeline/project_folders.py index ad205522a6..811a98ce4b 100644 --- a/client/ayon_core/pipeline/project_folders.py +++ b/client/ayon_core/pipeline/project_folders.py @@ -104,7 +104,7 @@ def _list_path_items(folder_structure): def get_project_basic_paths(project_name): project_settings = get_project_settings(project_name) folder_structure = ( - project_settings["global"]["project_folder_structure"] + project_settings["core"]["project_folder_structure"] ) if not folder_structure: return [] diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index a14651551f..90725e6d79 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -60,7 +60,7 @@ def get_template_name_profiles( return copy.deepcopy( project_settings - ["global"] + ["core"] ["tools"] ["publish"] ["template_name_profiles"] @@ -95,7 +95,7 @@ def get_hero_template_name_profiles( return copy.deepcopy( project_settings - ["global"] + ["core"] ["tools"] ["publish"] ["hero_template_name_profiles"] @@ -383,7 +383,7 @@ def get_plugin_settings(plugin, project_settings, log, category=None): # TODO: change after all plugins are moved one level up if category_from_file in ("ayon_core", "openpype"): - category_from_file = "global" + category_from_file = "core" try: return ( @@ -744,7 +744,7 @@ def get_custom_staging_dir_info(project_name, host_name, family, task_name, ValueError - if misconfigured template should be used """ settings = project_settings or get_project_settings(project_name) - custom_staging_dir_profiles = (settings["global"] + custom_staging_dir_profiles = (settings["core"] ["tools"] ["publish"] ["custom_staging_dir_profiles"]) diff --git a/client/ayon_core/pipeline/version_start.py b/client/ayon_core/pipeline/version_start.py index bd7d800335..4813910bf3 100644 --- a/client/ayon_core/pipeline/version_start.py +++ b/client/ayon_core/pipeline/version_start.py @@ -16,7 +16,7 @@ def get_versioning_start( project_settings = get_project_settings(project_name) version_start = 1 - settings = project_settings["global"] + settings = project_settings["core"] profiles = settings.get("version_start_category", {}).get("profiles", []) if not profiles: diff --git a/client/ayon_core/pipeline/workfile/lock_workfile.py b/client/ayon_core/pipeline/workfile/lock_workfile.py index a6d4348966..7eab3f36dc 100644 --- a/client/ayon_core/pipeline/workfile/lock_workfile.py +++ b/client/ayon_core/pipeline/workfile/lock_workfile.py @@ -64,7 +64,7 @@ def is_workfile_lock_enabled(host_name, project_name, project_setting=None): project_setting = get_project_settings(project_name) workfile_lock_profiles = ( project_setting - ["global"] + ["core"] ["tools"] ["Workfiles"] ["workfile_lock_profiles"]) diff --git a/client/ayon_core/pipeline/workfile/path_resolving.py b/client/ayon_core/pipeline/workfile/path_resolving.py index 2062705d3c..168e775475 100644 --- a/client/ayon_core/pipeline/workfile/path_resolving.py +++ b/client/ayon_core/pipeline/workfile/path_resolving.py @@ -72,7 +72,7 @@ def get_workfile_template_key( try: profiles = ( project_settings - ["global"] + ["core"] ["tools"] ["Workfiles"] ["workfile_template_profiles"] @@ -507,7 +507,7 @@ def create_workdir_extra_folders( # Load extra folders profiles extra_folders_profiles = ( - project_settings["global"]["tools"]["Workfiles"]["extra_folders"] + project_settings["core"]["tools"]["Workfiles"]["extra_folders"] ) # Skip if are empty if not extra_folders_profiles: diff --git a/client/ayon_core/plugins/publish/collect_comment.py b/client/ayon_core/plugins/publish/collect_comment.py index dadb7b9e8d..458c0a5658 100644 --- a/client/ayon_core/plugins/publish/collect_comment.py +++ b/client/ayon_core/plugins/publish/collect_comment.py @@ -43,7 +43,7 @@ class CollectInstanceCommentDef( @classmethod def apply_settings(cls, project_setting, _): - plugin_settings = project_setting["global"]["publish"].get( + plugin_settings = project_setting["core"]["publish"].get( "collect_comment_per_instance" ) if not plugin_settings: diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 6d2163ee6e..4d45f8cca8 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -397,22 +397,6 @@ def _convert_royalrender_project_settings(ayon_settings, output): } -def _convert_global_project_settings(ayon_settings, output, default_settings): - if "core" not in ayon_settings: - return - - ayon_core = ayon_settings["core"] - - # Publish conversion - ayon_publish = ayon_core["publish"] - - # Tools settings - ayon_core["sync_server"] = ( - default_settings["global"]["sync_server"] - ) - output["global"] = ayon_core - - def convert_project_settings(ayon_settings, default_settings): default_settings = copy.deepcopy(default_settings) output = {} @@ -422,8 +406,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_royalrender_project_settings(ayon_settings, output) - _convert_global_project_settings(ayon_settings, output, default_settings) - for key, value in ayon_settings.items(): if key not in output: output[key] = value diff --git a/client/ayon_core/tools/pyblish_pype/control.py b/client/ayon_core/tools/pyblish_pype/control.py index 1a3e7a15f0..0e25fa9e27 100644 --- a/client/ayon_core/tools/pyblish_pype/control.py +++ b/client/ayon_core/tools/pyblish_pype/control.py @@ -208,7 +208,7 @@ class Controller(QtCore.QObject): if not presets: return {} - result = presets.get("global", {}).get("filters", {}) + result = presets.get("core", {}).get("filters", {}) hosts = pyblish.api.registered_hosts() for host in hosts: host_presets = presets.get(host, {}).get("filters") From 47d9af00eab4da6b5cc244a718a6bf9a759883c3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 15 Feb 2024 23:14:06 +0100 Subject: [PATCH 090/149] fix burnins def loop --- client/ayon_core/plugins/publish/extract_burnin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 4da158343e..499a72bd4f 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -120,7 +120,7 @@ class ExtractBurnin(publish.Extractor): # Filter output definition by `burnin` represetation key repre_linked_burnins = [ burnin_def - for burnin_def in burnin_defs.items() + for burnin_def in burnin_defs if burnin_def["name"] in repre_burnin_links ] self.log.debug( From bc83a61365330b2c19dda4c523c14d20377fdaec Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Feb 2024 23:28:35 +0100 Subject: [PATCH 091/149] fix type check --- client/ayon_core/hosts/maya/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index aba5fd8903..42c0c7051e 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -612,7 +612,7 @@ def get_load_color_for_family(family, settings=None): else: raise ValueError("Invalid color definition {}".format(str(color))) - if type(red, int): + if isinstance(red, int): red = red / 255.0 green = green / 255.0 blue = blue / 255.0 From 005e1b70cc2d89e5a1b62087ca3513406d5dc4d5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:35:35 +0100 Subject: [PATCH 092/149] removed unused rr_path attribute --- client/ayon_core/modules/royalrender/royal_render_module.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/ayon_core/modules/royalrender/royal_render_module.py b/client/ayon_core/modules/royalrender/royal_render_module.py index 66b09832d8..a413fc4d8d 100644 --- a/client/ayon_core/modules/royalrender/royal_render_module.py +++ b/client/ayon_core/modules/royalrender/royal_render_module.py @@ -20,7 +20,6 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): def __init__(self, manager, settings): # type: (ayon_core.addon.AddonsManager, dict) -> None - self.rr_paths = {} self._api = None self.settings = settings super(RoyalRenderModule, self).__init__(manager, settings) @@ -29,7 +28,6 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): # type: (dict) -> None rr_settings = module_settings[self.name] self.enabled = rr_settings["enabled"] - self.rr_paths = rr_settings.get("rr_paths") @staticmethod def get_plugin_paths(): From c34daca9b034f00400dc37e84e95858b2f5e5b5e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:40:36 +0100 Subject: [PATCH 093/149] removed royalrender settings conversion --- client/ayon_core/settings/ayon_settings.py | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 190970b908..3a69711d57 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -78,21 +78,6 @@ def _convert_deadline_system_settings( output["modules"]["deadline"] = deadline_settings -def _convert_royalrender_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("royalrender") is not None - rr_settings = default_settings["modules"]["royalrender"] - rr_settings["enabled"] = enabled - if enabled: - ayon_royalrender = ayon_settings["royalrender"] - rr_settings["rr_paths"] = { - item["name"]: item["value"] - for item in ayon_royalrender["rr_paths"] - } - output["modules"]["royalrender"] = rr_settings - - def _convert_modules_system( ayon_settings, output, addon_versions, default_settings ): @@ -100,13 +85,13 @@ def _convert_modules_system( # TODO add 'enabled' values for func in ( _convert_deadline_system_settings, - _convert_royalrender_system_settings, ): func(ayon_settings, output, addon_versions, default_settings) for key in { "timers_manager", "clockify", + "royalrender", }: if addon_versions.get(key): output[key] = ayon_settings From 834cea70667cdeb885c34d2aaa2b14e1bd35dfa8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:42:21 +0100 Subject: [PATCH 094/149] Modified royal render addon initialization and name --- client/ayon_core/modules/royalrender/__init__.py | 4 ++-- .../modules/royalrender/royal_render_module.py | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/modules/royalrender/__init__.py b/client/ayon_core/modules/royalrender/__init__.py index cc92e3b50d..a4769b6086 100644 --- a/client/ayon_core/modules/royalrender/__init__.py +++ b/client/ayon_core/modules/royalrender/__init__.py @@ -1,6 +1,6 @@ -from .royal_render_module import RoyalRenderModule +from .royal_render_module import RoyalRenderAddon __all__ = ( - "RoyalRenderModule", + "RoyalRenderAddon", ) diff --git a/client/ayon_core/modules/royalrender/royal_render_module.py b/client/ayon_core/modules/royalrender/royal_render_module.py index a413fc4d8d..ba3ce67198 100644 --- a/client/ayon_core/modules/royalrender/royal_render_module.py +++ b/client/ayon_core/modules/royalrender/royal_render_module.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- """Module providing support for Royal Render.""" import os -import ayon_core.modules -from ayon_core.modules import OpenPypeModule, IPluginPaths + +from ayon_core.addon import AYONAddon, IPluginPaths -class RoyalRenderModule(OpenPypeModule, IPluginPaths): +class RoyalRenderAddon(AYONAddon, IPluginPaths): """Class providing basic Royal Render implementation logic.""" name = "royalrender" @@ -19,15 +19,13 @@ class RoyalRenderModule(OpenPypeModule, IPluginPaths): return self._api def __init__(self, manager, settings): - # type: (ayon_core.addon.AddonsManager, dict) -> None self._api = None self.settings = settings super(RoyalRenderModule, self).__init__(manager, settings) - def initialize(self, module_settings): + def initialize(self, studio_settings): # type: (dict) -> None - rr_settings = module_settings[self.name] - self.enabled = rr_settings["enabled"] + self.enabled = self.name in studio_settings @staticmethod def get_plugin_paths(): From 722923f3c09c3433bd0aefede385414fe4d581eb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:43:19 +0100 Subject: [PATCH 095/149] modified code to use AYON settings --- client/ayon_core/modules/royalrender/lib.py | 31 ++++----------- .../publish/collect_rr_path_from_instance.py | 39 +++++++------------ .../publish/submit_jobs_to_royalrender.py | 31 ++++----------- 3 files changed, 31 insertions(+), 70 deletions(-) diff --git a/client/ayon_core/modules/royalrender/lib.py b/client/ayon_core/modules/royalrender/lib.py index 5343a5f06f..966eb82ab1 100644 --- a/client/ayon_core/modules/royalrender/lib.py +++ b/client/ayon_core/modules/royalrender/lib.py @@ -213,30 +213,15 @@ class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, @staticmethod def _resolve_rr_path(context, rr_path_name): # type: (pyblish.api.Context, str) -> str - rr_settings = ( - context.data - ["system_settings"] - ["modules"] - ["royalrender"] - ) - try: - default_servers = rr_settings["rr_paths"] - project_servers = ( - context.data - ["project_settings"] - ["royalrender"] - ["rr_paths"] - ) - rr_servers = { - k: default_servers[k] - for k in project_servers - if k in default_servers - } - - except (AttributeError, KeyError): - # Handle situation were we had only one url for royal render. - return context.data["defaultRRPath"][platform.system().lower()] + rr_settings = context.data["project_settings"]["royalrender"] + rr_paths = rr_settings["rr_paths"] + selected_paths = rr_settings["selected_rr_paths"] + rr_servers = { + path_key: rr_paths[path_key] + for path_key in selected_paths + if path_key in rr_paths + } return rr_servers[rr_path_name][platform.system().lower()] def expected_files(self, instance, path, start_frame, end_frame): diff --git a/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py b/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py index e978ce5bed..f43ed1ca49 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py @@ -18,30 +18,21 @@ class CollectRRPathFromInstance(pyblish.api.InstancePlugin): def _collect_rr_path_name(instance): # type: (pyblish.api.Instance) -> str """Get Royal Render pat name from render instance.""" - rr_settings = ( - instance.context.data - ["system_settings"] - ["modules"] - ["royalrender"] - ) - if not instance.data.get("rrPaths"): + + instance_rr_paths = instance.data.get("rrPaths") + if instance_rr_paths is None: return "default" - try: - default_servers = rr_settings["rr_paths"] - project_servers = ( - instance.context.data - ["project_settings"] - ["royalrender"] - ["rr_paths"] - ) - rr_servers = { - k: default_servers[k] - for k in project_servers - if k in default_servers - } - except (AttributeError, KeyError): - # Handle situation were we had only one url for royal render. - return rr_settings["rr_paths"]["default"] + rr_settings = instance.context.data["project_settings"]["royalrender"] + rr_paths = rr_settings["rr_paths"] + selected_paths = rr_settings["selected_rr_paths"] - return list(rr_servers.keys())[int(instance.data.get("rrPaths"))] + rr_servers = { + path_key + for path_key in selected_paths + if path_key in rr_paths + } + for instance_rr_path in instance_rr_paths: + if instance_rr_path in rr_servers: + return instance_rr_path + return "default" diff --git a/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py b/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py index a76bdfc26c..5e25464186 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py @@ -104,28 +104,13 @@ class SubmitJobsToRoyalRender(pyblish.api.ContextPlugin): @staticmethod def _resolve_rr_path(context, rr_path_name): # type: (pyblish.api.Context, str) -> str - rr_settings = ( - context.data - ["system_settings"] - ["modules"] - ["royalrender"] - ) - try: - default_servers = rr_settings["rr_paths"] - project_servers = ( - context.data - ["project_settings"] - ["royalrender"] - ["rr_paths"] - ) - rr_servers = { - k: default_servers[k] - for k in project_servers - if k in default_servers - } - - except (AttributeError, KeyError): - # Handle situation were we had only one url for royal render. - return context.data["defaultRRPath"][platform.system().lower()] + rr_settings = context.data["project_settings"]["royalrender"] + rr_paths = rr_settings["rr_paths"] + selected_paths = rr_settings["selected_rr_paths"] + rr_servers = { + path_key: rr_paths[path_key] + for path_key in selected_paths + if path_key in rr_paths + } return rr_servers[rr_path_name][platform.system().lower()] From 50fbc854a3f10db8468e07761d5e2f2e12a534f0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:44:31 +0100 Subject: [PATCH 096/149] renamed 'royal_render_module.py' to 'addon.py' --- client/ayon_core/modules/royalrender/__init__.py | 2 +- .../modules/royalrender/{royal_render_module.py => addon.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename client/ayon_core/modules/royalrender/{royal_render_module.py => addon.py} (100%) diff --git a/client/ayon_core/modules/royalrender/__init__.py b/client/ayon_core/modules/royalrender/__init__.py index a4769b6086..121530beda 100644 --- a/client/ayon_core/modules/royalrender/__init__.py +++ b/client/ayon_core/modules/royalrender/__init__.py @@ -1,4 +1,4 @@ -from .royal_render_module import RoyalRenderAddon +from .addon import RoyalRenderAddon __all__ = ( diff --git a/client/ayon_core/modules/royalrender/royal_render_module.py b/client/ayon_core/modules/royalrender/addon.py similarity index 100% rename from client/ayon_core/modules/royalrender/royal_render_module.py rename to client/ayon_core/modules/royalrender/addon.py From 313894c5b1286328a24ca524d1b0b9bc45ad0153 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:51:56 +0100 Subject: [PATCH 097/149] commented out unused 'api' property --- client/ayon_core/modules/royalrender/addon.py | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/modules/royalrender/addon.py b/client/ayon_core/modules/royalrender/addon.py index ba3ce67198..e9dd694f4c 100644 --- a/client/ayon_core/modules/royalrender/addon.py +++ b/client/ayon_core/modules/royalrender/addon.py @@ -9,19 +9,14 @@ class RoyalRenderAddon(AYONAddon, IPluginPaths): """Class providing basic Royal Render implementation logic.""" name = "royalrender" - @property - def api(self): - if not self._api: - # import royal render modules - from . import api as rr_api - self._api = rr_api.Api(self.settings) - - return self._api - - def __init__(self, manager, settings): - self._api = None - self.settings = settings - super(RoyalRenderModule, self).__init__(manager, settings) + # @property + # def api(self): + # if not self._api: + # # import royal render modules + # from . import api as rr_api + # self._api = rr_api.Api(self.settings) + # + # return self._api def initialize(self, studio_settings): # type: (dict) -> None From c359f05d8d82e15375c83a941a94a3eb0641650b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 09:53:09 +0100 Subject: [PATCH 098/149] renamed 'api' property to 'rr_api' --- client/ayon_core/modules/royalrender/addon.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/modules/royalrender/addon.py b/client/ayon_core/modules/royalrender/addon.py index e9dd694f4c..e69cf9feec 100644 --- a/client/ayon_core/modules/royalrender/addon.py +++ b/client/ayon_core/modules/royalrender/addon.py @@ -9,14 +9,14 @@ class RoyalRenderAddon(AYONAddon, IPluginPaths): """Class providing basic Royal Render implementation logic.""" name = "royalrender" + # _rr_api = None # @property - # def api(self): - # if not self._api: + # def rr_api(self): + # if not self._rr_api: # # import royal render modules - # from . import api as rr_api - # self._api = rr_api.Api(self.settings) - # - # return self._api + # from .api import Api + # self._rr_api = Api(self.settings) + # return self._rr_api def initialize(self, studio_settings): # type: (dict) -> None From fe2909f2d8a8bc339c6ae12ac676ded79ae3ebdc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 10:22:51 +0100 Subject: [PATCH 099/149] removed deadline conversion --- client/ayon_core/settings/ayon_settings.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 190970b908..830cbd5e10 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -62,22 +62,6 @@ def _convert_general(ayon_settings, output, default_settings): } -def _convert_deadline_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("deadline") is not None - deadline_settings = default_settings["modules"]["deadline"] - deadline_settings["enabled"] = enabled - if enabled: - ayon_deadline = ayon_settings["deadline"] - deadline_settings["deadline_urls"] = { - item["name"]: item["value"] - for item in ayon_deadline["deadline_urls"] - } - - output["modules"]["deadline"] = deadline_settings - - def _convert_royalrender_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -99,7 +83,6 @@ def _convert_modules_system( # TODO add all modules # TODO add 'enabled' values for func in ( - _convert_deadline_system_settings, _convert_royalrender_system_settings, ): func(ayon_settings, output, addon_versions, default_settings) @@ -107,6 +90,7 @@ def _convert_modules_system( for key in { "timers_manager", "clockify", + "deadline", }: if addon_versions.get(key): output[key] = ayon_settings From b41109559b5e3d3cad29cd3a238d2f6605ac3a5e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 10:28:29 +0100 Subject: [PATCH 100/149] modified deadline addon to use AYON settings --- .../modules/deadline/deadline_module.py | 38 +++++++++---------- .../collect_deadline_server_from_instance.py | 7 +++- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/client/ayon_core/modules/deadline/deadline_module.py b/client/ayon_core/modules/deadline/deadline_module.py index c98d04759e..97d346c287 100644 --- a/client/ayon_core/modules/deadline/deadline_module.py +++ b/client/ayon_core/modules/deadline/deadline_module.py @@ -4,7 +4,7 @@ import six import sys from ayon_core.lib import requests_get, Logger -from ayon_core.modules import OpenPypeModule, IPluginPaths +from ayon_core.modules import AYONAddon, IPluginPaths class DeadlineWebserviceError(Exception): @@ -13,28 +13,28 @@ class DeadlineWebserviceError(Exception): """ -class DeadlineModule(OpenPypeModule, IPluginPaths): +class DeadlineModule(AYONAddon, IPluginPaths): name = "deadline" - def __init__(self, manager, settings): - self.deadline_urls = {} - super(DeadlineModule, self).__init__(manager, settings) - - def initialize(self, modules_settings): + def initialize(self, studio_settings): # This module is always enabled - deadline_settings = modules_settings[self.name] - self.enabled = deadline_settings["enabled"] - deadline_url = deadline_settings.get("DEADLINE_REST_URL") - if deadline_url: - self.deadline_urls = {"default": deadline_url} - else: - self.deadline_urls = deadline_settings.get("deadline_urls") # noqa: E501 + deadline_urls = {} + enabled = self.name in studio_settings + if enabled: + deadline_settings = studio_settings[self.name] + deadline_urls = { + url_item["name"]: url_item["value"] + for url_item in deadline_settings["deadline_urls"] + } - if not self.deadline_urls: - self.enabled = False - self.log.warning(("default Deadline Webservice URL " - "not specified. Disabling module.")) - return + if enabled and not deadline_urls: + enabled = False + self.log.warning(( + "Deadline Webservice URLs are not specified. Disabling addon." + )) + + self.enabled = enabled + self.deadline_urls = deadline_urls def get_plugin_paths(self): """Deadline plugin paths.""" diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py b/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py index 0cfe7c9b39..445971f2b0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py @@ -47,11 +47,11 @@ class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin): deadline_settings = ( render_instance.context.data ["system_settings"] - ["modules"] ["deadline"] ) default_server = render_instance.context.data["defaultDeadline"] + # QUESTION How and where is this is set? Should be removed? instance_server = render_instance.data.get("deadlineServers") if not instance_server: self.log.debug("Using default server.") @@ -64,7 +64,10 @@ class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin): asString=True ) - default_servers = deadline_settings["deadline_urls"] + default_servers = { + url_item["name"]: url_item["value"] + for url_item in deadline_settings["deadline_urls"] + } project_servers = ( render_instance.context.data ["project_settings"] From aafc6470c29f73fad297077bd256dab943c8d5f3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 14:45:10 +0100 Subject: [PATCH 101/149] use 'folderPath' instead of 'asset' --- .../publish/submit_maya_remote_publish_deadline.py | 2 +- .../plugins/publish/submit_publish_cache_job.py | 6 +++--- .../deadline/plugins/publish/submit_publish_job.py | 12 ++++++------ client/ayon_core/modules/royalrender/lib.py | 2 +- .../plugins/publish/collect_sequences_from_job.py | 4 ++-- .../publish/create_publish_royalrender_job.py | 4 ++-- .../timers_manager/plugins/publish/start_timer.py | 2 +- client/ayon_core/pipeline/create/legacy_create.py | 4 ++-- client/ayon_core/pipeline/farm/pyblish_functions.py | 10 +++++----- .../pipeline/publish/abstract_collect_render.py | 2 +- .../plugins/publish/collect_anatomy_instance_data.py | 4 ++-- client/ayon_core/plugins/publish/collect_audio.py | 2 +- .../plugins/publish/collect_context_entities.py | 2 +- .../plugins/publish/collect_current_context.py | 7 +++---- .../ayon_core/plugins/publish/collect_frames_fix.py | 2 +- .../plugins/publish/collect_from_create_context.py | 3 +-- .../ayon_core/plugins/publish/collect_hierarchy.py | 2 +- .../plugins/publish/collect_rendered_files.py | 11 ++++++++--- .../plugins/publish/extract_hierarchy_to_ayon.py | 2 +- .../plugins/publish/extract_otio_audio_tracks.py | 2 +- .../ayon_core/plugins/publish/integrate_thumbnail.py | 5 +++-- .../plugins/publish/validate_editorial_asset_name.py | 2 +- .../plugins/publish/validate_unique_subsets.py | 2 +- 23 files changed, 49 insertions(+), 45 deletions(-) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py index 1042c44c33..772fa03628 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py @@ -105,7 +105,7 @@ class MayaSubmitRemotePublishDeadline( } environment["AYON_PROJECT_NAME"] = project_name - environment["AYON_FOLDER_PATH"] = instance.context.data["asset"] + environment["AYON_FOLDER_PATH"] = instance.context.data["folderPath"] environment["AYON_TASK_NAME"] = instance.context.data["task"] environment["AYON_APP_NAME"] = os.environ.get("AYON_APP_NAME") environment["OPENPYPE_PUBLISH_SUBSET"] = instance.data["subset"] 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 54d4fb47fc..0b0e293943 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 @@ -112,7 +112,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, output_dir = self._get_publish_folder( anatomy, deepcopy(instance.data["anatomyData"]), - instance.data.get("asset"), + instance.data.get("folderPath"), instance.data["subset"], instance.context, instance.data["family"], @@ -126,7 +126,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, environment = { "AYON_PROJECT_NAME": instance.context.data["projectName"], - "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_FOLDER_PATH": instance.context.data["folderPath"], "AYON_TASK_NAME": instance.context.data["task"], "AYON_USERNAME": instance.context.data["user"], "AYON_LOG_NO_COLORS": "1", @@ -359,7 +359,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, # publish job file publish_job = { - "asset": instance_skeleton_data["asset"], + "folderPath": instance_skeleton_data["folderPath"], "frameStart": instance_skeleton_data["frameStart"], "frameEnd": instance_skeleton_data["frameEnd"], "fps": instance_skeleton_data["fps"], 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 d4d04f79f6..31c845a0b8 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 @@ -189,7 +189,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, output_dir = self._get_publish_folder( anatomy, deepcopy(instance.data["anatomyData"]), - instance.data.get("asset"), + instance.data.get("folderPath"), instances[0]["subset"], instance.context, instances[0]["family"], @@ -203,7 +203,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, environment = { "AYON_PROJECT_NAME": instance.context.data["projectName"], - "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_FOLDER_PATH": instance.context.data["folderPath"], "AYON_TASK_NAME": instance.context.data["task"], "AYON_USERNAME": instance.context.data["user"], "AYON_LOG_NO_COLORS": "1", @@ -335,7 +335,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, self.context = context self.anatomy = instance.context.data["anatomy"] - asset = data.get("asset") or context.data["asset"] + folder_path = data.get("folderPath") or context.data["folderPath"] subset = data.get("subset") start = instance.data.get("frameStart") @@ -360,7 +360,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, if data.get("extendFrames", False): start, end = self._extend_frames( - asset, + folder_path, subset, start, end, @@ -402,7 +402,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "family": family, "subset": subset, "families": families, - "asset": asset, + "folderPath": folder_path, "frameStart": start, "frameEnd": end, "handleStart": handle_start, @@ -620,7 +620,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, # publish job file publish_job = { - "asset": instance_skeleton_data["asset"], + "folderPath": instance_skeleton_data["folderPath"], "frameStart": instance_skeleton_data["frameStart"], "frameEnd": instance_skeleton_data["frameEnd"], "fps": instance_skeleton_data["fps"], diff --git a/client/ayon_core/modules/royalrender/lib.py b/client/ayon_core/modules/royalrender/lib.py index 5343a5f06f..f782cb9984 100644 --- a/client/ayon_core/modules/royalrender/lib.py +++ b/client/ayon_core/modules/royalrender/lib.py @@ -350,7 +350,7 @@ class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, add_kwargs = { "project": anatomy_data["project"]["name"], - "asset": instance.context.data["asset"], + "asset": instance.context.data["folderPath"], "task": anatomy_data["task"]["name"], "app": instance.context.data.get("appName"), "envgroup": "farm" diff --git a/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py b/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py index cd34ba9bb3..4460e11004 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py @@ -189,8 +189,8 @@ class CollectSequencesFromJob(pyblish.api.ContextPlugin): "family": families[0], # backwards compatibility / pyblish "families": list(families), "subset": subset, - "asset": data.get( - "asset", context.data["asset"] + "folderPath": data.get( + "folderPath", context.data["folderPath"] ), "stagingDir": root, "frameStart": start, diff --git a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index 910abfcb15..33f5585cef 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -132,7 +132,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, # publish job file publish_job = { - "asset": instance_skeleton_data["asset"], + "folderPath": instance_skeleton_data["folderPath"], "frameStart": instance_skeleton_data["frameStart"], "frameEnd": instance_skeleton_data["frameEnd"], "fps": instance_skeleton_data["fps"], @@ -180,7 +180,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, environment = RREnvList({ "AYON_PROJECT_NAME": anatomy_data["project"]["name"], - "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_FOLDER_PATH": instance.context.data["folderPath"], "AYON_TASK_NAME": anatomy_data["task"]["name"], "AYON_USERNAME": anatomy_data["user"] }) diff --git a/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py b/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py index 51f707ecf6..a3eb49ee70 100644 --- a/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py +++ b/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py @@ -24,7 +24,7 @@ class StartTimer(pyblish.api.ContextPlugin): return project_name = context.data["projectName"] - asset_name = context.data.get("asset") + asset_name = context.data.get("folderPath") task_name = context.data.get("task") if not project_name or not asset_name or not task_name: self.log.info(( diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index aab6b67e6f..a437c7921c 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -27,7 +27,7 @@ class LegacyCreator(object): log = logging.getLogger("LegacyCreator") log.propagate = True - def __init__(self, name, asset, options=None, data=None): + def __init__(self, name, folder_path, options=None, data=None): self.name = name # For backwards compatibility self.options = options @@ -35,7 +35,7 @@ class LegacyCreator(object): self.data = collections.OrderedDict() self.data["id"] = "pyblish.avalon.instance" self.data["family"] = self.family - self.data["asset"] = asset + self.data["folderPath"] = folder_path self.data["subset"] = name self.data["active"] = True diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 389d3d27ed..4652d34011 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -197,7 +197,7 @@ def create_skeleton_instance( if data.get("extendFrames", False): time_data.start, time_data.end = extend_frames( - data["asset"], + data["folderPath"], data["subset"], time_data.start, time_data.end, @@ -228,7 +228,7 @@ def create_skeleton_instance( "family": family, "subset": data["subset"], "families": families, - "asset": data["asset"], + "folderPath": data["folderPath"], "frameStart": time_data.start, "frameEnd": time_data.end, "handleStart": time_data.handle_start, @@ -777,7 +777,7 @@ def create_skeleton_instance_cache(instance): if data.get("extendFrames", False): time_data.start, time_data.end = extend_frames( - data["asset"], + data["folderPath"], data["subset"], time_data.start, time_data.end, @@ -805,7 +805,7 @@ def create_skeleton_instance_cache(instance): "family": family, "subset": data["subset"], "families": families, - "asset": data["asset"], + "folderPath": data["folderPath"], "frameStart": time_data.start, "frameEnd": time_data.end, "handleStart": time_data.handle_start, @@ -1011,7 +1011,7 @@ def copy_extend_frames(instance, representation): version = get_last_version_by_subset_name( project_name, instance.data.get("subset"), - asset_name=instance.data.get("asset") + asset_name=instance.data.get("folderPath") ) # get its files based on extension diff --git a/client/ayon_core/pipeline/publish/abstract_collect_render.py b/client/ayon_core/pipeline/publish/abstract_collect_render.py index 764532cadb..6ca1d81bc7 100644 --- a/client/ayon_core/pipeline/publish/abstract_collect_render.py +++ b/client/ayon_core/pipeline/publish/abstract_collect_render.py @@ -30,7 +30,7 @@ class RenderInstance(object): label = attr.ib() # label to show in GUI subset = attr.ib() # subset name task = attr.ib() # task name - asset = attr.ib() # asset name + folderPath = attr.ib() # folder path attachTo = attr.ib() # subset name to attach render to setMembers = attr.ib() # list of nodes/members producing render output publish = attr.ib() # bool, True to publish instance diff --git a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py index 336ac02b8e..763aee5b1c 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py @@ -296,7 +296,7 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): if hierarchy: parent_name = hierarchy.split("/")[-1] - asset_name = instance.data["asset"].split("/")[-1] + asset_name = instance.data["folderPath"].split("/")[-1] anatomy_data.update({ "asset": asset_name, "hierarchy": hierarchy, @@ -337,7 +337,7 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): # Try to find task data based on hierarchy context and asset name hierarchy_context = instance.context.data.get("hierarchyContext") - asset_name = instance.data.get("asset") + asset_name = instance.data.get("folderPath") if not hierarchy_context or not asset_name: return diff --git a/client/ayon_core/plugins/publish/collect_audio.py b/client/ayon_core/plugins/publish/collect_audio.py index 6da3fd0685..f0efd546e7 100644 --- a/client/ayon_core/plugins/publish/collect_audio.py +++ b/client/ayon_core/plugins/publish/collect_audio.py @@ -66,7 +66,7 @@ class CollectAudio(pyblish.api.ContextPlugin): # Add audio to instance if exists. instances_by_asset_name = collections.defaultdict(list) for instance in filtered_instances: - asset_name = instance.data["asset"] + asset_name = instance.data["folderPath"] instances_by_asset_name[asset_name].append(instance) asset_names = set(instances_by_asset_name.keys()) diff --git a/client/ayon_core/plugins/publish/collect_context_entities.py b/client/ayon_core/plugins/publish/collect_context_entities.py index 30bb184ef5..64ef73e2d9 100644 --- a/client/ayon_core/plugins/publish/collect_context_entities.py +++ b/client/ayon_core/plugins/publish/collect_context_entities.py @@ -25,7 +25,7 @@ class CollectContextEntities(pyblish.api.ContextPlugin): def process(self, context): project_name = context.data["projectName"] - asset_name = context.data["asset"] + asset_name = context.data["folderPath"] task_name = context.data["task"] project_entity = get_project(project_name) diff --git a/client/ayon_core/plugins/publish/collect_current_context.py b/client/ayon_core/plugins/publish/collect_current_context.py index 90b9fcdcbd..6a22daa04a 100644 --- a/client/ayon_core/plugins/publish/collect_current_context.py +++ b/client/ayon_core/plugins/publish/collect_current_context.py @@ -1,7 +1,7 @@ """ Provides: context -> projectName (str) - context -> asset (str) + context -> folderPath (str) context -> task (str) """ @@ -21,7 +21,7 @@ class CollectCurrentContext(pyblish.api.ContextPlugin): def process(self, context): # Check if values are already set project_name = context.data.get("projectName") - asset_name = context.data.get("asset") + asset_name = context.data.get("folderPath") task_name = context.data.get("task") current_context = get_current_context() @@ -29,13 +29,12 @@ class CollectCurrentContext(pyblish.api.ContextPlugin): context.data["projectName"] = current_context["project_name"] if not asset_name: - context.data["asset"] = current_context["asset_name"] + context.data["folderPath"] = current_context["asset_name"] if not task_name: context.data["task"] = current_context["task_name"] # QUESTION should we be explicit with keys? (the same on instances) - # - 'asset' -> 'assetName' # - 'task' -> 'taskName' self.log.info(( diff --git a/client/ayon_core/plugins/publish/collect_frames_fix.py b/client/ayon_core/plugins/publish/collect_frames_fix.py index 4903991d40..6996844eda 100644 --- a/client/ayon_core/plugins/publish/collect_frames_fix.py +++ b/client/ayon_core/plugins/publish/collect_frames_fix.py @@ -41,7 +41,7 @@ class CollectFramesFixDef( instance.data["frames_to_fix"] = frames_to_fix subset_name = instance.data["subset"] - asset_name = instance.data["asset"] + asset_name = instance.data["folderPath"] project_entity = instance.data["projectEntity"] project_name = project_entity["name"] diff --git a/client/ayon_core/plugins/publish/collect_from_create_context.py b/client/ayon_core/plugins/publish/collect_from_create_context.py index 66ca5745b2..7152446de8 100644 --- a/client/ayon_core/plugins/publish/collect_from_create_context.py +++ b/client/ayon_core/plugins/publish/collect_from_create_context.py @@ -38,7 +38,6 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): for created_instance in create_context.instances: instance_data = created_instance.data_to_store() - instance_data["asset"] = instance_data.pop("folderPath") if instance_data["active"]: thumbnail_path = thumbnail_paths_by_instance_id.get( created_instance.id @@ -80,7 +79,7 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): instance = context.create_instance(subset) instance.data.update({ "subset": subset, - "asset": in_data["asset"], + "folderPath": in_data["folderPath"], "task": in_data["task"], "label": in_data.get("label") or subset, "name": subset, diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 32f10ba4c8..d7077d030a 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -62,7 +62,7 @@ class CollectHierarchy(pyblish.api.ContextPlugin): "pixelAspect": instance.data["pixelAspect"] } # Split by '/' for AYON where asset is a path - name = instance.data["asset"].split("/")[-1] + name = instance.data["folderPath"].split("/")[-1] actual = {name: shot_data} for parent in reversed(instance.data["parents"]): diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index 9a316b69a4..fcea773208 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -71,14 +71,19 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): """ # validate basic necessary data data_err = "invalid json file - missing data" - required = ["asset", "user", "comment", + required = ["user", "comment", "job", "instances", "version"] assert all(elem in data.keys() for elem in required), data_err + if "folderPath" not in data and "asset" not in data: + raise AssertionError(data_err) + + if "folderPath" not in data: + data["folderPath"] = data.pop("asset") # set context by first json file ctx = self._context.data - ctx["asset"] = ctx.get("asset") or data.get("asset") + ctx["folderPath"] = ctx.get("folderPath") or data.get("folderPath") ctx["intent"] = ctx.get("intent") or data.get("intent") ctx["comment"] = ctx.get("comment") or data.get("comment") ctx["user"] = ctx.get("user") or data.get("user") @@ -87,7 +92,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): # basic sanity check to see if we are working in same context # if some other json file has different context, bail out. ctx_err = "inconsistent contexts in json files - %s" - assert ctx.get("asset") == data.get("asset"), ctx_err % "asset" + assert ctx.get("folderPath") == data.get("folderPath"), ctx_err % "folderPath" assert ctx.get("intent") == data.get("intent"), ctx_err % "intent" assert ctx.get("comment") == data.get("comment"), ctx_err % "comment" assert ctx.get("user") == data.get("user"), ctx_err % "user" diff --git a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py index 0851b28134..26e448cc6e 100644 --- a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py +++ b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py @@ -45,7 +45,7 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): continue # Skip if instance asset does not match - instance_asset_name = instance.data.get("asset") + instance_asset_name = instance.data.get("folderPath") instances_by_asset_name[instance_asset_name].append(instance) project_doc = context.data["projectEntity"] diff --git a/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py b/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py index c6bdb59f59..dd45f3fc1a 100644 --- a/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py +++ b/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py @@ -68,7 +68,7 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): def add_audio_to_instances(self, audio_file, instances): created_files = [] for inst in instances: - name = inst.data["asset"] + name = inst.data["folderPath"] recycling_file = [f for f in created_files if name in f] diff --git a/client/ayon_core/plugins/publish/integrate_thumbnail.py b/client/ayon_core/plugins/publish/integrate_thumbnail.py index dd3fdd5073..03bc8d2d3d 100644 --- a/client/ayon_core/plugins/publish/integrate_thumbnail.py +++ b/client/ayon_core/plugins/publish/integrate_thumbnail.py @@ -196,12 +196,13 @@ class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin): )) asset_entity = instance.data["assetEntity"] + folder_path = instance.data["folderPath"] thumbnail_info_by_entity_id[asset_entity["_id"]] = { "thumbnail_id": thumbnail_id, "entity_type": "asset", } - self.log.debug("Setting thumbnail for asset \"{}\" <{}>".format( - asset_entity["name"], version_id + self.log.debug("Setting thumbnail for folder \"{}\" <{}>".format( + folder_path, version_id )) op_session = OperationsSession() diff --git a/client/ayon_core/plugins/publish/validate_editorial_asset_name.py b/client/ayon_core/plugins/publish/validate_editorial_asset_name.py index d40263d7f3..dd1a19f602 100644 --- a/client/ayon_core/plugins/publish/validate_editorial_asset_name.py +++ b/client/ayon_core/plugins/publish/validate_editorial_asset_name.py @@ -113,7 +113,7 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): def get_parents(self, context): return_dict = {} for instance in context: - asset = instance.data["asset"] + asset = instance.data["folderPath"] families = instance.data.get("families", []) + [ instance.data["family"] ] diff --git a/client/ayon_core/plugins/publish/validate_unique_subsets.py b/client/ayon_core/plugins/publish/validate_unique_subsets.py index 75d12f8e01..5e0e90cff6 100644 --- a/client/ayon_core/plugins/publish/validate_unique_subsets.py +++ b/client/ayon_core/plugins/publish/validate_unique_subsets.py @@ -36,7 +36,7 @@ class ValidateSubsetUniqueness(pyblish.api.ContextPlugin): continue # Ignore instance without asset data - asset = instance.data.get("asset") + asset = instance.data.get("folderPath") if asset is None: self.log.warning("Instance found without `asset` data: " "{}".format(instance.name)) From ecba1daaa074a77fc81f21a5fc8d0f54e01657a9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 15:06:28 +0100 Subject: [PATCH 102/149] changed docstrings --- client/ayon_core/pipeline/create/README.md | 2 +- .../ayon_core/plugins/publish/collect_anatomy_instance_data.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/create/README.md b/client/ayon_core/pipeline/create/README.md index 012572a776..3858314a82 100644 --- a/client/ayon_core/pipeline/create/README.md +++ b/client/ayon_core/pipeline/create/README.md @@ -48,7 +48,7 @@ Family tells how should be instance processed and subset what name will publishe : {...}, ... }, - ## Additional data related to instance (`asset`, `task`, etc.) + ## Additional data related to instance (`folderPath`, `task`, etc.) ... } ``` diff --git a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py index 763aee5b1c..b33c438233 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py @@ -3,7 +3,7 @@ Requires: context -> anatomyData context -> projectEntity context -> assetEntity - instance -> asset + instance -> folderPath instance -> subset instance -> family From a8041e55f9daafb50a0229f70393eeb286741a39 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 15:58:18 +0100 Subject: [PATCH 103/149] moved 'usdlib.py' to pipeline --- .../houdini/plugins/publish/collect_instances_usd_layered.py | 2 +- .../hosts/houdini/plugins/publish/collect_usd_bootstrap.py | 2 +- client/ayon_core/{lib => pipeline}/usdlib.py | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename client/ayon_core/{lib => pipeline}/usdlib.py (100%) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py index 800d6fb883..ee259fb70d 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py @@ -2,7 +2,7 @@ import hou import pyblish.api from ayon_core.hosts.houdini.api import lib import ayon_core.hosts.houdini.api.usd as hou_usdlib -import ayon_core.lib.usdlib as usdlib +from ayon_core.pipeline import usdlib class CollectInstancesUsdLayered(pyblish.api.ContextPlugin): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py index ed54ad8bc1..7342c8f621 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py @@ -5,7 +5,7 @@ from ayon_core.client import ( get_asset_by_name, get_asset_name_identifier, ) -import ayon_core.lib.usdlib as usdlib +from ayon_core.pipeline import usdlib class CollectUsdBootstrap(pyblish.api.InstancePlugin): diff --git a/client/ayon_core/lib/usdlib.py b/client/ayon_core/pipeline/usdlib.py similarity index 100% rename from client/ayon_core/lib/usdlib.py rename to client/ayon_core/pipeline/usdlib.py From 4ab0591047f1b6c9029adc739eb1989b4e9bc850 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:08:52 +0100 Subject: [PATCH 104/149] fix used key in collect current context --- client/ayon_core/plugins/publish/collect_current_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_current_context.py b/client/ayon_core/plugins/publish/collect_current_context.py index 6a22daa04a..418ca8eff6 100644 --- a/client/ayon_core/plugins/publish/collect_current_context.py +++ b/client/ayon_core/plugins/publish/collect_current_context.py @@ -44,6 +44,6 @@ class CollectCurrentContext(pyblish.api.ContextPlugin): "Task: {task_name}" ).format( project_name=context.data["projectName"], - asset_name=context.data["asset"], + asset_name=context.data["folderPath"], task_name=context.data["task"] )) From d250405dd672d75af23b349d1226156e1c20fa59 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:29:20 +0100 Subject: [PATCH 105/149] don't use 'get_local_settings' in experimental tools --- client/ayon_core/tools/experimental_tools/tools_def.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/tools/experimental_tools/tools_def.py b/client/ayon_core/tools/experimental_tools/tools_def.py index be6762b239..305060978d 100644 --- a/client/ayon_core/tools/experimental_tools/tools_def.py +++ b/client/ayon_core/tools/experimental_tools/tools_def.py @@ -1,5 +1,4 @@ import os -from ayon_core.settings import get_local_settings # Constant key under which local settings are stored LOCAL_EXPERIMENTAL_KEY = "experimental_tools" @@ -151,7 +150,10 @@ class ExperimentalTools: def refresh_availability(self): """Reload local settings and check if any tool changed ability.""" - local_settings = get_local_settings() + + # NOTE AYON does not have implemented settings for experimental + # tools. + local_settings = {} experimental_settings = ( local_settings.get(LOCAL_EXPERIMENTAL_KEY) ) or {} From 21989f88dd6a1adeb3841e0f44ca33e3c855f35d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:29:39 +0100 Subject: [PATCH 106/149] don't use local settings in applications logic --- client/ayon_core/lib/applications.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 60ef2a6708..69da56a0da 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -16,7 +16,6 @@ from ayon_core.client import get_asset_name_identifier from ayon_core.settings import ( get_system_settings, get_project_settings, - get_local_settings ) from ayon_core.settings.constants import ( METADATA_KEYS, @@ -1528,16 +1527,17 @@ def prepare_app_environments( # Use environments from local settings filtered_local_envs = {} - system_settings = data["system_settings"] - whitelist_envs = system_settings["general"].get("local_env_white_list") - if whitelist_envs: - local_settings = get_local_settings() - local_envs = local_settings.get("environments") or {} - filtered_local_envs = { - key: value - for key, value in local_envs.items() - if key in whitelist_envs - } + # NOTE Overrides for environment variables are not implemented in AYON. + # system_settings = data["system_settings"] + # whitelist_envs = system_settings["general"].get("local_env_white_list") + # if whitelist_envs: + # local_settings = get_local_settings() + # local_envs = local_settings.get("environments") or {} + # filtered_local_envs = { + # key: value + # for key, value in local_envs.items() + # if key in whitelist_envs + # } # Apply local environment variables for already existing values for key, value in filtered_local_envs.items(): From f7790f14af0395f496d193796966ffa6cb6b2c72 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:30:01 +0100 Subject: [PATCH 107/149] do not add local settings to 'get_all_current_info' --- client/ayon_core/lib/ayon_info.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/ayon_core/lib/ayon_info.py b/client/ayon_core/lib/ayon_info.py index 97a35adcc6..ec37d735d8 100644 --- a/client/ayon_core/lib/ayon_info.py +++ b/client/ayon_core/lib/ayon_info.py @@ -5,7 +5,6 @@ import platform import getpass import socket -from ayon_core.settings.lib import get_local_settings from .execute import get_ayon_launcher_args from .local_settings import get_local_site_id @@ -96,7 +95,6 @@ def get_all_current_info(): return { "workstation": get_workstation_info(), "env": os.environ.copy(), - "local_settings": get_local_settings(), "ayon": get_ayon_info(), } From 02ecdb0ad19a399f6ee68f158c92ecce1c02757a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:31:20 +0100 Subject: [PATCH 108/149] don't use local settings in anatomy --- client/ayon_core/pipeline/anatomy.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/client/ayon_core/pipeline/anatomy.py b/client/ayon_core/pipeline/anatomy.py index 4864822aa1..e7833a9a15 100644 --- a/client/ayon_core/pipeline/anatomy.py +++ b/client/ayon_core/pipeline/anatomy.py @@ -8,9 +8,6 @@ import numbers import six import time -from ayon_core.settings.lib import ( - get_local_settings, -) from ayon_core.client import get_project, get_ayon_server_api_connection from ayon_core.lib import Logger, get_local_site_id from ayon_core.lib.path_templates import ( @@ -453,7 +450,7 @@ class Anatomy(BaseAnatomy): return cls._sync_server_addon_cache.data @classmethod - def _get_studio_roots_overrides(cls, project_name, local_settings=None): + def _get_studio_roots_overrides(cls, project_name): """This would return 'studio' site override by local settings. Notes: @@ -465,7 +462,6 @@ class Anatomy(BaseAnatomy): Args: project_name (str): Name of project. - local_settings (Optional[dict[str, Any]]): Prepared local settings. Returns: Union[Dict[str, str], None]): Local root overrides. @@ -488,11 +484,6 @@ class Anatomy(BaseAnatomy): should be returned. """ - # Local settings may be used more than once or may not be used at all - # - to avoid slowdowns 'get_local_settings' is not called until it's - # really needed - local_settings = None - # First check if sync server is available and enabled sync_server = cls.get_sync_server_addon() if sync_server is None or not sync_server.enabled: @@ -503,11 +494,8 @@ class Anatomy(BaseAnatomy): # Use sync server to receive active site name project_cache = cls._default_site_id_cache[project_name] if project_cache.is_outdated: - local_settings = get_local_settings() project_cache.update_data( - sync_server.get_active_site_type( - project_name, local_settings - ) + sync_server.get_active_site_type(project_name) ) site_name = project_cache.data @@ -517,12 +505,12 @@ class Anatomy(BaseAnatomy): # Handle studio root overrides without sync server # - studio root overrides can be done even without sync server roots_overrides = cls._get_studio_roots_overrides( - project_name, local_settings + project_name ) else: # Ask sync server to get roots overrides roots_overrides = sync_server.get_site_root_overrides( - project_name, site_name, local_settings + project_name, site_name ) site_cache.update_data(roots_overrides) return site_cache.data From 5224125b3af8310b212926fb0de98258633989f9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:32:15 +0100 Subject: [PATCH 109/149] removed 'get_local_settings' function --- client/ayon_core/settings/__init__.py | 2 -- client/ayon_core/settings/lib.py | 5 ----- 2 files changed, 7 deletions(-) diff --git a/client/ayon_core/settings/__init__.py b/client/ayon_core/settings/__init__.py index f0e5c95efe..074dbf8d03 100644 --- a/client/ayon_core/settings/__init__.py +++ b/client/ayon_core/settings/__init__.py @@ -7,7 +7,6 @@ from .lib import ( get_system_settings, get_project_settings, get_current_project_settings, - get_local_settings, ) from .ayon_settings import get_ayon_settings @@ -20,7 +19,6 @@ __all__ = ( "get_system_settings", "get_project_settings", "get_current_project_settings", - "get_local_settings", "get_ayon_settings", ) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 4dff7768f7..1508516c71 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -48,11 +48,6 @@ def clear_metadata_from_settings(values): clear_metadata_from_settings(item) -def get_local_settings(): - # TODO implement ayon implementation - return {} - - def load_openpype_default_settings(): """Load openpype default settings.""" return load_jsons_from_dir(DEFAULTS_DIR) From 4c1ac5a4f022fe1f5fd89c6f1e9402b4639e5668 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:32:28 +0100 Subject: [PATCH 110/149] cleared 'get_site_local_overrides' and added warning --- client/ayon_core/settings/lib.py | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 1508516c71..8e358396c4 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -198,39 +198,17 @@ def merge_overrides(source_dict, override_dict): def get_site_local_overrides(project_name, site_name, local_settings=None): """Site overrides from local settings for passet project and site name. + Warning: + This function is not implemented for AYON. + Args: project_name (str): For which project are overrides. site_name (str): For which site are overrides needed. local_settings (dict): Preloaded local settings. They are loaded automatically if not passed. """ - # Check if local settings were passed - if local_settings is None: - local_settings = get_local_settings() - output = {} - - # Skip if local settings are empty - if not local_settings: - return output - - local_project_settings = local_settings.get("projects") or {} - - # Prepare overrides for entered project and for default project - project_locals = None - if project_name: - project_locals = local_project_settings.get(project_name) - default_project_locals = local_project_settings.get(DEFAULT_PROJECT_KEY) - - # First load and use local settings from default project - if default_project_locals and site_name in default_project_locals: - output.update(default_project_locals[site_name]) - - # Apply project specific local settings if there are any - if project_locals and site_name in project_locals: - output.update(project_locals[site_name]) - - return output + return {} def get_current_project_settings(): From eb07f945a56440a5e3b5d402a56a0ee9745fe5bd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:34:33 +0100 Subject: [PATCH 111/149] added comment to dirmap implementation --- client/ayon_core/host/dirmap.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/ayon_core/host/dirmap.py b/client/ayon_core/host/dirmap.py index 9756657386..effafb6261 100644 --- a/client/ayon_core/host/dirmap.py +++ b/client/ayon_core/host/dirmap.py @@ -181,6 +181,10 @@ class HostDirmap(object): exclude_locals=False, cached=False) + # TODO implement + # Dirmap is dependent on 'get_site_local_overrides' which + # is not implemented in AYON. The mapping should be received + # from sitesync addon. active_overrides = get_site_local_overrides( project_name, active_site) remote_overrides = get_site_local_overrides( From d10d860623c7c15f3c403016382f7e52c4d2fd56 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:44:30 +0100 Subject: [PATCH 112/149] reduced filtering hosts for publisher as experimental tool --- client/ayon_core/tools/experimental_tools/tools_def.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/tools/experimental_tools/tools_def.py b/client/ayon_core/tools/experimental_tools/tools_def.py index be6762b239..716a45c3a0 100644 --- a/client/ayon_core/tools/experimental_tools/tools_def.py +++ b/client/ayon_core/tools/experimental_tools/tools_def.py @@ -89,9 +89,13 @@ class ExperimentalTools: "New publisher", "Combined creation and publishing into one tool.", self._show_publisher, - hosts_filter=["blender", "maya", "nuke", "celaction", "flame", - "fusion", "harmony", "hiero", "resolve", - "tvpaint", "unreal"] + hosts_filter=[ + "celaction", + "flame", + "harmony", + "hiero", + "resolve", + ] ) ] From cd9a240296205699e1911f0049516c9d3562f910 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 16 Feb 2024 16:07:16 +0000 Subject: [PATCH 113/149] Remove redundant code --- .../plugins/publish/submit_publish_job.py | 145 ------------------ 1 file changed, 145 deletions(-) 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 d4d04f79f6..4023846817 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 @@ -330,151 +330,6 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, self.log.debug("Skipping local instance.") return - data = instance.data.copy() - context = instance.context - self.context = context - self.anatomy = instance.context.data["anatomy"] - - asset = data.get("asset") or context.data["asset"] - subset = data.get("subset") - - start = instance.data.get("frameStart") - if start is None: - start = context.data["frameStart"] - - end = instance.data.get("frameEnd") - if end is None: - end = context.data["frameEnd"] - - handle_start = instance.data.get("handleStart") - if handle_start is None: - handle_start = context.data["handleStart"] - - handle_end = instance.data.get("handleEnd") - if handle_end is None: - handle_end = context.data["handleEnd"] - - fps = instance.data.get("fps") - if fps is None: - fps = context.data["fps"] - - if data.get("extendFrames", False): - start, end = self._extend_frames( - asset, - subset, - start, - end, - data["overrideExistingFrame"]) - - try: - source = data["source"] - except KeyError: - source = context.data["currentFile"] - - success, rootless_path = ( - self.anatomy.find_root_template_from_path(source) - ) - if success: - source = rootless_path - - else: - # `rootless_path` is not set to `source` if none of roots match - self.log.warning(( - "Could not find root path for remapping \"{}\"." - " This may cause issues." - ).format(source)) - - family = "render" - if ("prerender" in instance.data["families"] or - "prerender.farm" in instance.data["families"]): - family = "prerender" - families = [family] - - # pass review to families if marked as review - do_not_add_review = False - if data.get("review"): - families.append("review") - elif data.get("review") is False: - self.log.debug("Instance has review explicitly disabled.") - do_not_add_review = True - - instance_skeleton_data = { - "family": family, - "subset": subset, - "families": families, - "asset": asset, - "frameStart": start, - "frameEnd": end, - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStartHandle": start - handle_start, - "frameEndHandle": end + handle_end, - "comment": instance.data["comment"], - "fps": fps, - "source": source, - "extendFrames": data.get("extendFrames"), - "overrideExistingFrame": data.get("overrideExistingFrame"), - "pixelAspect": data.get("pixelAspect", 1), - "resolutionWidth": data.get("resolutionWidth", 1920), - "resolutionHeight": data.get("resolutionHeight", 1080), - "multipartExr": data.get("multipartExr", False), - "jobBatchName": data.get("jobBatchName", ""), - "useSequenceForReview": data.get("useSequenceForReview", True), - # map inputVersions `ObjectId` -> `str` so json supports it - "inputVersions": list(map(str, data.get("inputVersions", []))), - "colorspace": instance.data.get("colorspace"), - "stagingDir_persistent": instance.data.get( - "stagingDir_persistent", False - ) - } - - # skip locking version if we are creating v01 - instance_version = instance.data.get("version") # take this if exists - if instance_version != 1: - instance_skeleton_data["version"] = instance_version - - # transfer specific families from original instance to new render - for item in self.families_transfer: - if item in instance.data.get("families", []): - instance_skeleton_data["families"] += [item] - - # transfer specific properties from original instance based on - # mapping dictionary `instance_transfer` - for key, values in self.instance_transfer.items(): - if key in instance.data.get("families", []): - for v in values: - instance_skeleton_data[v] = instance.data.get(v) - - # look into instance data if representations are not having any - # which are having tag `publish_on_farm` and include them - for repre in instance.data.get("representations", []): - staging_dir = repre.get("stagingDir") - if staging_dir: - success, rootless_staging_dir = ( - self.anatomy.find_root_template_from_path( - staging_dir - ) - ) - if success: - repre["stagingDir"] = rootless_staging_dir - else: - self.log.warning(( - "Could not find root path for remapping \"{}\"." - " This may cause issues on farm." - ).format(staging_dir)) - repre["stagingDir"] = staging_dir - - if "publish_on_farm" in repre.get("tags"): - # create representations attribute of not there - if "representations" not in instance_skeleton_data.keys(): - instance_skeleton_data["representations"] = [] - - instance_skeleton_data["representations"].append(repre) - - instances = None - assert data.get("expectedFiles"), ("Submission from old Pype version" - " - missing expectedFiles") - anatomy = instance.context.data["anatomy"] instance_skeleton_data = create_skeleton_instance( From f5fb7308e0cafdb3f5d9af538cf9bb93cf1707f1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 17:13:21 +0100 Subject: [PATCH 114/149] use 'folderPath' in hosts --- .../hosts/aftereffects/plugins/publish/collect_render.py | 6 +++--- .../hosts/aftereffects/plugins/publish/collect_workfile.py | 4 ++-- .../plugins/publish/validate_instance_asset.py | 4 ++-- .../hosts/blender/plugins/create/create_action.py | 4 +++- .../plugins/publish/collect_celaction_instances.py | 2 +- .../hosts/flame/plugins/publish/collect_timeline_otio.py | 4 ++-- .../flame/plugins/publish/extract_subset_resources.py | 4 ++-- .../hosts/flame/plugins/publish/integrate_batch_group.py | 4 ++-- .../hosts/fusion/plugins/publish/collect_render.py | 2 +- .../hosts/fusion/plugins/publish/extract_render_local.py | 2 +- .../fusion/plugins/publish/validate_unique_subsets.py | 4 +++- .../hosts/harmony/plugins/publish/collect_farm_render.py | 4 ++-- .../hosts/harmony/plugins/publish/collect_palettes.py | 4 ++-- .../hosts/harmony/plugins/publish/collect_workfile.py | 2 +- .../hosts/harmony/plugins/publish/validate_instances.py | 5 +++-- .../hosts/hiero/plugins/publish/collect_clip_effects.py | 4 ++-- .../hiero/plugins/publish/collect_frame_tag_instances.py | 6 +++--- .../hosts/hiero/plugins/publish/extract_clip_effects.py | 2 +- .../hosts/hiero/plugins/publish/precollect_instances.py | 7 +++---- .../hosts/hiero/plugins/publish/precollect_workfile.py | 2 +- .../hosts/houdini/plugins/publish/collect_instances.py | 2 +- .../ayon_core/hosts/max/plugins/publish/collect_render.py | 2 +- .../hosts/max/plugins/publish/collect_workfile.py | 2 +- client/ayon_core/hosts/maya/api/action.py | 4 ++-- .../hosts/maya/plugins/publish/validate_model_name.py | 4 ++-- .../hosts/nuke/plugins/publish/validate_asset_context.py | 6 +++--- client/ayon_core/hosts/photoshop/api/ws_stub.py | 4 ++-- .../hosts/photoshop/plugins/publish/collect_auto_image.py | 4 ++-- .../hosts/photoshop/plugins/publish/collect_auto_review.py | 4 ++-- .../photoshop/plugins/publish/collect_auto_workfile.py | 4 ++-- .../hosts/photoshop/plugins/publish/collect_batch_data.py | 4 ++-- .../plugins/publish/collect_color_coded_instances.py | 4 ++-- .../photoshop/plugins/publish/validate_instance_asset.py | 4 ++-- client/ayon_core/hosts/resolve/api/lib.py | 2 +- .../hosts/resolve/plugins/publish/precollect_instances.py | 6 +++--- .../hosts/resolve/plugins/publish/precollect_workfile.py | 2 +- .../plugins/publish/collect_textureset_images.py | 4 ++-- .../hosts/tvpaint/plugins/publish/collect_workfile_data.py | 4 ++-- .../hosts/tvpaint/plugins/publish/validate_asset_name.py | 6 +++--- .../unreal/plugins/publish/collect_render_instances.py | 2 +- 40 files changed, 77 insertions(+), 73 deletions(-) diff --git a/client/ayon_core/hosts/aftereffects/plugins/publish/collect_render.py b/client/ayon_core/hosts/aftereffects/plugins/publish/collect_render.py index a8a316ea80..32e3b4f3c3 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/aftereffects/plugins/publish/collect_render.py @@ -98,7 +98,7 @@ class CollectAERender(publish.AbstractCollectRender): source=current_file, label="{} - {}".format(subset_name, family), subset=subset_name, - asset=inst.data["asset"], + folderPath=inst.data["folderPath"], task=task_name, attachTo=False, setMembers='', @@ -175,7 +175,7 @@ class CollectAERender(publish.AbstractCollectRender): version_str = "v{:03d}".format(render_instance.version) if "#" not in file_name: # single frame (mov)W path = os.path.join(base_dir, "{}_{}_{}.{}".format( - render_instance.asset, + render_instance.folderPath, render_instance.subset, version_str, ext @@ -184,7 +184,7 @@ class CollectAERender(publish.AbstractCollectRender): else: for frame in range(start, end + 1): path = os.path.join(base_dir, "{}_{}_{}.{}.{}".format( - render_instance.asset, + render_instance.folderPath, render_instance.subset, version_str, str(frame).zfill(self.padding_width), diff --git a/client/ayon_core/hosts/aftereffects/plugins/publish/collect_workfile.py b/client/ayon_core/hosts/aftereffects/plugins/publish/collect_workfile.py index 538d646ab4..107643f56c 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/publish/collect_workfile.py +++ b/client/ayon_core/hosts/aftereffects/plugins/publish/collect_workfile.py @@ -50,11 +50,11 @@ class CollectWorkfile(pyblish.api.ContextPlugin): asset_entity = context.data["assetEntity"] project_entity = context.data["projectEntity"] - asset_name = get_asset_name_identifier(asset_entity) + folder_path = get_asset_name_identifier(asset_entity) instance_data = { "active": True, - "asset": asset_name, + "folderPath": folder_path, "task": task, "frameStart": context.data['frameStart'], "frameEnd": context.data['frameEnd'], diff --git a/client/ayon_core/hosts/aftereffects/plugins/publish/validate_instance_asset.py b/client/ayon_core/hosts/aftereffects/plugins/publish/validate_instance_asset.py index c3938ecbda..e8f2e29a2f 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/publish/validate_instance_asset.py +++ b/client/ayon_core/hosts/aftereffects/plugins/publish/validate_instance_asset.py @@ -30,7 +30,7 @@ class ValidateInstanceAssetRepair(pyblish.api.Action): for instance in instances: data = stub.read(instance[0]) - data["asset"] = get_current_asset_name() + data["folderPath"] = get_current_asset_name() stub.imprint(instance[0].instance_id, data) @@ -53,7 +53,7 @@ class ValidateInstanceAsset(pyblish.api.InstancePlugin): order = ValidateContentsOrder def process(self, instance): - instance_asset = instance.data["asset"] + instance_asset = instance.data["folderPath"] current_asset = get_current_asset_name() msg = ( f"Instance asset {instance_asset} is not the same " diff --git a/client/ayon_core/hosts/blender/plugins/create/create_action.py b/client/ayon_core/hosts/blender/plugins/create/create_action.py index 2331daf7b7..82047fb5c6 100644 --- a/client/ayon_core/hosts/blender/plugins/create/create_action.py +++ b/client/ayon_core/hosts/blender/plugins/create/create_action.py @@ -22,7 +22,9 @@ class CreateAction(plugin.BaseCreator): ) # Get instance name - name = plugin.prepare_scene_name(instance_data["asset"], subset_name) + name = plugin.prepare_scene_name( + instance_data["folderPath"], subset_name + ) if pre_create_data.get("use_selection"): for obj in lib.get_selection(): diff --git a/client/ayon_core/hosts/celaction/plugins/publish/collect_celaction_instances.py b/client/ayon_core/hosts/celaction/plugins/publish/collect_celaction_instances.py index d0f4c59290..ef471dbd05 100644 --- a/client/ayon_core/hosts/celaction/plugins/publish/collect_celaction_instances.py +++ b/client/ayon_core/hosts/celaction/plugins/publish/collect_celaction_instances.py @@ -22,7 +22,7 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): asset_name = get_asset_name_identifier(asset_entity) shared_instance_data = { - "asset": asset_name, + "folderPath": asset_name, "frameStart": asset_entity["data"]["frameStart"], "frameEnd": asset_entity["data"]["frameEnd"], "handleStart": asset_entity["data"]["handleStart"], diff --git a/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_otio.py b/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_otio.py index 6a3e99aa55..2fcfb55e7c 100644 --- a/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_otio.py +++ b/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_otio.py @@ -34,7 +34,7 @@ class CollecTimelineOTIO(pyblish.api.ContextPlugin): project_settings=context.data["project_settings"] ) - asset_name = get_asset_name_identifier(asset_doc) + folder_path = get_asset_name_identifier(asset_doc) # adding otio timeline to context with opfapi.maintained_segment_selection(sequence) as selected_seg: @@ -42,7 +42,7 @@ class CollecTimelineOTIO(pyblish.api.ContextPlugin): instance_data = { "name": subset_name, - "asset": asset_name, + "folderPath": folder_path, "subset": subset_name, "family": "workfile", "families": [] diff --git a/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py b/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py index 9e55dbce96..cae08cd76b 100644 --- a/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py @@ -55,7 +55,7 @@ class ExtractProductResources(publish.Extractor): # flame objects segment = instance.data["item"] - asset_name = instance.data["asset"] + folder_path = instance.data["folderPath"] segment_name = segment.name.get_value() clip_path = instance.data["path"] sequence_clip = instance.context.data["flameSequence"] @@ -249,7 +249,7 @@ class ExtractProductResources(publish.Extractor): out_mark = in_mark + source_duration_handles exporting_clip = self.import_clip(clip_path) exporting_clip.name.set_value("{}_{}".format( - asset_name, segment_name)) + folder_path, segment_name)) # add xml tags modifications modify_xml_data.update({ diff --git a/client/ayon_core/hosts/flame/plugins/publish/integrate_batch_group.py b/client/ayon_core/hosts/flame/plugins/publish/integrate_batch_group.py index 3458bd3002..e36d2a22d5 100644 --- a/client/ayon_core/hosts/flame/plugins/publish/integrate_batch_group.py +++ b/client/ayon_core/hosts/flame/plugins/publish/integrate_batch_group.py @@ -168,10 +168,10 @@ class IntegrateBatchGroup(pyblish.api.InstancePlugin): handle_start = instance.data["handleStart"] handle_end = instance.data["handleEnd"] frame_duration = (frame_end - frame_start) + 1 - asset_name = instance.data["asset"] + folder_path = instance.data["folderPath"] task_name = task_data["name"] - batchgroup_name = "{}_{}".format(asset_name, task_name) + batchgroup_name = "{}_{}".format(folder_path, task_name) batch_data = { "shematic_reels": [ diff --git a/client/ayon_core/hosts/fusion/plugins/publish/collect_render.py b/client/ayon_core/hosts/fusion/plugins/publish/collect_render.py index f8870da1c5..0a0e4b38af 100644 --- a/client/ayon_core/hosts/fusion/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/fusion/plugins/publish/collect_render.py @@ -68,7 +68,7 @@ class CollectFusionRender( source=current_file, label=inst.data["label"], subset=subset_name, - asset=inst.data["asset"], + folderPath=inst.data["folderPath"], task=task_name, attachTo=False, setMembers='', diff --git a/client/ayon_core/hosts/fusion/plugins/publish/extract_render_local.py b/client/ayon_core/hosts/fusion/plugins/publish/extract_render_local.py index eea232ac29..23a8cdb8a0 100644 --- a/client/ayon_core/hosts/fusion/plugins/publish/extract_render_local.py +++ b/client/ayon_core/hosts/fusion/plugins/publish/extract_render_local.py @@ -72,7 +72,7 @@ class FusionRenderLocal( self.log.info( "Rendered '{nm}' for asset '{ast}' under the task '{tsk}'".format( nm=instance.data["name"], - ast=instance.data["asset"], + ast=instance.data["folderPath"], tsk=instance.data["task"], ) ) diff --git a/client/ayon_core/hosts/fusion/plugins/publish/validate_unique_subsets.py b/client/ayon_core/hosts/fusion/plugins/publish/validate_unique_subsets.py index 619b52077e..3131400de9 100644 --- a/client/ayon_core/hosts/fusion/plugins/publish/validate_unique_subsets.py +++ b/client/ayon_core/hosts/fusion/plugins/publish/validate_unique_subsets.py @@ -21,7 +21,9 @@ class ValidateUniqueSubsets(pyblish.api.ContextPlugin): # Collect instances per subset per asset instances_per_subset_asset = defaultdict(lambda: defaultdict(list)) for instance in context: - asset = instance.data.get("asset", context.data.get("asset")) + asset = instance.data.get( + "folderPath", context.data.get("folderPath") + ) subset = instance.data.get("subset", context.data.get("subset")) instances_per_subset_asset[asset][subset].append(instance) diff --git a/client/ayon_core/hosts/harmony/plugins/publish/collect_farm_render.py b/client/ayon_core/hosts/harmony/plugins/publish/collect_farm_render.py index faeff7bddd..6a9c349185 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/collect_farm_render.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/collect_farm_render.py @@ -98,7 +98,7 @@ class CollectFarmRender(publish.AbstractCollectRender): self_name = self.__class__.__name__ - asset_name = context.data["asset"] + folder_path = context.data["folderPath"] for node in context.data["allNodes"]: data = harmony.read(node) @@ -142,7 +142,7 @@ class CollectFarmRender(publish.AbstractCollectRender): source=context.data["currentFile"], label=node.split("/")[1], subset=subset_name, - asset=asset_name, + folderPath=folder_path, task=task_name, attachTo=False, setMembers=[node], diff --git a/client/ayon_core/hosts/harmony/plugins/publish/collect_palettes.py b/client/ayon_core/hosts/harmony/plugins/publish/collect_palettes.py index 9343fab86d..66b1ee6085 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/collect_palettes.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/collect_palettes.py @@ -31,7 +31,7 @@ class CollectPalettes(pyblish.api.ContextPlugin): if (not any([re.search(pattern, task_name) for pattern in self.allowed_tasks])): return - asset_name = context.data["asset"] + folder_path = context.data["folderPath"] for name, id in palettes.items(): instance = context.create_instance(name) @@ -39,7 +39,7 @@ class CollectPalettes(pyblish.api.ContextPlugin): "id": id, "family": "harmony.palette", 'families': [], - "asset": asset_name, + "folderPath": folder_path, "subset": "{}{}".format("palette", name) }) self.log.info( diff --git a/client/ayon_core/hosts/harmony/plugins/publish/collect_workfile.py b/client/ayon_core/hosts/harmony/plugins/publish/collect_workfile.py index 4be2a0fc26..1ea1f15124 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/collect_workfile.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/collect_workfile.py @@ -36,5 +36,5 @@ class CollectWorkfile(pyblish.api.ContextPlugin): "family": family, "families": [family], "representations": [], - "asset": context.data["asset"] + "folderPath": context.data["folderPath"] }) diff --git a/client/ayon_core/hosts/harmony/plugins/publish/validate_instances.py b/client/ayon_core/hosts/harmony/plugins/publish/validate_instances.py index a57a863d6f..fdba834de6 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/validate_instances.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/validate_instances.py @@ -27,9 +27,10 @@ class ValidateInstanceRepair(pyblish.api.Action): # Apply pyblish.logic to get the instances for the plug-in instances = pyblish.api.instances_by_plugin(failed, plugin) + folder_path = get_current_asset_name() for instance in instances: data = harmony.read(instance.data["setMembers"][0]) - data["asset"] = get_current_asset_name() + data["folderPath"] = folder_path harmony.imprint(instance.data["setMembers"][0], data) @@ -42,7 +43,7 @@ class ValidateInstance(pyblish.api.InstancePlugin): order = ValidateContentsOrder def process(self, instance): - instance_asset = instance.data["asset"] + instance_asset = instance.data["folderPath"] current_asset = get_current_asset_name() msg = ( "Instance asset is not the same as current asset:" diff --git a/client/ayon_core/hosts/hiero/plugins/publish/collect_clip_effects.py b/client/ayon_core/hosts/hiero/plugins/publish/collect_clip_effects.py index d7f646ebc9..3bd5b88942 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/collect_clip_effects.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/collect_clip_effects.py @@ -118,9 +118,9 @@ class CollectClipEffects(pyblish.api.InstancePlugin): data["subset"] = name data["family"] = family data["families"] = [family] - data["name"] = data["subset"] + "_" + data["asset"] + data["name"] = data["subset"] + "_" + data["folderPath"] data["label"] = "{} - {}".format( - data['asset'], data["subset"] + data["folderPath"], data["subset"] ) data["effects"] = effects diff --git a/client/ayon_core/hosts/hiero/plugins/publish/collect_frame_tag_instances.py b/client/ayon_core/hosts/hiero/plugins/publish/collect_frame_tag_instances.py index b981d89eef..6f99e6be29 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/collect_frame_tag_instances.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/collect_frame_tag_instances.py @@ -102,7 +102,7 @@ class CollectFrameTagInstances(pyblish.api.ContextPlugin): # first collect all available subset tag frames subset_data = {} context_asset_doc = context.data["assetEntity"] - context_asset_name = get_asset_name_identifier(context_asset_doc) + context_folder_path = get_asset_name_identifier(context_asset_doc) for tag_data in sequence_tags: frame = int(tag_data["start"]) @@ -120,7 +120,7 @@ class CollectFrameTagInstances(pyblish.api.ContextPlugin): subset_data[subset] = { "frames": [frame], "format": tag_data["format"], - "asset": context_asset_name + "folderPath": context_folder_path } return subset_data @@ -133,7 +133,7 @@ class CollectFrameTagInstances(pyblish.api.ContextPlugin): "label": "{} {}".format(name, subset_data["frames"]), "family": "image", "families": ["frame"], - "asset": subset_data["asset"], + "folderPath": subset_data["folderPath"], "subset": name, "format": subset_data["format"], "frames": subset_data["frames"] diff --git a/client/ayon_core/hosts/hiero/plugins/publish/extract_clip_effects.py b/client/ayon_core/hosts/hiero/plugins/publish/extract_clip_effects.py index afff41fc74..d1edfed0d7 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/extract_clip_effects.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/extract_clip_effects.py @@ -57,7 +57,7 @@ class ExtractClipEffects(publish.Extractor): "sourceStart", "sourceStartH", "sourceEnd", "sourceEndH", "frameStart", "frameEnd", "clipIn", "clipOut", "clipInH", "clipOutH", - "asset", "version" + "folderPath", "version" ] # pass data to version diff --git a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py index e41ca74320..4142d2f403 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py @@ -98,7 +98,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): data.update({ "name": "{}_{}".format(asset, subset), "label": label, - "asset": asset, + "folderPath": asset, "asset_name": asset_name, "item": track_item, "families": families, @@ -189,7 +189,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not hierarchy_data: return - asset = data["asset"] + asset = data["folderPath"] asset_name = data["asset_name"] # insert family into families @@ -241,7 +241,6 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not master_layer: return - asset = data.get("asset") item = data.get("item") clip_name = item.name() @@ -249,7 +248,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not self.test_any_audio(item): return - asset = data["asset"] + asset = data["folferPath"] asset_name = data["asset_name"] # insert family into families diff --git a/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py b/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py index e9e2aae653..2925e723b8 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py @@ -17,7 +17,7 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder - 0.491 def process(self, context): - asset = context.data["asset"] + asset = context.data["folderPath"] asset_name = asset.split("/")[-1] active_timeline = hiero.ui.activeSequence() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py index 2780da95d9..b445397b18 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py @@ -72,7 +72,7 @@ class CollectInstances(pyblish.api.ContextPlugin): # Create nice name if the instance has a frame range. label = data.get("name", node.name()) - label += " (%s)" % data["asset"] # include asset in name + label += " (%s)" % data["folderPath"] # include folder in name instance = context.create_instance(label) diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_render.py b/client/ayon_core/hosts/max/plugins/publish/collect_render.py index a97e8a154e..66226e24fa 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_render.py @@ -94,7 +94,7 @@ class CollectRender(pyblish.api.InstancePlugin): renderer = str(renderer_class).split(":")[0] # also need to get the render dir for conversion data = { - "asset": instance.data["asset"], + "folderPath": instance.data["folderPath"], "subset": str(instance.name), "publish": True, "maxversion": str(get_max_version()), diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py index 0eb4bb731e..f5d4ba475d 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py @@ -35,7 +35,7 @@ class CollectWorkfile(pyblish.api.ContextPlugin): data.update({ "subset": subset, - "asset": context.data["asset"], + "folderPath": context.data["folderPath"], "label": subset, "publish": True, "family": 'workfile', diff --git a/client/ayon_core/hosts/maya/api/action.py b/client/ayon_core/hosts/maya/api/action.py index 1edca82ee4..4beb1e3e5b 100644 --- a/client/ayon_core/hosts/maya/api/action.py +++ b/client/ayon_core/hosts/maya/api/action.py @@ -15,7 +15,7 @@ class GenerateUUIDsOnInvalidAction(pyblish.api.Action): receive new UUIDs are actually invalid. Requires: - - instance.data["asset"] + - instance.data["folderPath"] """ @@ -78,7 +78,7 @@ class GenerateUUIDsOnInvalidAction(pyblish.api.Action): # should be always available, but kept a way to query it by name. asset_doc = instance.data.get("assetEntity") if not asset_doc: - asset_name = instance.data["asset"] + asset_name = instance.data["folderPath"] project_name = instance.context.data["projectName"] self.log.info(( "Asset is not stored on instance." diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py index cf2bbcd77c..673cfd0d29 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py @@ -67,14 +67,14 @@ class ValidateModelName(pyblish.api.InstancePlugin, r = re.compile(regex) m = r.match(top_group) project_name = instance.context.data["projectName"] - current_asset_name = instance.context.data["asset"] + current_folder_path = instance.context.data["folderPath"] if m is None: cls.log.error("invalid name on: {}".format(top_group)) cls.log.error("name doesn't match regex {}".format(regex)) invalid.append(top_group) else: if "asset" in r.groupindex: - if m.group("asset") != current_asset_name: + if m.group("folderPath") != current_folder_path: cls.log.error("Invalid asset name in top level group.") return top_group if "subset" in r.groupindex: diff --git a/client/ayon_core/hosts/nuke/plugins/publish/validate_asset_context.py b/client/ayon_core/hosts/nuke/plugins/publish/validate_asset_context.py index b4814c6a00..52ef4a58d4 100644 --- a/client/ayon_core/hosts/nuke/plugins/publish/validate_asset_context.py +++ b/client/ayon_core/hosts/nuke/plugins/publish/validate_asset_context.py @@ -23,10 +23,10 @@ class ValidateCorrectAssetContext( current asset (shot). This validator checks if this is so. It is optional so it can be disabled when needed. - Checking `asset` and `task` keys. + Checking `folderPath` and `task` keys. """ order = ValidateContentsOrder - label = "Validate asset context" + label = "Validate Folder context" hosts = ["nuke"] actions = [ RepairAction, @@ -85,7 +85,7 @@ class ValidateCorrectAssetContext( """Get invalid keys from instance data and context data.""" invalid_keys = [] - testing_keys = ["asset", "task"] + testing_keys = ["folderPath", "task"] for _key in testing_keys: if _key not in instance.data: invalid_keys.append(_key) diff --git a/client/ayon_core/hosts/photoshop/api/ws_stub.py b/client/ayon_core/hosts/photoshop/api/ws_stub.py index 42bad05f26..8f9d3a876b 100644 --- a/client/ayon_core/hosts/photoshop/api/ws_stub.py +++ b/client/ayon_core/hosts/photoshop/api/ws_stub.py @@ -120,7 +120,7 @@ class PhotoshopServerStub: "subset":"imageBG", "family":"image", "id":"pyblish.avalon.instance", - "asset":"Town", + "folderPath":"Town", "uuid": "8" }] - for created instances OR @@ -421,7 +421,7 @@ class PhotoshopServerStub: example: {"8":{"active":true,"subset":"imageBG", "family":"image","id":"pyblish.avalon.instance", - "asset":"Town"}} + "folderPath":"Town"}} 8 is layer(group) id - used for deletion, update etc. """ res = self.websocketserver.call(self.client.call('Photoshop.read')) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_image.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_image.py index 051a3da0a1..479d9139af 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_image.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_image.py @@ -28,7 +28,7 @@ class CollectAutoImage(pyblish.api.ContextPlugin): task_name = context.data["task"] host_name = context.data["hostName"] asset_doc = context.data["assetEntity"] - asset_name = get_asset_name_identifier(asset_doc) + folder_path = get_asset_name_identifier(asset_doc) auto_creator = proj_settings.get( "photoshop", {}).get( @@ -86,7 +86,7 @@ class CollectAutoImage(pyblish.api.ContextPlugin): instance = context.create_instance(subset_name) instance.data["family"] = family - instance.data["asset"] = asset_name + instance.data["folderPath"] = folder_path instance.data["subset"] = subset_name instance.data["ids"] = publishable_ids instance.data["publish"] = True diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_review.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_review.py index c8d4ddf111..e31508e641 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_review.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_review.py @@ -67,7 +67,7 @@ class CollectAutoReview(pyblish.api.ContextPlugin): host_name = context.data["hostName"] asset_doc = context.data["assetEntity"] - asset_name = get_asset_name_identifier(asset_doc) + folder_path = get_asset_name_identifier(asset_doc) subset_name = get_subset_name( family, @@ -87,7 +87,7 @@ class CollectAutoReview(pyblish.api.ContextPlugin): "family": family, "families": [], "representations": [], - "asset": asset_name, + "folderPath": folder_path, "publish": self.publish }) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_workfile.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_workfile.py index 365fd0a684..12fc31a2f2 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_workfile.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_auto_workfile.py @@ -71,7 +71,7 @@ class CollectAutoWorkfile(pyblish.api.ContextPlugin): host_name = context.data["hostName"] asset_doc = context.data["assetEntity"] - asset_name = get_asset_name_identifier(asset_doc) + folder_path = get_asset_name_identifier(asset_doc) subset_name = get_subset_name( family, variant, @@ -91,7 +91,7 @@ class CollectAutoWorkfile(pyblish.api.ContextPlugin): "family": family, "families": [], "representations": [], - "asset": asset_name + "folderPath": folder_path }) # creating representation diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py index 464b6e3999..a32b5f8fa5 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py @@ -2,7 +2,7 @@ Provides: context -> Loaded batch file. - - asset + - folderPath - task (task name) - taskType - project_name @@ -71,7 +71,7 @@ class CollectBatchData(pyblish.api.ContextPlugin): os.environ["AYON_FOLDER_PATH"] = asset_name os.environ["AYON_TASK_NAME"] = task_name - context.data["asset"] = asset_name + context.data["folderPath"] = asset_name context.data["task"] = task_name context.data["taskType"] = task_type context.data["project_name"] = project_name diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py index 6a09cff3c7..35538279eb 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py @@ -56,7 +56,7 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin): existing_subset_names = self._get_existing_subset_names(context) # from CollectBatchData - asset_name = context.data["asset"] + asset_name = context.data["folderPath"] task_name = context.data["task"] variant = context.data["variant"] project_name = context.data["projectEntity"]["name"] @@ -163,7 +163,7 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin): instance = context.create_instance(layer.name) instance.data["family"] = family instance.data["publish"] = True - instance.data["asset"] = asset + instance.data["folderPath"] = asset instance.data["task"] = task_name instance.data["subset"] = subset instance.data["layer"] = layer diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/validate_instance_asset.py b/client/ayon_core/hosts/photoshop/plugins/publish/validate_instance_asset.py index dc0f2efd52..67a7303316 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/validate_instance_asset.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/validate_instance_asset.py @@ -31,7 +31,7 @@ class ValidateInstanceAssetRepair(pyblish.api.Action): current_asset_name = get_current_asset_name() for instance in instances: data = stub.read(instance[0]) - data["asset"] = current_asset_name + data["folderPath"] = current_asset_name stub.imprint(instance[0], data) @@ -54,7 +54,7 @@ class ValidateInstanceAsset(OptionalPyblishPluginMixin, order = ValidateContentsOrder def process(self, instance): - instance_asset = instance.data["asset"] + instance_asset = instance.data["folderPath"] current_asset = get_current_asset_name() if instance_asset != current_asset: diff --git a/client/ayon_core/hosts/resolve/api/lib.py b/client/ayon_core/hosts/resolve/api/lib.py index 2c648bb4cc..5eb88afdcb 100644 --- a/client/ayon_core/hosts/resolve/api/lib.py +++ b/client/ayon_core/hosts/resolve/api/lib.py @@ -519,7 +519,7 @@ def imprint(timeline_item, data=None): Examples: data = { - 'asset': 'sq020sh0280', + 'folderPath': 'sq020sh0280', 'family': 'render', 'subset': 'subsetMain' } diff --git a/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py b/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py index 0ae6206496..c288d1bf99 100644 --- a/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py +++ b/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py @@ -66,7 +66,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): data.update({ "name": "{}_{}".format(asset, subset), "label": "{} {}".format(asset, subset), - "asset": asset, + "folderPath": asset, "item": timeline_item, "publish": get_publish_attribute(timeline_item), "fps": context.data["fps"], @@ -124,7 +124,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not hierarchy_data: return - asset = data["asset"] + asset = data["folderPath"] subset = "shotMain" # insert family into families @@ -134,7 +134,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): "name": "{}_{}".format(asset, subset), "label": "{} {}".format(asset, subset), "subset": subset, - "asset": asset, + "folderPath": asset, "family": family, "families": [], "publish": get_publish_attribute(timeline_item) diff --git a/client/ayon_core/hosts/resolve/plugins/publish/precollect_workfile.py b/client/ayon_core/hosts/resolve/plugins/publish/precollect_workfile.py index 5f8cf6b5d9..814b1e159f 100644 --- a/client/ayon_core/hosts/resolve/plugins/publish/precollect_workfile.py +++ b/client/ayon_core/hosts/resolve/plugins/publish/precollect_workfile.py @@ -28,7 +28,7 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): instance_data = { "name": "{}_{}".format(asset_name, subset), "label": "{} {}".format(current_asset_name, subset), - "asset": current_asset_name, + "folderPath": current_asset_name, "subset": subset, "item": project, "family": "workfile", diff --git a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py index b8279c99cd..03e17192d2 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py +++ b/client/ayon_core/hosts/substancepainter/plugins/publish/collect_textureset_images.py @@ -27,8 +27,8 @@ class CollectTextureSet(pyblish.api.InstancePlugin): config = self.get_export_config(instance) asset_doc = get_asset_by_name( - project_name=instance.context.data["projectName"], - asset_name=instance.data["asset"] + instance.context.data["projectName"], + instance.data["folderPath"] ) instance.data["exportConfig"] = config diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py index a6b6f05dc9..1cf21a1fae 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py @@ -65,7 +65,7 @@ class CollectWorkfileData(pyblish.api.ContextPlugin): # Collect and store current context to have reference current_context = { "project_name": context.data["projectName"], - "asset_name": context.data["asset"], + "asset_name": context.data["folderPath"], "task_name": context.data["task"] } self.log.debug("Current context is: {}".format(current_context)) @@ -105,7 +105,7 @@ class CollectWorkfileData(pyblish.api.ContextPlugin): )) # Store context asset name - context.data["asset"] = asset_name + context.data["folderPath"] = asset_name context.data["task"] = task_name self.log.info( "Context is set to Asset: \"{}\" and Task: \"{}\"".format( diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/validate_asset_name.py b/client/ayon_core/hosts/tvpaint/plugins/publish/validate_asset_name.py index 62603a460b..927d601e34 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/validate_asset_name.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/validate_asset_name.py @@ -20,7 +20,7 @@ class FixAssetNames(pyblish.api.Action): on = "failed" def process(self, context, plugin): - context_asset_name = context.data["asset"] + context_asset_name = context.data["folderPath"] old_instance_items = list_instances() new_instance_items = [] for instance_item in old_instance_items: @@ -51,9 +51,9 @@ class ValidateAssetName( def process(self, context): if not self.is_active(context.data): return - context_asset_name = context.data["asset"] + context_asset_name = context.data["folderPath"] for instance in context: - asset_name = instance.data.get("asset") + asset_name = instance.data.get("folderPath") if asset_name and asset_name == context_asset_name: continue diff --git a/client/ayon_core/hosts/unreal/plugins/publish/collect_render_instances.py b/client/ayon_core/hosts/unreal/plugins/publish/collect_render_instances.py index 8641094610..8bbf5a5c62 100644 --- a/client/ayon_core/hosts/unreal/plugins/publish/collect_render_instances.py +++ b/client/ayon_core/hosts/unreal/plugins/publish/collect_render_instances.py @@ -64,7 +64,7 @@ class CollectRenderInstances(pyblish.api.InstancePlugin): new_data = new_instance.data - new_data["asset"] = seq_name + new_data["folderPath"] = seq_name new_data["setMembers"] = seq_name new_data["family"] = "render" new_data["families"] = ["render", "review"] From eaf6e0dfdb192fc2a5833631c4df29fd79347b1e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 17:14:53 +0100 Subject: [PATCH 115/149] fix collect anatomy instance data --- .../ayon_core/plugins/publish/collect_anatomy_instance_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py index b33c438233..f6326bb9e8 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py @@ -68,7 +68,7 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): instances_with_missing_asset_doc = collections.defaultdict(list) for instance in context: instance_asset_doc = instance.data.get("assetEntity") - _asset_name = instance.data["asset"] + _asset_name = instance.data["folderPath"] # There is possibility that assetEntity on instance is already set # which can happen in standalone publisher From 47f51af6e1207d085ca96edb8363a62afc877be0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 17:20:08 +0100 Subject: [PATCH 116/149] fix precollect workfile in hiero --- .../hosts/hiero/plugins/publish/precollect_workfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py b/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py index 2925e723b8..15dd0dee26 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/precollect_workfile.py @@ -64,7 +64,7 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): "label": "{} - {}Main".format( asset, family), "name": "{}_{}".format(asset_name, family), - "asset": context.data["asset"], + "folderPath": context.data["folderPath"], # TODO use 'get_subset_name' "subset": "{}{}Main".format(asset_name, family.capitalize()), "item": project, From f9a70bc7699dce3e92c609cc0453e12af55fe57c Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 19 Feb 2024 09:09:16 +0000 Subject: [PATCH 117/149] Fix exposed knobs validator --- .../hosts/nuke/plugins/publish/validate_exposed_knobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py b/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py index 9111bcdc2c..c047347481 100644 --- a/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py +++ b/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py @@ -65,7 +65,7 @@ class ValidateExposedKnobs( group_node = instance.data["transientData"]["node"] nuke_settings = instance.context.data["project_settings"]["nuke"] create_settings = nuke_settings["create"][plugin] - exposed_knobs = create_settings["exposed_knobs"] + exposed_knobs = create_settings.get("exposed_knobs", []) unexposed_knobs = [] for knob in exposed_knobs: if knob not in group_node.knobs(): From 25ead9ee87ad2b7e1ec32192441aef96054a5965 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 19 Feb 2024 09:11:59 +0000 Subject: [PATCH 118/149] Fix exposed write knobs --- client/ayon_core/hosts/nuke/api/plugin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/api/plugin.py b/client/ayon_core/hosts/nuke/api/plugin.py index 4b8ddac167..af7b6d5b2f 100644 --- a/client/ayon_core/hosts/nuke/api/plugin.py +++ b/client/ayon_core/hosts/nuke/api/plugin.py @@ -1348,7 +1348,9 @@ def _remove_old_knobs(node): def exposed_write_knobs(settings, plugin_name, instance_node): - exposed_knobs = settings["nuke"]["create"][plugin_name]["exposed_knobs"] + exposed_knobs = settings["nuke"]["create"][plugin_name].get( + "exposed_knobs", [] + ) if exposed_knobs: instance_node.addKnob(nuke.Text_Knob('', 'Write Knobs')) write_node = nuke.allNodes(group=instance_node, filter="Write")[0] From 2cbbe4b3bcbb5033fbc905691febbf719d12fff8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 10:26:40 +0100 Subject: [PATCH 119/149] file maya collectors --- client/ayon_core/hosts/maya/plugins/publish/collect_render.py | 2 +- .../ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index 4ea91ccb0d..d5392fba4a 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -307,7 +307,7 @@ class CollectMayaRender(pyblish.api.InstancePlugin): _instance.data["version"] = context.data["version"] # Define nice label - label = "{0} ({1})".format(layer_name, instance.data["asset"]) + label = "{0} ({1})".format(layer_name, instance.data["folderPath"]) label += " [{0}-{1}]".format( int(data["frameStartHandle"]), int(data["frameEndHandle"]) ) diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py b/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py index db008cc2be..979f49f7fe 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py @@ -99,7 +99,7 @@ class CollectVrayScene(pyblish.api.InstancePlugin): instance.data.update(data) # Define nice label - label = "{0} ({1})".format(layer_name, instance.data["asset"]) + label = "{0} ({1})".format(layer_name, instance.data["folderPath"]) label += " [{0}-{1}]".format( int(data["frameStartHandle"]), int(data["frameEndHandle"]) ) From 9c22294717ae2df2615f4c3baf28d6c3ee561c92 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 10:28:21 +0100 Subject: [PATCH 120/149] fix another maya plugins --- .../maya/plugins/publish/extract_unreal_skeletalmesh_fbx.py | 2 +- .../maya/plugins/publish/validate_instance_in_context.py | 4 ++-- .../hosts/maya/plugins/publish/validate_shader_name.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_skeletalmesh_fbx.py b/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_skeletalmesh_fbx.py index 7b44c92194..edbb5f845e 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_skeletalmesh_fbx.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_skeletalmesh_fbx.py @@ -61,7 +61,7 @@ class ExtractUnrealSkeletalMeshFbx(publish.Extractor): # we rely on hierarchy under one root. original_parent = to_extract[0].split("|")[1] - parent_node = instance.data.get("asset") + parent_node = instance.data.get("folderPath") # this needs to be done for AYON # WARNING: since AYON supports duplicity of asset names, # this needs to be refactored throughout the pipeline. diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_instance_in_context.py b/client/ayon_core/hosts/maya/plugins/publish/validate_instance_in_context.py index c683c1b30f..43b4f06e3f 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_instance_in_context.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_instance_in_context.py @@ -37,7 +37,7 @@ class ValidateInstanceInContext(pyblish.api.InstancePlugin, if not self.is_active(instance.data): return - asset = instance.data.get("asset") + asset = instance.data.get("folderPath") context_asset = self.get_context_asset(instance) if asset != context_asset: raise PublishValidationError( @@ -74,4 +74,4 @@ class ValidateInstanceInContext(pyblish.api.InstancePlugin, @staticmethod def get_context_asset(instance): - return instance.context.data["asset"] + return instance.context.data["folderPath"] diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_shader_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_shader_name.py index cb7f975535..86ca0ca400 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_shader_name.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_shader_name.py @@ -51,7 +51,7 @@ class ValidateShaderName(pyblish.api.InstancePlugin, descendants = cmds.ls(descendants, noIntermediate=True, long=True) shapes = cmds.ls(descendants, type=["nurbsSurface", "mesh"], long=True) - asset_name = instance.data.get("asset") + asset_name = instance.data.get("folderPath") # Check the number of connected shadingEngines per shape regex_compile = re.compile(cls.regex) From 4f09e30e204d639032b869c2722e1b22af3c8f57 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 10:42:20 +0100 Subject: [PATCH 121/149] removed debug log --- client/ayon_core/plugins/publish/extract_burnin.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 499a72bd4f..d189e36a99 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -113,9 +113,6 @@ class ExtractBurnin(publish.Extractor): ) burnin_defs = copy.deepcopy(src_burnin_defs) - self.log.debug( - "burnin_defs.keys(): {}".format(burnin_defs.keys()) - ) # Filter output definition by `burnin` represetation key repre_linked_burnins = [ From c45a4245361f7e6ff72fea57d792e04470a0a9d5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 10:58:35 +0100 Subject: [PATCH 122/149] add docstring --- client/ayon_core/plugins/publish/extract_burnin.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index d189e36a99..88670928f2 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -96,6 +96,17 @@ class ExtractBurnin(publish.Extractor): instance.data["representations"].remove(repre) def _get_burnins_per_representations(self, instance, src_burnin_defs): + """ + + Args: + instance (pyblish.api.Instance): Pyblish instance. + src_burnin_defs (list): Burnin definitions. + + Returns: + list[tuple[dict, list]]: List of tuples containing representation + and its burnin definitions. + + """ self.log.debug( "Filtering of representations and their burnins starts" ) From 17e9a0a4a62eb57111163ada47bae20c7c3195dc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 13:49:31 +0100 Subject: [PATCH 123/149] remove 'ObjectId' usage --- .../publish/collect_input_representations_to_versions.py | 2 -- client/ayon_core/plugins/publish/integrate.py | 2 -- client/ayon_core/tools/push_to_project/models/integrate.py | 3 --- 3 files changed, 7 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py b/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py index b5c9872e74..6caee1be6a 100644 --- a/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py +++ b/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py @@ -1,7 +1,5 @@ import pyblish.api -from bson.objectid import ObjectId - from ayon_core.client import get_representations diff --git a/client/ayon_core/plugins/publish/integrate.py b/client/ayon_core/plugins/publish/integrate.py index a67c837daf..a502031595 100644 --- a/client/ayon_core/plugins/publish/integrate.py +++ b/client/ayon_core/plugins/publish/integrate.py @@ -6,7 +6,6 @@ import datetime import clique import six -from bson.objectid import ObjectId import pyblish.api from ayon_core.client.operations import ( @@ -988,7 +987,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin): """ return { - "_id": ObjectId(), "path": self.get_rootless_path(anatomy, path), "size": os.path.getsize(path), "hash": source_hash(path), 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 175716cf10..3de1beb2d2 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -8,8 +8,6 @@ import sys import traceback import uuid -from bson.objectid import ObjectId - from ayon_core.client import ( get_project, get_assets, @@ -1080,7 +1078,6 @@ class ProjectPushItemProcess: new_repre_files = [] for (path, rootless_path) in repre_filepaths: new_repre_files.append({ - "_id": ObjectId(), "path": rootless_path, "size": os.path.getsize(path), "hash": source_hash(path), From b5cecb728cc4fcacb49b419c03f295aa69d95980 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 15:37:31 +0100 Subject: [PATCH 124/149] fix burnin defs --- client/ayon_core/plugins/publish/extract_burnin.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 88670928f2..edba7d6d8a 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -773,10 +773,13 @@ class ExtractBurnin(publish.Extractor): continue # Burnin values + new_burnin_def = {} burnin_values = {} for key, value in tuple(burnin_def.items()): key_low = key.lower() - if key_low in self.positions and value: + if key_low not in self.positions: + new_burnin_def[key] = value + elif value: burnin_values[key_low] = value # Skip processing if burnin values are not set @@ -788,9 +791,9 @@ class ExtractBurnin(publish.Extractor): ).format(filename_suffix, str(orig_burnin_def))) continue - burnin_values["filter"] = def_filter + new_burnin_def.update(burnin_values) - filtered_burnin_defs.append(burnin_values) + filtered_burnin_defs.append(new_burnin_def) self.log.debug(( "Burnin definition \"{}\" passed first filtering." From afb0a966a2539a14ca1e13db9b242ba04f578671 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 16:33:23 +0100 Subject: [PATCH 125/149] fix integrate product group --- client/ayon_core/plugins/publish/integrate_product_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/integrate_product_group.py b/client/ayon_core/plugins/publish/integrate_product_group.py index f7c96893ca..82646ed733 100644 --- a/client/ayon_core/plugins/publish/integrate_product_group.py +++ b/client/ayon_core/plugins/publish/integrate_product_group.py @@ -58,7 +58,7 @@ class IntegrateProductGroup(pyblish.api.InstancePlugin): template = profile["template"] fill_pairs = prepare_template_data({ - "family": filter_criteria["families"], + "family": filter_criteria["product_types"], "task": filter_criteria["tasks"], "host": filter_criteria["hosts"], "subset": instance.data["subset"], From 76ffe5742b7792d01c6d6b54c1444464c5322617 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 16:58:32 +0100 Subject: [PATCH 126/149] fix extract review --- client/ayon_core/plugins/publish/extract_review.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index b0bc94c317..927c8a3538 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1280,14 +1280,11 @@ class ExtractReview(pyblish.api.InstancePlugin): "FFprobe couldn't read resolution from input file: \"{}\"" ).format(full_input_path_single_file)) - # NOTE Setting only one of `width` or `heigth` is not allowed + # NOTE Setting only one of `width` or `height` is not allowed # - settings value can't have None but has value of 0 - output_width = ( - output_def.get("output_width") or output_width or None - ) - output_height = ( - output_def.get("output_height") or output_height or None - ) + output_width = output_def["width"] or output_width or None + output_height = output_def["height"] or output_height or None + # Force to use input resolution if output resolution was not defined # in settings. Resolution from instance is not used when # 'use_input_res' is set to 'True'. From 940e8a4cc7794ad079b6ae336149d06e689e597a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:46:30 +0100 Subject: [PATCH 127/149] Change warning to deprecation and modify message --- client/ayon_core/settings/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 8e358396c4..4dde488d6c 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -198,8 +198,8 @@ def merge_overrides(source_dict, override_dict): def get_site_local_overrides(project_name, site_name, local_settings=None): """Site overrides from local settings for passet project and site name. - Warning: - This function is not implemented for AYON. + Deprecated: + This function is not implemented for AYON and will be removed. Args: project_name (str): For which project are overrides. From e382bb101d9e30acfbcfb9f5db228d1b9d8d7d46 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:55:29 +0100 Subject: [PATCH 128/149] removed shader definition editor --- .../maya/api/shader_definition_editor.py | 176 ------------------ 1 file changed, 176 deletions(-) delete mode 100644 client/ayon_core/hosts/maya/api/shader_definition_editor.py diff --git a/client/ayon_core/hosts/maya/api/shader_definition_editor.py b/client/ayon_core/hosts/maya/api/shader_definition_editor.py deleted file mode 100644 index bfa531eb87..0000000000 --- a/client/ayon_core/hosts/maya/api/shader_definition_editor.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -"""Editor for shader definitions. - -Shader names are stored as simple text file over GridFS in mongodb. - -""" -import os -from qtpy import QtWidgets, QtCore, QtGui -from ayon_core.client.mongo import OpenPypeMongoConnection -from ayon_core import resources -import gridfs - - -DEFINITION_FILENAME = "{}/maya/shader_definition.txt".format( - os.getenv("AYON_PROJECT_NAME")) - - -class ShaderDefinitionsEditor(QtWidgets.QWidget): - """Widget serving as simple editor for shader name definitions.""" - - # name of the file used to store definitions - - def __init__(self, parent=None): - super(ShaderDefinitionsEditor, self).__init__(parent) - self._mongo = OpenPypeMongoConnection.get_mongo_client() - self._gridfs = gridfs.GridFS( - self._mongo[os.getenv("OPENPYPE_DATABASE_NAME")]) - self._editor = None - - self._original_content = self._read_definition_file() - - self.setObjectName("shaderDefinitionEditor") - self.setWindowTitle("OpenPype shader name definition editor") - icon = QtGui.QIcon(resources.get_ayon_icon_filepath()) - self.setWindowIcon(icon) - self.setWindowFlags(QtCore.Qt.Window) - self.setParent(parent) - self.setAttribute(QtCore.Qt.WA_DeleteOnClose) - self.resize(750, 500) - - self._setup_ui() - self._reload() - - def _setup_ui(self): - """Setup UI of Widget.""" - layout = QtWidgets.QVBoxLayout(self) - label = QtWidgets.QLabel() - label.setText("Put shader names here - one name per line:") - layout.addWidget(label) - self._editor = QtWidgets.QPlainTextEdit() - self._editor.setStyleSheet("border: none;") - layout.addWidget(self._editor) - - btn_layout = QtWidgets.QHBoxLayout() - save_btn = QtWidgets.QPushButton("Save") - save_btn.clicked.connect(self._save) - - reload_btn = QtWidgets.QPushButton("Reload") - reload_btn.clicked.connect(self._reload) - - exit_btn = QtWidgets.QPushButton("Exit") - exit_btn.clicked.connect(self._close) - - btn_layout.addWidget(reload_btn) - btn_layout.addWidget(save_btn) - btn_layout.addWidget(exit_btn) - - layout.addLayout(btn_layout) - - def _read_definition_file(self, file=None): - """Read definition file from database. - - Args: - file (gridfs.grid_file.GridOut, Optional): File to read. If not - set, new query will be issued to find it. - - Returns: - str: Content of the file or empty string if file doesn't exist. - - """ - content = "" - if not file: - file = self._gridfs.find_one( - {"filename": DEFINITION_FILENAME}) - if not file: - print(">>> [SNDE]: nothing in database yet") - return content - content = file.read() - file.close() - return content - - def _write_definition_file(self, content, force=False): - """Write content as definition to file in database. - - Before file is written, check is made if its content has not - changed. If is changed, warning is issued to user if he wants - it to overwrite. Note: GridFs doesn't allow changing file content. - You need to delete existing file and create new one. - - Args: - content (str): Content to write. - - Raises: - ContentException: If file is changed in database while - editor is running. - """ - file = self._gridfs.find_one( - {"filename": DEFINITION_FILENAME}) - if file: - content_check = self._read_definition_file(file) - if content == content_check: - print(">>> [SNDE]: content not changed") - return - if self._original_content != content_check: - if not force: - raise ContentException("Content changed") - print(">>> [SNDE]: overwriting data") - file.close() - self._gridfs.delete(file._id) - - file = self._gridfs.new_file( - filename=DEFINITION_FILENAME, - content_type='text/plain', - encoding='utf-8') - file.write(content) - file.close() - QtCore.QTimer.singleShot(200, self._reset_style) - self._editor.setStyleSheet("border: 1px solid #33AF65;") - self._original_content = content - - def _reset_style(self): - """Reset editor style back. - - Used to visually indicate save. - - """ - self._editor.setStyleSheet("border: none;") - - def _close(self): - self.hide() - - def closeEvent(self, event): - event.ignore() - self.hide() - - def _reload(self): - print(">>> [SNDE]: reloading") - self._set_content(self._read_definition_file()) - - def _save(self): - try: - self._write_definition_file(content=self._editor.toPlainText()) - except ContentException: - # content has changed meanwhile - print(">>> [SNDE]: content has changed") - self._show_overwrite_warning() - - def _set_content(self, content): - self._editor.setPlainText(content) - - def _show_overwrite_warning(self): - reply = QtWidgets.QMessageBox.question( - self, - "Warning", - ("Content you are editing was changed meanwhile in database.\n" - "Please, reload and solve the conflict."), - QtWidgets.QMessageBox.OK) - - if reply == QtWidgets.QMessageBox.OK: - # do nothing - pass - - -class ContentException(Exception): - """This is risen during save if file is changed in database.""" - pass From 0a9acb834ff1b445c5bc46e8fbf9749cfd332993 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:56:59 +0100 Subject: [PATCH 129/149] modified ValidateModelName plugin --- .../plugins/publish/validate_model_name.py | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py index cf2bbcd77c..0d27965971 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py @@ -4,16 +4,15 @@ import os import platform import re -import gridfs import pyblish.api from maya import cmds import ayon_core.hosts.maya.api.action -from ayon_core.client.mongo import OpenPypeMongoConnection -from ayon_core.hosts.maya.api.shader_definition_editor import ( - DEFINITION_FILENAME) from ayon_core.pipeline.publish import ( - OptionalPyblishPluginMixin, PublishValidationError, ValidateContentsOrder) + OptionalPyblishPluginMixin, + PublishValidationError, + ValidateContentsOrder, +) class ValidateModelName(pyblish.api.InstancePlugin, @@ -31,13 +30,16 @@ class ValidateModelName(pyblish.api.InstancePlugin, families = ["model"] label = "Model Name" actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] - material_file = None - database_file = DEFINITION_FILENAME + + material_file = { + "windows": None, + "darwin": None, + "linux": None, + } @classmethod def get_invalid(cls, instance): """Get invalid nodes.""" - use_db = cls.database def is_group(group_name): """Find out if supplied transform is group or not.""" @@ -98,25 +100,15 @@ class ValidateModelName(pyblish.api.InstancePlugin, # load shader list file as utf-8 shaders = [] - if not use_db: - material_file = cls.material_file[platform.system().lower()] - if material_file: - if os.path.isfile(material_file): - shader_file = open(material_file, "r") - shaders = shader_file.readlines() - shader_file.close() - else: - cls.log.error("Missing shader name definition file.") - return True + material_file = cls.material_file[platform.system().lower()] + if material_file: + if os.path.isfile(material_file): + shader_file = open(material_file, "r") + shaders = shader_file.readlines() + shader_file.close() else: - client = OpenPypeMongoConnection.get_mongo_client() - fs = gridfs.GridFS(client[os.getenv("OPENPYPE_DATABASE_NAME")]) - shader_file = fs.find_one({"filename": cls.database_file}) - if not shader_file: - cls.log.error("Missing shader name definition in database.") - return True - shaders = shader_file.read().splitlines() - shader_file.close() + cls.log.error("Missing shader name definition file.") + return True # strip line endings from list shaders = [s.rstrip() for s in shaders if s.rstrip()] From f53b12605e34ee1ca2cd91a707932eb44a95a7a0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:57:12 +0100 Subject: [PATCH 130/149] removed unused function 'edit_shader_definitions' --- client/ayon_core/hosts/maya/api/commands.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/commands.py b/client/ayon_core/hosts/maya/api/commands.py index b52d5e6c2d..f69dca97a8 100644 --- a/client/ayon_core/hosts/maya/api/commands.py +++ b/client/ayon_core/hosts/maya/api/commands.py @@ -38,25 +38,6 @@ class ToolWindows: cls._windows[tool] = window -def edit_shader_definitions(): - from qtpy import QtWidgets - from ayon_core.hosts.maya.api.shader_definition_editor import ( - ShaderDefinitionsEditor - ) - from ayon_core.tools.utils import qt_app_context - - top_level_widgets = QtWidgets.QApplication.topLevelWidgets() - main_window = next(widget for widget in top_level_widgets - if widget.objectName() == "MayaWindow") - - with qt_app_context(): - window = ToolWindows.get_window("shader_definition_editor") - if not window: - window = ShaderDefinitionsEditor(parent=main_window) - ToolWindows.set_window("shader_definition_editor", window) - window.show() - - def _resolution_from_document(doc): if not doc or "data" not in doc: print("Entered document is not valid. \"{}\"".format(str(doc))) From 73637ae363583fb2ae343982bf589d56c1339178 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 18:06:00 +0100 Subject: [PATCH 131/149] removed plugins and script related to maya remote publish --- .../publish/collect_publishable_instances.py | 39 ------ .../submit_maya_remote_publish_deadline.py | 131 ------------------ client/ayon_core/scripts/remote_publish.py | 12 -- 3 files changed, 182 deletions(-) delete mode 100644 client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py delete mode 100644 client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py delete mode 100644 client/ayon_core/scripts/remote_publish.py diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py b/client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py deleted file mode 100644 index 347da86360..0000000000 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -"""Collect instances that should be processed and published on DL. - -""" -import os - -import pyblish.api -from ayon_core.pipeline import PublishValidationError - - -class CollectDeadlinePublishableInstances(pyblish.api.InstancePlugin): - """Collect instances that should be processed and published on DL. - - Some long running publishes (not just renders) could be offloaded to DL, - this plugin compares theirs name against env variable, marks only - publishable by farm. - - Triggered only when running only in headless mode, eg on a farm. - """ - - order = pyblish.api.CollectorOrder + 0.499 - label = "Collect Deadline Publishable Instance" - targets = ["remote"] - - def process(self, instance): - self.log.debug("CollectDeadlinePublishableInstances") - publish_inst = os.environ.get("OPENPYPE_PUBLISH_SUBSET", '') - if not publish_inst: - raise PublishValidationError("OPENPYPE_PUBLISH_SUBSET env var " - "required for remote publishing") - - subset_name = instance.data["subset"] - if subset_name == publish_inst: - self.log.debug("Publish {}".format(subset_name)) - instance.data["publish"] = True - instance.data["farm"] = False - else: - self.log.debug("Skipping {}".format(subset_name)) - instance.data["publish"] = False diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py deleted file mode 100644 index 1042c44c33..0000000000 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ /dev/null @@ -1,131 +0,0 @@ -import os -import attr -from datetime import datetime - -from ayon_core.pipeline import PublishXmlValidationError -from ayon_core.lib import is_in_tests -from openpype_modules.deadline import abstract_submit_deadline -from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo - -import pyblish.api - - -@attr.s -class MayaPluginInfo(object): - Build = attr.ib(default=None) # Don't force build - StrictErrorChecking = attr.ib(default=True) - - SceneFile = attr.ib(default=None) # Input scene - Version = attr.ib(default=None) # Mandatory for Deadline - ProjectPath = attr.ib(default=None) - - ScriptJob = attr.ib(default=True) - ScriptFilename = attr.ib(default=None) - - -class MayaSubmitRemotePublishDeadline( - abstract_submit_deadline.AbstractSubmitDeadline): - """Submit Maya scene to perform a local publish in Deadline. - - Publishing in Deadline can be helpful for scenes that publish very slow. - This way it can process in the background on another machine without the - Artist having to wait for the publish to finish on their local machine. - - Submission is done through the Deadline Web Service. DL then triggers - `openpype/scripts/remote_publish.py`. - - Each publishable instance creates its own full publish job. - - Different from `ProcessSubmittedJobOnFarm` which creates publish job - depending on metadata json containing context and instance data of - rendered files. - """ - - label = "Submit Scene to Deadline" - order = pyblish.api.IntegratorOrder - hosts = ["maya"] - families = ["publish.farm"] - targets = ["local"] - - def process(self, instance): - - # Ensure no errors so far - if not (all(result["success"] - for result in instance.context.data["results"])): - raise PublishXmlValidationError("Publish process has errors") - - if not instance.data["publish"]: - self.log.warning("No active instances found. " - "Skipping submission..") - return - - super(MayaSubmitRemotePublishDeadline, self).process(instance) - - def get_job_info(self): - instance = self._instance - context = instance.context - - project_name = instance.context.data["projectName"] - scene = instance.context.data["currentFile"] - scenename = os.path.basename(scene) - - job_name = "{scene} [PUBLISH]".format(scene=scenename) - batch_name = "{code} - {scene}".format(code=project_name, - scene=scenename) - - if is_in_tests(): - batch_name += datetime.now().strftime("%d%m%Y%H%M%S") - - job_info = DeadlineJobInfo(Plugin="MayaBatch") - job_info.BatchName = batch_name - job_info.Name = job_name - job_info.UserName = context.data.get("user") - job_info.Comment = context.data.get("comment", "") - - # use setting for publish job on farm, no reason to have it separately - project_settings = context.data["project_settings"] - deadline_publish_job_sett = project_settings["deadline"]["publish"]["ProcessSubmittedJobOnFarm"] # noqa - job_info.Department = deadline_publish_job_sett["deadline_department"] - job_info.ChunkSize = deadline_publish_job_sett["deadline_chunk_size"] - job_info.Priority = deadline_publish_job_sett["deadline_priority"] - job_info.Group = deadline_publish_job_sett["deadline_group"] - job_info.Pool = deadline_publish_job_sett["deadline_pool"] - - # Include critical environment variables with submission + Session - keys = [ - "FTRACK_API_USER", - "FTRACK_API_KEY", - "FTRACK_SERVER" - ] - - environment = { - key: os.environ[key] - for key in keys - if key in os.environ - } - - environment["AYON_PROJECT_NAME"] = project_name - environment["AYON_FOLDER_PATH"] = instance.context.data["asset"] - environment["AYON_TASK_NAME"] = instance.context.data["task"] - environment["AYON_APP_NAME"] = os.environ.get("AYON_APP_NAME") - environment["OPENPYPE_PUBLISH_SUBSET"] = instance.data["subset"] - environment["AYON_LOG_NO_COLORS"] = "1" - environment["AYON_USERNAME"] = instance.context.data["user"] - environment["AYON_REMOTE_PUBLISH"] = "1" - - for key, value in environment.items(): - job_info.EnvironmentKeyValue[key] = value - - def get_plugin_info(self): - # Not all hosts can import this module. - from maya import cmds - scene = self._instance.context.data["currentFile"] - - plugin_info = MayaPluginInfo() - plugin_info.SceneFile = scene - plugin_info.ScriptFilename = "{OPENPYPE_REPOS_ROOT}/openpype/scripts/remote_publish.py" # noqa - plugin_info.Version = cmds.about(version=True) - plugin_info.ProjectPath = cmds.workspace(query=True, - rootDirectory=True) - - return attr.asdict(plugin_info) diff --git a/client/ayon_core/scripts/remote_publish.py b/client/ayon_core/scripts/remote_publish.py deleted file mode 100644 index 7e7bf2493b..0000000000 --- a/client/ayon_core/scripts/remote_publish.py +++ /dev/null @@ -1,12 +0,0 @@ -try: - from ayon_core.lib import Logger - from ayon_core.pipeline.publish.lib import remote_publish -except ImportError as exc: - # Ensure Deadline fails by output an error that contains "Fatal Error:" - raise ImportError("Fatal Error: %s" % exc) - - -if __name__ == "__main__": - # Perform remote publish with thorough error checking - log = Logger.get_logger(__name__) - remote_publish(log) From 5bb00e43717c1d736875a94aad668efb183c3cfd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 18:06:16 +0100 Subject: [PATCH 132/149] removed 'remote_publish' function from publish lib --- client/ayon_core/pipeline/publish/lib.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 90725e6d79..7d980b4bbe 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -485,26 +485,6 @@ def filter_pyblish_plugins(plugins): plugins.remove(plugin) -def remote_publish(log): - """Loops through all plugins, logs to console. Used for tests. - - Args: - log (Logger) - """ - - # Error exit as soon as any error occurs. - error_format = "Failed {plugin.__name__}: {error}\n{error.traceback}" - - for result in pyblish.util.publish_iter(): - if not result["error"]: - continue - - error_message = error_format.format(**result) - log.error(error_message) - # 'Fatal Error: ' is because of Deadline - raise RuntimeError("Fatal Error: {}".format(error_message)) - - def get_errored_instances_from_context(context, plugin=None): """Collect failed instances from pyblish context. From 14ba402c164018fe09cab7e20772c103ddd6a78b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 11:09:41 +0100 Subject: [PATCH 133/149] fix forgotten places --- .../hosts/houdini/plugins/publish/collect_usd_bootstrap.py | 2 +- .../hosts/houdini/plugins/publish/collect_usd_layers.py | 2 +- .../houdini/plugins/publish/validate_usd_shade_model_exists.py | 2 +- .../traypublisher/plugins/publish/collect_shot_instances.py | 2 +- .../traypublisher/plugins/publish/validate_existing_version.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py index ed54ad8bc1..0fb269516c 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py @@ -55,7 +55,7 @@ class CollectUsdBootstrap(pyblish.api.InstancePlugin): self.log.debug("Add bootstrap for: %s" % bootstrap) project_name = instance.context.data["projectName"] - asset_name = instance.data["asset"] + asset_name = instance.data["folderPath"] asset_doc = get_asset_by_name(project_name, asset_name) assert asset_doc, "Asset must exist: %s" % asset_name diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_layers.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_layers.py index e36cd875ba..70dc28e925 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_layers.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_layers.py @@ -55,7 +55,7 @@ class CollectUsdLayers(pyblish.api.InstancePlugin): layer_inst.data["families"] = [family] layer_inst.data["subset"] = "__stub__" layer_inst.data["label"] = label - layer_inst.data["asset"] = instance.data["asset"] + layer_inst.data["folderPath"] = instance.data["folderPath"] layer_inst.data["instance_node"] = instance.data["instance_node"] # include same USD ROP layer_inst.append(rop_node) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_usd_shade_model_exists.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_usd_shade_model_exists.py index 8fa20ace02..c8b9ed9bab 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_usd_shade_model_exists.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_usd_shade_model_exists.py @@ -18,7 +18,7 @@ class ValidateUSDShadeModelExists(pyblish.api.InstancePlugin): def process(self, instance): project_name = instance.context.data["projectName"] - asset_name = instance.data["asset"] + asset_name = instance.data["folderPath"] subset = instance.data["subset"] # Assume shading variation starts after a dot separator diff --git a/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py b/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py index b19eb36168..67eb3d425c 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py +++ b/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py @@ -170,7 +170,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin): parents = instance.data.get('parents', []) # Split by '/' for AYON where asset is a path - asset_name = instance.data["asset"].split("/")[-1] + asset_name = instance.data["folderPath"].split("/")[-1] actual = {asset_name: in_info} for parent in reversed(parents): diff --git a/client/ayon_core/hosts/traypublisher/plugins/publish/validate_existing_version.py b/client/ayon_core/hosts/traypublisher/plugins/publish/validate_existing_version.py index 6a85f92ce1..b75ae674e8 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/publish/validate_existing_version.py +++ b/client/ayon_core/hosts/traypublisher/plugins/publish/validate_existing_version.py @@ -40,7 +40,7 @@ class ValidateExistingVersion( formatting_data = { "subset_name": subset_name, - "asset_name": instance.data["asset"], + "asset_name": instance.data["folderPath"], "version": version } raise PublishXmlValidationError( From 43485cc64abc348e51321725de577daf5627df9f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 11:29:20 +0100 Subject: [PATCH 134/149] fix extract usd layered --- .../hosts/houdini/plugins/publish/extract_usd_layered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_usd_layered.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_usd_layered.py index 7160e3d282..56c335f50e 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_usd_layered.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_usd_layered.py @@ -285,7 +285,7 @@ class ExtractUSDLayered(publish.Extractor): # to detect whether we should make this into a new publish # version. If not, skip it. asset = get_asset_by_name( - project_name, dependency.data["asset"], fields=["_id"] + project_name, dependency.data["folderPath"], fields=["_id"] ) subset = get_subset_by_name( project_name, From b938fe4220a4cd878342183309ff0fff16afdae8 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Tue, 20 Feb 2024 10:45:44 +0000 Subject: [PATCH 135/149] Remove validate model plugin --- .../plugins/publish/validate_model_name.py | 153 ------------------ 1 file changed, 153 deletions(-) delete mode 100644 client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py deleted file mode 100644 index 0d27965971..0000000000 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validate model nodes names.""" -import os -import platform -import re - -import pyblish.api -from maya import cmds - -import ayon_core.hosts.maya.api.action -from ayon_core.pipeline.publish import ( - OptionalPyblishPluginMixin, - PublishValidationError, - ValidateContentsOrder, -) - - -class ValidateModelName(pyblish.api.InstancePlugin, - OptionalPyblishPluginMixin): - """Validate name of model - - starts with (somename)_###_(materialID)_GEO - materialID must be present in list - padding number doesn't have limit - - """ - optional = True - order = ValidateContentsOrder - hosts = ["maya"] - families = ["model"] - label = "Model Name" - actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] - - material_file = { - "windows": None, - "darwin": None, - "linux": None, - } - - @classmethod - def get_invalid(cls, instance): - """Get invalid nodes.""" - - def is_group(group_name): - """Find out if supplied transform is group or not.""" - try: - children = cmds.listRelatives(group_name, children=True) - for child in children: - if not cmds.ls(child, transforms=True): - return False - return True - except Exception: - return False - - invalid = [] - content_instance = instance.data.get("setMembers", None) - if not content_instance: - cls.log.error("Instance has no nodes!") - return True - pass - - # validate top level group name - assemblies = cmds.ls(content_instance, assemblies=True, long=True) - if len(assemblies) != 1: - cls.log.error("Must have exactly one top group") - return assemblies or True - top_group = assemblies[0] - regex = cls.top_level_regex - r = re.compile(regex) - m = r.match(top_group) - project_name = instance.context.data["projectName"] - current_asset_name = instance.context.data["asset"] - if m is None: - cls.log.error("invalid name on: {}".format(top_group)) - cls.log.error("name doesn't match regex {}".format(regex)) - invalid.append(top_group) - else: - if "asset" in r.groupindex: - if m.group("asset") != current_asset_name: - cls.log.error("Invalid asset name in top level group.") - return top_group - if "subset" in r.groupindex: - if m.group("subset") != instance.data.get("subset"): - cls.log.error("Invalid subset name in top level group.") - return top_group - if "project" in r.groupindex: - if m.group("project") != project_name: - cls.log.error("Invalid project name in top level group.") - return top_group - - descendants = cmds.listRelatives(content_instance, - allDescendents=True, - fullPath=True) or [] - - descendants = cmds.ls(descendants, noIntermediate=True, long=True) - trns = cmds.ls(descendants, long=False, type='transform') - - # filter out groups - filtered = [node for node in trns if not is_group(node)] - - # load shader list file as utf-8 - shaders = [] - material_file = cls.material_file[platform.system().lower()] - if material_file: - if os.path.isfile(material_file): - shader_file = open(material_file, "r") - shaders = shader_file.readlines() - shader_file.close() - else: - cls.log.error("Missing shader name definition file.") - return True - - # strip line endings from list - shaders = [s.rstrip() for s in shaders if s.rstrip()] - - # compile regex for testing names - regex = cls.regex - r = re.compile(regex) - - for obj in filtered: - cls.log.debug("testing: {}".format(obj)) - m = r.match(obj) - if m is None: - cls.log.error("invalid name on: {}".format(obj)) - invalid.append(obj) - else: - # if we have shader files and shader named group is in - # regex, test this group against names in shader file - if "shader" in r.groupindex and shaders: - try: - if not m.group('shader') in shaders: - cls.log.error( - "invalid materialID on: {0} ({1})".format( - obj, m.group('shader'))) - invalid.append(obj) - except IndexError: - # shader named group doesn't match - cls.log.error( - "shader group doesn't match: {}".format(obj)) - invalid.append(obj) - - return invalid - - def process(self, instance): - """Plugin entry point.""" - if not self.is_active(instance.data): - return - - invalid = self.get_invalid(instance) - - if invalid: - raise PublishValidationError( - "Model naming is invalid. See the log.") From 1b153953113c6eb8378da508ac38f9451d63556e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 20 Feb 2024 18:54:38 +0800 Subject: [PATCH 136/149] change on the identifier in regards to the ayon and move the collector of current file to lower priority for collecting the data --- client/ayon_core/hosts/max/plugins/create/create_workfile.py | 2 +- .../ayon_core/hosts/max/plugins/publish/collect_current_file.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/create/create_workfile.py b/client/ayon_core/hosts/max/plugins/create/create_workfile.py index ce4d8b976d..27864c28d5 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_workfile.py +++ b/client/ayon_core/hosts/max/plugins/create/create_workfile.py @@ -9,7 +9,7 @@ from pymxs import runtime as rt class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): """Workfile auto-creator.""" - identifier = "io.openpype.creators.max.workfile" + identifier = "io.ayon.creators.max.workfile" label = "Workfile" family = "workfile" icon = "fa5.file" diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py b/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py index 689a357c53..6f8b8dda4b 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py +++ b/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py @@ -7,7 +7,7 @@ from pymxs import runtime as rt class CollectCurrentFile(pyblish.api.ContextPlugin): """Inject the current working file.""" - order = pyblish.api.CollectorOrder - 0.4 + order = pyblish.api.CollectorOrder - 0.5 label = "Max Current File" hosts = ['max'] From 98a0f72f0363574f9141f175907b667b53c6065a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 13:25:13 +0100 Subject: [PATCH 137/149] define new metadata ids --- client/ayon_core/pipeline/__init__.py | 4 ++++ client/ayon_core/pipeline/constants.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/__init__.py b/client/ayon_core/pipeline/__init__.py index c5507b0a7b..679e9a195e 100644 --- a/client/ayon_core/pipeline/__init__.py +++ b/client/ayon_core/pipeline/__init__.py @@ -1,6 +1,8 @@ from .constants import ( AVALON_CONTAINER_ID, + AVALON_INSTANCE_ID, AYON_CONTAINER_ID, + AYON_INSTANCE_ID, HOST_WORKFILE_EXTENSIONS, ) @@ -101,7 +103,9 @@ uninstall = uninstall_host __all__ = ( "AVALON_CONTAINER_ID", + "AVALON_INSTANCE_ID", "AYON_CONTAINER_ID", + "AYON_INSTANCE_ID", "HOST_WORKFILE_EXTENSIONS", # --- Anatomy --- diff --git a/client/ayon_core/pipeline/constants.py b/client/ayon_core/pipeline/constants.py index 755a5fb380..7a08cbb3aa 100644 --- a/client/ayon_core/pipeline/constants.py +++ b/client/ayon_core/pipeline/constants.py @@ -1,5 +1,9 @@ # Metadata ID of loaded container into scene -AVALON_CONTAINER_ID = AYON_CONTAINER_ID = "pyblish.avalon.container" +AYON_CONTAINER_ID = "ayon.load.container" +AYON_INSTANCE_ID = "ayon.create.instance" +# Backwards compatibility +AVALON_CONTAINER_ID = "pyblish.avalon.container" +AVALON_INSTANCE_ID = "pyblish.avalon.instance" # TODO get extensions from host implementations HOST_WORKFILE_EXTENSIONS = { From ce6fc93d486730da3391c750742c039324f301b3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 14:04:26 +0100 Subject: [PATCH 138/149] fix collect usd bootstrap --- .../hosts/houdini/plugins/publish/collect_usd_bootstrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py index c43ff4f442..791b530eed 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py @@ -95,7 +95,7 @@ class CollectUsdBootstrap(pyblish.api.InstancePlugin): new.data["optional"] = False # Copy some data from the instance for which we bootstrap - for key in ["asset"]: + for key in ["folderPath"]: new.data[key] = instance.data[key] def _subset_exists(self, project_name, instance, subset_name, asset_doc): @@ -107,7 +107,7 @@ class CollectUsdBootstrap(pyblish.api.InstancePlugin): for inst in context: if ( inst.data["subset"] == subset_name - and inst.data["asset"] == asset_doc_name + and inst.data["folderPath"] == asset_doc_name ): return True From 522e1b1095d1f152a4db95de915be45d9eba0ee0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 14:11:10 +0100 Subject: [PATCH 139/149] fix extract hierarchy to ayon --- client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py index 26e448cc6e..7ceaf7d2ad 100644 --- a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py +++ b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py @@ -189,7 +189,7 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): active_folder_paths = set() for instance in context: if instance.data.get("publish") is not False: - active_folder_paths.add(instance.data.get("asset")) + active_folder_paths.add(instance.data.get("folderPath")) active_folder_paths.discard(None) From 229bd07396f8f59fa70d7285aae71c50377b4fe3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 14:11:31 +0100 Subject: [PATCH 140/149] fix 'get_last_versions_for_instances' --- client/ayon_core/pipeline/create/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/create/utils.py b/client/ayon_core/pipeline/create/utils.py index 0547c20c0a..c2655f319f 100644 --- a/client/ayon_core/pipeline/create/utils.py +++ b/client/ayon_core/pipeline/create/utils.py @@ -32,7 +32,7 @@ def get_last_versions_for_instances( subset_names_by_asset_name = collections.defaultdict(set) instances_by_hierarchy = {} for instance in instances: - asset_name = instance.data.get("asset") + asset_name = instance.data.get("folderPath") subset_name = instance.subset_name if not asset_name or not subset_name: if use_value_for_missing: From d724a666331b042d9908a1c6e4a4271348174c76 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 14:30:20 +0100 Subject: [PATCH 141/149] use constants instead of hardcoded values --- .../hosts/aftereffects/api/pipeline.py | 6 +++++- .../ayon_core/hosts/blender/api/pipeline.py | 6 ++++-- client/ayon_core/hosts/blender/api/plugin.py | 8 ++++++-- .../publish/collect_timeline_instances.py | 5 ++++- client/ayon_core/hosts/fusion/api/plugin.py | 18 ++++++++++-------- client/ayon_core/hosts/harmony/api/README.md | 8 ++++++-- .../plugins/publish/collect_instances.py | 2 +- client/ayon_core/hosts/hiero/api/lib.py | 11 +++++++++-- client/ayon_core/hosts/hiero/api/pipeline.py | 5 ++++- .../plugins/publish/precollect_instances.py | 5 ++++- .../ayon_core/hosts/houdini/api/pipeline.py | 8 ++++++-- client/ayon_core/hosts/houdini/api/plugin.py | 9 +++++++-- .../plugins/publish/collect_instances.py | 7 +++++-- .../publish/collect_instances_usd_layered.py | 2 +- client/ayon_core/hosts/max/api/pipeline.py | 5 ++++- client/ayon_core/hosts/max/api/plugin.py | 14 ++++++++++++-- client/ayon_core/hosts/maya/api/lib.py | 19 +++++++++++++++---- client/ayon_core/hosts/maya/api/pipeline.py | 10 +++++++--- client/ayon_core/hosts/maya/api/plugin.py | 11 +++++++++-- .../maya/api/workfile_template_builder.py | 11 +++++++++-- .../maya/plugins/publish/collect_instances.py | 2 +- .../plugins/publish/extract_maya_scene_raw.py | 10 ++++++++-- client/ayon_core/hosts/nuke/api/lib.py | 10 ++++++++-- client/ayon_core/hosts/nuke/api/pipeline.py | 6 +++++- client/ayon_core/hosts/nuke/api/plugin.py | 8 ++++++-- .../nuke/plugins/create/convert_legacy.py | 5 ++++- .../ayon_core/hosts/photoshop/api/README.md | 2 +- .../ayon_core/hosts/photoshop/api/pipeline.py | 6 +++++- .../ayon_core/hosts/photoshop/api/ws_stub.py | 6 +++--- .../publish/collect_color_coded_instances.py | 2 +- .../plugins/publish/precollect_instances.py | 5 ++++- .../ayon_core/hosts/tvpaint/api/pipeline.py | 2 +- client/ayon_core/pipeline/create/README.md | 4 ++-- client/ayon_core/pipeline/create/context.py | 12 ++++++++++-- .../pipeline/create/legacy_create.py | 4 +++- .../ayon_core/tools/subsetmanager/README.md | 2 +- 36 files changed, 191 insertions(+), 65 deletions(-) diff --git a/client/ayon_core/hosts/aftereffects/api/pipeline.py b/client/ayon_core/hosts/aftereffects/api/pipeline.py index 32e064d8cb..7ed244fd1d 100644 --- a/client/ayon_core/hosts/aftereffects/api/pipeline.py +++ b/client/ayon_core/hosts/aftereffects/api/pipeline.py @@ -9,6 +9,8 @@ from ayon_core.pipeline import ( register_loader_plugin_path, register_creator_plugin_path, AVALON_CONTAINER_ID, + AVALON_INSTANCE_ID, + AYON_INSTANCE_ID, ) from ayon_core.hosts.aftereffects.api.workfile_template_builder import ( AEPlaceholderLoadPlugin, @@ -142,7 +144,9 @@ class AfterEffectsHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): layers_meta = stub.get_metadata() for instance in layers_meta: - if instance.get("id") == "pyblish.avalon.instance": + if instance.get("id") in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: instances.append(instance) return instances diff --git a/client/ayon_core/hosts/blender/api/pipeline.py b/client/ayon_core/hosts/blender/api/pipeline.py index a49afeea6b..fcac285f74 100644 --- a/client/ayon_core/hosts/blender/api/pipeline.py +++ b/client/ayon_core/hosts/blender/api/pipeline.py @@ -26,6 +26,7 @@ from ayon_core.pipeline import ( deregister_loader_plugin_path, deregister_creator_plugin_path, AVALON_CONTAINER_ID, + AYON_CONTAINER_ID, ) from ayon_core.lib import ( Logger, @@ -563,8 +564,9 @@ def ls() -> Iterator: called containers. """ - for container in lib.lsattr("id", AVALON_CONTAINER_ID): - yield parse_container(container) + for id_type in {AYON_CONTAINER_ID, AVALON_CONTAINER_ID}: + for container in lib.lsattr("id", id_type): + yield parse_container(container) def publish(): diff --git a/client/ayon_core/hosts/blender/api/plugin.py b/client/ayon_core/hosts/blender/api/plugin.py index 2cd8d1f291..d72754f148 100644 --- a/client/ayon_core/hosts/blender/api/plugin.py +++ b/client/ayon_core/hosts/blender/api/plugin.py @@ -10,6 +10,8 @@ from ayon_core.pipeline import ( Creator, CreatedInstance, LoaderPlugin, + AVALON_INSTANCE_ID, + AYON_INSTANCE_ID, ) from ayon_core.lib import BoolDef @@ -193,7 +195,9 @@ class BaseCreator(Creator): if not avalon_prop: continue - if avalon_prop.get('id') != 'pyblish.avalon.instance': + if avalon_prop.get('id') not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue creator_id = avalon_prop.get('creator_identifier') @@ -352,7 +356,7 @@ class BaseCreator(Creator): instance_data.update( { - "id": "pyblish.avalon.instance", + "id": AVALON_INSTANCE_ID, "creator_identifier": self.identifier, "subset": subset_name, } diff --git a/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py b/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py index 636cbd8031..3819537010 100644 --- a/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py +++ b/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py @@ -3,6 +3,7 @@ from types import NoneType import pyblish import ayon_core.hosts.flame.api as opfapi from ayon_core.hosts.flame.otio import flame_export +from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID from ayon_core.pipeline.editorial import ( is_overlapping_otio_ranges, get_media_range_with_retimes @@ -47,7 +48,9 @@ class CollectTimelineInstances(pyblish.api.ContextPlugin): if not marker_data: continue - if marker_data.get("id") != "pyblish.avalon.instance": + if marker_data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue self.log.debug("__ segment.name: {}".format( diff --git a/client/ayon_core/hosts/fusion/api/plugin.py b/client/ayon_core/hosts/fusion/api/plugin.py index 70392c2f5b..3bf810ca23 100644 --- a/client/ayon_core/hosts/fusion/api/plugin.py +++ b/client/ayon_core/hosts/fusion/api/plugin.py @@ -12,7 +12,9 @@ from ayon_core.lib import ( ) from ayon_core.pipeline import ( Creator, - CreatedInstance + CreatedInstance, + AVALON_INSTANCE_ID, + AYON_INSTANCE_ID, ) @@ -172,13 +174,13 @@ class GenericCreateSaver(Creator): if not isinstance(data, dict): return - required = { - "id": "pyblish.avalon.instance", - "creator_identifier": self.identifier, - } - for key, value in required.items(): - if key not in data or data[key] != value: - return + if ( + data.get("creator_identifier") != self.identifier + or data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + } + ): + return # Get active state from the actual tool state attrs = tool.GetAttrs() diff --git a/client/ayon_core/hosts/harmony/api/README.md b/client/ayon_core/hosts/harmony/api/README.md index 680a88c423..457e22fb2e 100644 --- a/client/ayon_core/hosts/harmony/api/README.md +++ b/client/ayon_core/hosts/harmony/api/README.md @@ -212,6 +212,7 @@ class CreateComposite(harmony.Creator): The creator plugin can be configured to use other node types. For example here is a write node creator: ```python +from uuid import uuid4 import ayon_core.hosts.harmony.api as harmony @@ -242,6 +243,7 @@ class CreateRender(harmony.Creator): #### Collector Plugin ```python import pyblish.api +from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID import ayon_core.hosts.harmony.api as harmony @@ -252,7 +254,7 @@ class CollectInstances(pyblish.api.ContextPlugin): a composite node and marked with a unique identifier; Identifier: - id (str): "pyblish.avalon.instance" + id (str): "ayon.create.instance" """ label = "Instances" @@ -272,7 +274,7 @@ class CollectInstances(pyblish.api.ContextPlugin): continue # Skip containers. - if "container" in data["id"]: + if data["id"] not in {AYON_INSTANCE_ID, AVALON_INSTANCE_ID}: continue instance = context.create_instance(node.split("/")[-1]) @@ -287,6 +289,7 @@ class CollectInstances(pyblish.api.ContextPlugin): #### Extractor Plugin ```python import os +from uuid import uuid4 import pyblish.api import ayon_core.hosts.harmony.api as harmony @@ -418,6 +421,7 @@ class ExtractImage(pyblish.api.InstancePlugin): #### Loader Plugin ```python import os +from uuid import uuid4 import ayon_core.hosts.harmony.api as harmony diff --git a/client/ayon_core/hosts/harmony/plugins/publish/collect_instances.py b/client/ayon_core/hosts/harmony/plugins/publish/collect_instances.py index 3eb689aff6..9ce99a3c3d 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/collect_instances.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/collect_instances.py @@ -13,7 +13,7 @@ class CollectInstances(pyblish.api.ContextPlugin): a composite node and marked with a unique identifier. Identifier: - id (str): "pyblish.avalon.instance" + id (str): "ayon.create.instance" """ label = "Instances" diff --git a/client/ayon_core/hosts/hiero/api/lib.py b/client/ayon_core/hosts/hiero/api/lib.py index 24ff76d30b..d74ff13f05 100644 --- a/client/ayon_core/hosts/hiero/api/lib.py +++ b/client/ayon_core/hosts/hiero/api/lib.py @@ -22,7 +22,12 @@ except ImportError: from ayon_core.client import get_project from ayon_core.settings import get_project_settings -from ayon_core.pipeline import Anatomy, get_current_project_name +from ayon_core.pipeline import ( + Anatomy, + get_current_project_name, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, +) from ayon_core.pipeline.load import filter_containers from ayon_core.lib import Logger from . import tags @@ -1217,7 +1222,9 @@ def sync_clip_name_to_data_asset(track_items_list): # ignore if no data on the clip or not publish instance if not data: continue - if data.get("id") != "pyblish.avalon.instance": + if data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue # fix data if wrong name diff --git a/client/ayon_core/hosts/hiero/api/pipeline.py b/client/ayon_core/hosts/hiero/api/pipeline.py index 1897628678..a9ba2e4df3 100644 --- a/client/ayon_core/hosts/hiero/api/pipeline.py +++ b/client/ayon_core/hosts/hiero/api/pipeline.py @@ -15,6 +15,7 @@ from ayon_core.pipeline import ( deregister_creator_plugin_path, deregister_loader_plugin_path, AVALON_CONTAINER_ID, + AYON_CONTAINER_ID, ) from ayon_core.tools.utils import host_tools from . import lib, menu, events @@ -158,7 +159,9 @@ def parse_container(item, validate=True): def data_to_container(item, data): if ( not data - or data.get("id") != "pyblish.avalon.container" + or data.get("id") not in { + AYON_CONTAINER_ID, AVALON_CONTAINER_ID + } ): return diff --git a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py index e41ca74320..6344d76cd0 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py @@ -1,5 +1,6 @@ import pyblish +from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID from ayon_core.pipeline.editorial import is_overlapping_otio_ranges from ayon_core.hosts.hiero import api as phiero @@ -56,7 +57,9 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not tag_data: continue - if tag_data.get("id") != "pyblish.avalon.instance": + if tag_data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue # get clips subtracks and anotations diff --git a/client/ayon_core/hosts/houdini/api/pipeline.py b/client/ayon_core/hosts/houdini/api/pipeline.py index d93ea9acec..cbc94a2408 100644 --- a/client/ayon_core/hosts/houdini/api/pipeline.py +++ b/client/ayon_core/hosts/houdini/api/pipeline.py @@ -15,6 +15,7 @@ from ayon_core.pipeline import ( register_loader_plugin_path, register_inventory_action_path, AVALON_CONTAINER_ID, + AYON_CONTAINER_ID, ) from ayon_core.pipeline.load import any_outdated_containers from ayon_core.hosts.houdini import HOUDINI_HOST_DIR @@ -271,8 +272,11 @@ def parse_container(container): def ls(): containers = [] - for identifier in (AVALON_CONTAINER_ID, - "pyblish.mindbender.container"): + for identifier in ( + AYON_CONTAINER_ID, + AVALON_CONTAINER_ID, + "pyblish.mindbender.container" + ): containers += lib.lsattr("id", identifier) for container in sorted(containers, diff --git a/client/ayon_core/hosts/houdini/api/plugin.py b/client/ayon_core/hosts/houdini/api/plugin.py index e8f89bfbb4..2538766f5f 100644 --- a/client/ayon_core/hosts/houdini/api/plugin.py +++ b/client/ayon_core/hosts/houdini/api/plugin.py @@ -11,7 +11,9 @@ from ayon_core.pipeline import ( CreatorError, LegacyCreator, Creator as NewCreator, - CreatedInstance + CreatedInstance, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, ) from ayon_core.lib import BoolDef from .lib import imprint, read, lsattr, add_self_publish_button @@ -118,7 +120,10 @@ class HoudiniCreatorBase(object): cache = dict() cache_legacy = dict() - for node in lsattr("id", "pyblish.avalon.instance"): + nodes = [] + for id_type in [AYON_INSTANCE_ID, AVALON_INSTANCE_ID]: + nodes.extend(lsattr("id", AYON_INSTANCE_ID)) + for node in nodes: creator_identifier_parm = node.parm("creator_identifier") if creator_identifier_parm: diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py index 2780da95d9..5869d201c0 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances.py @@ -2,6 +2,7 @@ import hou import pyblish.api +from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID from ayon_core.hosts.houdini.api import lib @@ -12,7 +13,7 @@ class CollectInstances(pyblish.api.ContextPlugin): an specific node and marked with a unique identifier; Identifier: - id (str): "pyblish.avalon.instance + id (str): "ayon.create.instance" Specific node: The specific node is important because it dictates in which way the @@ -44,7 +45,9 @@ class CollectInstances(pyblish.api.ContextPlugin): if not node.parm("id"): continue - if node.evalParm("id") != "pyblish.avalon.instance": + if node.evalParm("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue # instance was created by new creator code, skip it as diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py index ee259fb70d..7a3087c268 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py @@ -12,7 +12,7 @@ class CollectInstancesUsdLayered(pyblish.api.ContextPlugin): layers remain set to 'publish' by the user. This works differently from most of our Avalon instances in the pipeline. - As opposed to storing `pyblish.avalon.instance` as id on the node we store + As opposed to storing `ayon.create.instance` as id on the node we store `pyblish.avalon.usdlayered`. Additionally this instance has no need for storing family, asset, subset diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index c26e697429..46c5aeec11 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -12,6 +12,7 @@ from ayon_core.pipeline import ( register_creator_plugin_path, register_loader_plugin_path, AVALON_CONTAINER_ID, + AYON_CONTAINER_ID, ) from ayon_core.hosts.max.api.menu import OpenPypeMenu from ayon_core.hosts.max.api import lib @@ -151,7 +152,9 @@ def ls() -> list: objs = rt.objects containers = [ obj for obj in objs - if rt.getUserProp(obj, "id") == AVALON_CONTAINER_ID + if rt.getUserProp(obj, "id") in { + AYON_CONTAINER_ID, AVALON_CONTAINER_ID + } ] for container in sorted(containers, key=attrgetter("name")): diff --git a/client/ayon_core/hosts/max/api/plugin.py b/client/ayon_core/hosts/max/api/plugin.py index 3551450c24..18f752631d 100644 --- a/client/ayon_core/hosts/max/api/plugin.py +++ b/client/ayon_core/hosts/max/api/plugin.py @@ -6,7 +6,13 @@ import six from pymxs import runtime as rt from ayon_core.lib import BoolDef -from ayon_core.pipeline import CreatedInstance, Creator, CreatorError +from ayon_core.pipeline import ( + CreatedInstance, + Creator, + CreatorError, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, +) from .lib import imprint, lsattr, read @@ -162,7 +168,11 @@ class MaxCreatorBase(object): return shared_data shared_data["max_cached_subsets"] = {} - cached_instances = lsattr("id", "pyblish.avalon.instance") + + cached_instances = [] + for id_type in [AYON_INSTANCE_ID, AVALON_INSTANCE_ID]: + cached_instances.extend(lsattr("id", id_type)) + for i in cached_instances: creator_id = rt.GetUserProp(i, "creator_identifier") if creator_id not in shared_data["max_cached_subsets"]: diff --git a/client/ayon_core/hosts/maya/api/lib.py b/client/ayon_core/hosts/maya/api/lib.py index 3a29fe433b..b38439144e 100644 --- a/client/ayon_core/hosts/maya/api/lib.py +++ b/client/ayon_core/hosts/maya/api/lib.py @@ -35,7 +35,11 @@ from ayon_core.pipeline import ( loaders_from_representation, get_representation_path, load_container, - registered_host + registered_host, + AVALON_CONTAINER_ID, + AVALON_INSTANCE_ID, + AYON_INSTANCE_ID, + AYON_CONTAINER_ID, ) from ayon_core.lib import NumberDef from ayon_core.pipeline.context_tools import get_current_project_asset @@ -2100,7 +2104,7 @@ def get_related_sets(node): """Return objectSets that are relationships for a look for `node`. Filters out based on: - - id attribute is NOT `pyblish.avalon.container` + - id attribute is NOT `AVALON_CONTAINER_ID` - shapes and deformer shapes (alembic creates meshShapeDeformed) - set name ends with any from a predefined list - set in not in viewport set (isolate selected for example) @@ -2120,7 +2124,12 @@ def get_related_sets(node): defaults = {"defaultLightSet", "defaultObjectSet"} # Ids to ignore - ignored = {"pyblish.avalon.instance", "pyblish.avalon.container"} + ignored = { + AVALON_INSTANCE_ID, + AVALON_CONTAINER_ID, + AYON_INSTANCE_ID, + AYON_CONTAINER_ID, + } view_sets = get_isolate_view_sets() @@ -3151,7 +3160,9 @@ def update_content_on_context_change(): new_data = asset_doc["data"] for s in scene_sets: try: - if cmds.getAttr("{}.id".format(s)) == "pyblish.avalon.instance": + if cmds.getAttr("{}.id".format(s)) in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: attr = cmds.listAttr(s) print(s) if "asset" in attr: diff --git a/client/ayon_core/hosts/maya/api/pipeline.py b/client/ayon_core/hosts/maya/api/pipeline.py index e58316030e..bba9943889 100644 --- a/client/ayon_core/hosts/maya/api/pipeline.py +++ b/client/ayon_core/hosts/maya/api/pipeline.py @@ -33,6 +33,7 @@ from ayon_core.pipeline import ( deregister_loader_plugin_path, deregister_inventory_action_path, deregister_creator_plugin_path, + AYON_CONTAINER_ID, AVALON_CONTAINER_ID, ) from ayon_core.pipeline.load import any_outdated_containers @@ -376,9 +377,12 @@ def _ls(): yield iterator.thisNode() iterator.next() - ids = {AVALON_CONTAINER_ID, - # Backwards compatibility - "pyblish.mindbender.container"} + ids = { + AYON_CONTAINER_ID, + # Backwards compatibility + AVALON_CONTAINER_ID, + "pyblish.mindbender.container" + } # Iterate over all 'set' nodes in the scene to detect whether # they have the avalon container ".id" attribute. diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index 42c0c7051e..7a01f1a174 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -10,6 +10,9 @@ from maya.app.renderSetup.model import renderSetup from ayon_core.lib import BoolDef, Logger from ayon_core.settings import get_project_settings from ayon_core.pipeline import ( + AYON_INSTANCE_ID, + AYON_CONTAINER_ID, + AVALON_INSTANCE_ID, AVALON_CONTAINER_ID, Anatomy, @@ -110,7 +113,9 @@ class MayaCreatorBase(object): for node in cmds.ls(type="objectSet"): - if _get_attr(node, attr="id") != "pyblish.avalon.instance": + if _get_attr(node, attr="id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue creator_id = _get_attr(node, attr="creator_identifier") @@ -992,5 +997,7 @@ class ReferenceLoader(Loader): id_attr = "{}.id".format(node) if not cmds.attributeQuery("id", node=node, exists=True): continue - if cmds.getAttr(id_attr) == AVALON_CONTAINER_ID: + if cmds.getAttr(id_attr) not in { + AYON_CONTAINER_ID, AVALON_CONTAINER_ID + }: cmds.sets(node, forceElement=container) diff --git a/client/ayon_core/hosts/maya/api/workfile_template_builder.py b/client/ayon_core/hosts/maya/api/workfile_template_builder.py index c3c61e5444..e9db8ffe79 100644 --- a/client/ayon_core/hosts/maya/api/workfile_template_builder.py +++ b/client/ayon_core/hosts/maya/api/workfile_template_builder.py @@ -2,7 +2,12 @@ import json from maya import cmds -from ayon_core.pipeline import registered_host, get_current_asset_name +from ayon_core.pipeline import ( + registered_host, + get_current_asset_name, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, +) from ayon_core.pipeline.workfile.workfile_template_builder import ( TemplateAlreadyImported, AbstractTemplateBuilder, @@ -73,7 +78,9 @@ class MayaTemplateBuilder(AbstractTemplateBuilder): for node in imported_sets: if not cmds.attributeQuery("id", node=node, exists=True): continue - if cmds.getAttr("{}.id".format(node)) != "pyblish.avalon.instance": + if cmds.getAttr("{}.id".format(node)) not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue if not cmds.attributeQuery("asset", node=node, exists=True): continue diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_instances.py b/client/ayon_core/hosts/maya/plugins/publish/collect_instances.py index 0b29851db0..2d745d0ca8 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_instances.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_instances.py @@ -11,7 +11,7 @@ class CollectNewInstances(pyblish.api.InstancePlugin): an objectSet and marked with a unique identifier; Identifier: - id (str): "pyblish.avalon.instance" + id (str): "ayon.create.instance" Limitations: - Does not take into account nodes connected to those diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py b/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py index cd6f3bab6a..135185fe5c 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py @@ -5,7 +5,11 @@ import os from maya import cmds from ayon_core.hosts.maya.api.lib import maintained_selection -from ayon_core.pipeline import AVALON_CONTAINER_ID, publish +from ayon_core.pipeline import ( + AYON_CONTAINER_ID, + AVALON_CONTAINER_ID, + publish, +) from ayon_core.pipeline.publish import AYONPyblishPluginMixin from ayon_core.lib import BoolDef @@ -136,7 +140,9 @@ class ExtractMayaSceneRaw(publish.Extractor, AYONPyblishPluginMixin): continue id_attr = "{}.id".format(obj_set) - if cmds.getAttr(id_attr) != AVALON_CONTAINER_ID: + if cmds.getAttr(id_attr) not in { + AYON_CONTAINER_ID, AVALON_CONTAINER_ID + }: continue set_content = set(cmds.sets(obj_set, query=True)) diff --git a/client/ayon_core/hosts/nuke/api/lib.py b/client/ayon_core/hosts/nuke/api/lib.py index c320df9361..a2ec8fdb98 100644 --- a/client/ayon_core/hosts/nuke/api/lib.py +++ b/client/ayon_core/hosts/nuke/api/lib.py @@ -45,6 +45,8 @@ from ayon_core.pipeline import ( get_current_host_name, get_current_project_name, get_current_asset_name, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, ) from ayon_core.pipeline.context_tools import ( get_custom_workfile_template_from_session @@ -2300,12 +2302,16 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies. # backward compatibility # TODO: remove this once old avalon data api will be removed avalon_knob_data - and avalon_knob_data.get("id") != "pyblish.avalon.instance" + and avalon_knob_data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + } ): continue elif ( node_data - and node_data.get("id") != "pyblish.avalon.instance" + and node_data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + } ): continue diff --git a/client/ayon_core/hosts/nuke/api/pipeline.py b/client/ayon_core/hosts/nuke/api/pipeline.py index 735426240e..c747996d9d 100644 --- a/client/ayon_core/hosts/nuke/api/pipeline.py +++ b/client/ayon_core/hosts/nuke/api/pipeline.py @@ -18,6 +18,8 @@ from ayon_core.pipeline import ( register_loader_plugin_path, register_creator_plugin_path, register_inventory_action_path, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, AVALON_CONTAINER_ID, get_current_asset_name, get_current_task_name, @@ -550,7 +552,9 @@ def list_instances(creator_id=None): if not instance_data: continue - if instance_data["id"] != "pyblish.avalon.instance": + if instance_data["id"] not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue if creator_id and instance_data["creator_identifier"] != creator_id: diff --git a/client/ayon_core/hosts/nuke/api/plugin.py b/client/ayon_core/hosts/nuke/api/plugin.py index dc14515f2a..59042acee1 100644 --- a/client/ayon_core/hosts/nuke/api/plugin.py +++ b/client/ayon_core/hosts/nuke/api/plugin.py @@ -19,7 +19,9 @@ from ayon_core.pipeline import ( CreatorError, Creator as NewCreator, CreatedInstance, - get_current_task_name + get_current_task_name, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, ) from ayon_core.pipeline.colorspace import ( get_display_view_colorspace_name, @@ -1265,7 +1267,9 @@ def convert_to_valid_instaces(): if not avalon_knob_data: continue - if avalon_knob_data["id"] != "pyblish.avalon.instance": + if avalon_knob_data["id"] not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue transfer_data.update({ diff --git a/client/ayon_core/hosts/nuke/plugins/create/convert_legacy.py b/client/ayon_core/hosts/nuke/plugins/create/convert_legacy.py index 815170ac8b..f113bec887 100644 --- a/client/ayon_core/hosts/nuke/plugins/create/convert_legacy.py +++ b/client/ayon_core/hosts/nuke/plugins/create/convert_legacy.py @@ -1,3 +1,4 @@ +from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID from ayon_core.pipeline.create.creator_plugins import SubsetConvertorPlugin from ayon_core.hosts.nuke.api.lib import ( INSTANCE_DATA_KNOB, @@ -34,7 +35,9 @@ class LegacyConverted(SubsetConvertorPlugin): if not avalon_knob_data: continue - if avalon_knob_data["id"] != "pyblish.avalon.instance": + if avalon_knob_data["id"] not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue # catch and break diff --git a/client/ayon_core/hosts/photoshop/api/README.md b/client/ayon_core/hosts/photoshop/api/README.md index 72e2217829..02868753d1 100644 --- a/client/ayon_core/hosts/photoshop/api/README.md +++ b/client/ayon_core/hosts/photoshop/api/README.md @@ -75,7 +75,7 @@ class CollectInstances(pyblish.api.ContextPlugin): an LayerSet and marked with a unique identifier; Identifier: - id (str): "pyblish.avalon.instance" + id (str): "ayon.create.instance" """ label = "Instances" diff --git a/client/ayon_core/hosts/photoshop/api/pipeline.py b/client/ayon_core/hosts/photoshop/api/pipeline.py index ebde175053..4e9a861220 100644 --- a/client/ayon_core/hosts/photoshop/api/pipeline.py +++ b/client/ayon_core/hosts/photoshop/api/pipeline.py @@ -9,6 +9,8 @@ from ayon_core.pipeline import ( register_loader_plugin_path, register_creator_plugin_path, AVALON_CONTAINER_ID, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, ) from ayon_core.host import ( @@ -121,7 +123,9 @@ class PhotoshopHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): layers_meta = stub.get_layers_metadata() if layers_meta: for instance in layers_meta: - if instance.get("id") == "pyblish.avalon.instance": + if instance.get("id") in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: instances.append(instance) return instances diff --git a/client/ayon_core/hosts/photoshop/api/ws_stub.py b/client/ayon_core/hosts/photoshop/api/ws_stub.py index 42bad05f26..f53f7e04d9 100644 --- a/client/ayon_core/hosts/photoshop/api/ws_stub.py +++ b/client/ayon_core/hosts/photoshop/api/ws_stub.py @@ -119,14 +119,14 @@ class PhotoshopServerStub: "active":true, "subset":"imageBG", "family":"image", - "id":"pyblish.avalon.instance", + "id":"ayon.create.instance", "asset":"Town", "uuid": "8" }] - for created instances OR [{ "schema": "openpype:container-2.0", - "id": "pyblish.avalon.instance", + "id": "ayon.create.instance", "name": "imageMG", "namespace": "Jungle_imageMG_001", "loader": "ImageLoader", @@ -420,7 +420,7 @@ class PhotoshopServerStub: (list) example: {"8":{"active":true,"subset":"imageBG", - "family":"image","id":"pyblish.avalon.instance", + "family":"image","id":"ayon.create.instance", "asset":"Town"}} 8 is layer(group) id - used for deletion, update etc. """ diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py index 6a09cff3c7..fa0ad4aac5 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py @@ -26,7 +26,7 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin): only separate subsets per marked layer. Identifier: - id (str): "pyblish.avalon.instance" + id (str): "ayon.create.instance" """ label = "Collect Color-coded Instances" diff --git a/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py b/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py index 0ae6206496..89546373ad 100644 --- a/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py +++ b/client/ayon_core/hosts/resolve/plugins/publish/precollect_instances.py @@ -2,6 +2,7 @@ from pprint import pformat import pyblish +from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID from ayon_core.hosts.resolve.api.lib import ( get_current_timeline_items, get_timeline_item_pype_tag, @@ -39,7 +40,9 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not tag_data: continue - if tag_data.get("id") != "pyblish.avalon.instance": + if tag_data.get("id") not in { + AYON_INSTANCE_ID, AVALON_INSTANCE_ID + }: continue media_pool_item = timeline_item.GetMediaPoolItem() diff --git a/client/ayon_core/hosts/tvpaint/api/pipeline.py b/client/ayon_core/hosts/tvpaint/api/pipeline.py index 78a0c5270d..6194851cfb 100644 --- a/client/ayon_core/hosts/tvpaint/api/pipeline.py +++ b/client/ayon_core/hosts/tvpaint/api/pipeline.py @@ -52,7 +52,7 @@ expected that there are also keys `["instances0", "instances1"]`. Workfile data looks like: ``` [avalon] -instances0=[{{__dq__}id{__dq__}: {__dq__}pyblish.avalon.instance{__dq__... +instances0=[{{__dq__}id{__dq__}: {__dq__}ayon.create.instance{__dq__... instances1=...more data... instances=2 ``` diff --git a/client/ayon_core/pipeline/create/README.md b/client/ayon_core/pipeline/create/README.md index 012572a776..074cd24364 100644 --- a/client/ayon_core/pipeline/create/README.md +++ b/client/ayon_core/pipeline/create/README.md @@ -14,7 +14,7 @@ Except creating and removing instances are all changes not automatically propaga ## CreatedInstance -Product of creation is "instance" which holds basic data defying it. Core data are `creator_identifier`, `family` and `subset`. Other data can be keys used to fill subset name or metadata modifying publishing process of the instance (more described later). All instances have `id` which holds constant `pyblish.avalon.instance` and `instance_id` which is identifier of the instance. +Product of creation is "instance" which holds basic data defying it. Core data are `creator_identifier`, `family` and `subset`. Other data can be keys used to fill subset name or metadata modifying publishing process of the instance (more described later). All instances have `id` which holds constant `ayon.create.instance` or `pyblish.avalon.instance` (for backwards compatibility) and `instance_id` which is identifier of the instance. Family tells how should be instance processed and subset what name will published item have. - There are cases when subset is not fully filled during creation and may change during publishing. That is in most of cases caused because instance is related to other instance or instance data do not represent final product. @@ -24,7 +24,7 @@ Family tells how should be instance processed and subset what name will publishe { # Immutable data after creation ## Identifier that this data represents instance for publishing (automatically assigned) - "id": "pyblish.avalon.instance", + "id": "ayon.create.instance", ## Identifier of this specific instance (automatically assigned) "instance_id": , ## Instance family (used from Creator) diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index b973c45097..c50170f070 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -27,7 +27,11 @@ from ayon_core.lib.attribute_definitions import ( get_default_values, ) from ayon_core.host import IPublishHost, IWorkfileHost -from ayon_core.pipeline import Anatomy +from ayon_core.pipeline import ( + Anatomy, + AYON_INSTANCE_ID, + AVALON_INSTANCE_ID, +) from ayon_core.pipeline.plugin_discover import DiscoverResult from .creator_plugins import ( @@ -937,7 +941,11 @@ class CreatedInstance: # QUESTION Does it make sense to have data stored as ordered dict? self._data = collections.OrderedDict() # QUESTION Do we need this "id" information on instance? - self._data["id"] = "pyblish.avalon.instance" + item_id = data.get("id") + # TODO use only 'AYON_INSTANCE_ID' when all hosts support it + if item_id not in {AYON_INSTANCE_ID, AVALON_INSTANCE_ID}: + item_id = AVALON_INSTANCE_ID + self._data["id"] = item_id self._data["family"] = family self._data["subset"] = subset_name self._data["active"] = data.get("active", True) diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index 2ab8b8e3e5..b0e94ca225 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -10,6 +10,7 @@ import logging import collections from ayon_core.client import get_asset_by_id +from ayon_core.pipeline.constants import AVALON_INSTANCE_ID from .subset_name import get_subset_name @@ -33,7 +34,8 @@ class LegacyCreator(object): # Default data self.data = collections.OrderedDict() - self.data["id"] = "pyblish.avalon.instance" + # TODO use 'AYON_INSTANCE_ID' when all hosts support it + self.data["id"] = AVALON_INSTANCE_ID self.data["family"] = self.family self.data["asset"] = asset self.data["subset"] = name diff --git a/client/ayon_core/tools/subsetmanager/README.md b/client/ayon_core/tools/subsetmanager/README.md index 062214834a..35b80ea114 100644 --- a/client/ayon_core/tools/subsetmanager/README.md +++ b/client/ayon_core/tools/subsetmanager/README.md @@ -14,6 +14,6 @@ Host is expected to implemented: - `list_instances` - returning list of dictionaries (instances), must contain unique uuid field example: - ```[{"uuid":"15","active":true,"subset":"imageBG","family":"image","id":"pyblish.avalon.instance","asset":"Town"}]``` + ```[{"uuid":"15","active":true,"subset":"imageBG","family":"image","id":"ayon.create.instance","asset":"Town"}]``` - `remove_instance(instance)` - removes instance from file's metadata instance is a dictionary, with uuid field \ No newline at end of file From e145b3347666bb4815147d135118a335e5837727 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 20 Feb 2024 15:04:20 +0100 Subject: [PATCH 142/149] Fix typo in data key and update variable name. - Corrected a typo in a data key from "folferPath" to "folderPath". - Updated the variable name from "asset" to "asset_name". --- .../hosts/hiero/plugins/publish/precollect_instances.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py index 4142d2f403..e97059edf6 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py @@ -248,7 +248,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if not self.test_any_audio(item): return - asset = data["folferPath"] + asset = data["folderPath"] asset_name = data["asset_name"] # insert family into families From 72e615169b198580394a0f7a0314d545b861c901 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 16:42:30 +0100 Subject: [PATCH 143/149] fix houdini instance collection --- client/ayon_core/hosts/houdini/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/plugin.py b/client/ayon_core/hosts/houdini/api/plugin.py index 2538766f5f..57fd194000 100644 --- a/client/ayon_core/hosts/houdini/api/plugin.py +++ b/client/ayon_core/hosts/houdini/api/plugin.py @@ -122,7 +122,7 @@ class HoudiniCreatorBase(object): nodes = [] for id_type in [AYON_INSTANCE_ID, AVALON_INSTANCE_ID]: - nodes.extend(lsattr("id", AYON_INSTANCE_ID)) + nodes.extend(lsattr("id", id_type)) for node in nodes: creator_identifier_parm = node.parm("creator_identifier") From 69882f5d796fd8816615ad9975addae17acb35d7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:43:01 +0100 Subject: [PATCH 144/149] Remove 'pyblish.mindbender.container' Co-authored-by: Roy Nieterau --- client/ayon_core/hosts/maya/api/pipeline.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/pipeline.py b/client/ayon_core/hosts/maya/api/pipeline.py index bba9943889..90fb2e5888 100644 --- a/client/ayon_core/hosts/maya/api/pipeline.py +++ b/client/ayon_core/hosts/maya/api/pipeline.py @@ -380,8 +380,7 @@ def _ls(): ids = { AYON_CONTAINER_ID, # Backwards compatibility - AVALON_CONTAINER_ID, - "pyblish.mindbender.container" + AVALON_CONTAINER_ID } # Iterate over all 'set' nodes in the scene to detect whether From ebfa5a2f3b79f367fe6c8079043e322dfd2f841b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 20 Feb 2024 17:02:42 +0100 Subject: [PATCH 145/149] fix traypublisher editorial --- .../hosts/traypublisher/plugins/create/create_online.py | 2 +- .../traypublisher/plugins/publish/collect_shot_instances.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/hosts/traypublisher/plugins/create/create_online.py b/client/ayon_core/hosts/traypublisher/plugins/create/create_online.py index db11d30afe..36d2fba976 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/create/create_online.py +++ b/client/ayon_core/hosts/traypublisher/plugins/create/create_online.py @@ -53,7 +53,7 @@ class OnlineCreator(TrayPublishCreator): # disable check for existing subset with the same name """ asset = get_asset_by_name( - self.project_name, instance_data["asset"], fields=["_id"]) + self.project_name, instance_data["folderPath"], fields=["_id"]) if get_subset_by_name( self.project_name, origin_basename, asset["_id"], diff --git a/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py b/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py index 67eb3d425c..d489528c57 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py +++ b/client/ayon_core/hosts/traypublisher/plugins/publish/collect_shot_instances.py @@ -17,7 +17,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin): families = ["shot"] SHARED_KEYS = [ - "asset", + "folderPath", "fps", "handleStart", "handleEnd", @@ -132,7 +132,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin): "sourceIn": _cr_attrs["sourceIn"], "sourceOut": _cr_attrs["sourceOut"], "workfileFrameStart": workfile_start_frame, - "asset": _cr_attrs["folderPath"], + "folderPath": _cr_attrs["folderPath"], } def _solve_hierarchy_context(self, instance): From 7e78937e31b39c9d690d7b6573d8aa0860986ee1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Feb 2024 10:38:21 +0100 Subject: [PATCH 146/149] fix 'update_content_on_context_change' in maya --- client/ayon_core/hosts/maya/api/lib.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/lib.py b/client/ayon_core/hosts/maya/api/lib.py index 3a29fe433b..e2e985396b 100644 --- a/client/ayon_core/hosts/maya/api/lib.py +++ b/client/ayon_core/hosts/maya/api/lib.py @@ -24,7 +24,8 @@ from ayon_core.client import ( get_asset_by_name, get_subsets, get_last_versions, - get_representation_by_name + get_representation_by_name, + get_asset_name_identifier, ) from ayon_core.settings import get_project_settings from ayon_core.pipeline import ( @@ -3143,21 +3144,25 @@ def fix_incompatible_containers(): def update_content_on_context_change(): """ - This will update scene content to match new asset on context change + This will update scene content to match new folder on context change """ scene_sets = cmds.listSets(allSets=True) asset_doc = get_current_project_asset() - new_asset = asset_doc["name"] + new_folder_path = get_asset_name_identifier(asset_doc) new_data = asset_doc["data"] for s in scene_sets: try: if cmds.getAttr("{}.id".format(s)) == "pyblish.avalon.instance": attr = cmds.listAttr(s) print(s) - if "asset" in attr: - print(" - setting asset to: [ {} ]".format(new_asset)) - cmds.setAttr("{}.asset".format(s), - new_asset, type="string") + if "folderPath" in attr: + print( + " - setting folder to: [ {} ]".format(new_folder_path) + ) + cmds.setAttr( + "{}.folderPath".format(s), + new_folder_path, type="string" + ) if "frameStart" in attr: cmds.setAttr("{}.frameStart".format(s), new_data["frameStart"]) From c1e528e134c85667c075ef3a211d6bb07b3f9cc2 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 21 Feb 2024 12:06:41 +0100 Subject: [PATCH 147/149] Remove pushing OPENPYPE_VERSION That env var doesn't make sense in Ayon. --- .../publish/create_publish_royalrender_job.py | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index 910abfcb15..90eab2e675 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -216,7 +216,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, SeqEnd=1, SeqStep=1, SeqFileOffset=0, - Version=self._sanitize_version(os.environ.get("OPENPYPE_VERSION")), + Version=os.environ["AYON_BUNDLE_NAME"], SceneName=abs_metadata_path, # command line arguments CustomAddCmdFlags=" ".join(args), @@ -243,26 +243,3 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, job.WaitForPreIDs += jobs_pre_ids return job - - def _sanitize_version(self, version): - """Returns version in format MAJOR.MINORPATCH - - 3.15.7-nightly.2 >> 3.157 - """ - VERSION_REGEX = re.compile( - r"(?P0|[1-9]\d*)" - r"\.(?P0|[1-9]\d*)" - r"\.(?P0|[1-9]\d*)" - r"(?:-(?P[a-zA-Z\d\-.]*))?" - r"(?:\+(?P[a-zA-Z\d\-.]*))?" - ) - - valid_parts = VERSION_REGEX.findall(version) - if len(valid_parts) != 1: - # Return invalid version with filled 'origin' attribute - return version - - # Unpack found version - major, minor, patch, pre, post = valid_parts[0] - - return "{}.{}{}".format(major, minor, patch) From 528f161472c0ca1e68244b99334b72f777e3dff6 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 21 Feb 2024 12:09:51 +0100 Subject: [PATCH 148/149] Cleaned up how selected RR server is queried It should be only queried only once in Collector phase, not multiple times. There is no real possibility to select RR server on instance, eg. artist cannot set that in Publisher, but thats on different PR. --- client/ayon_core/modules/royalrender/lib.py | 18 +------------ .../publish/collect_rr_path_from_instance.py | 3 +++ .../publish/submit_jobs_to_royalrender.py | 26 +------------------ 3 files changed, 5 insertions(+), 42 deletions(-) diff --git a/client/ayon_core/modules/royalrender/lib.py b/client/ayon_core/modules/royalrender/lib.py index 966eb82ab1..73383d482c 100644 --- a/client/ayon_core/modules/royalrender/lib.py +++ b/client/ayon_core/modules/royalrender/lib.py @@ -108,9 +108,7 @@ class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, context = instance.context - self._rr_root = self._resolve_rr_path(context, instance.data.get( - "rrPathName")) # noqa - self.log.debug(self._rr_root) + self._rr_root = instance.data.get("rrPathName") if not self._rr_root: raise KnownPublishError( ("Missing RoyalRender root. " @@ -210,20 +208,6 @@ class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, """Host specific mapping for RRJob""" raise NotImplementedError - @staticmethod - def _resolve_rr_path(context, rr_path_name): - # type: (pyblish.api.Context, str) -> str - rr_settings = context.data["project_settings"]["royalrender"] - rr_paths = rr_settings["rr_paths"] - selected_paths = rr_settings["selected_rr_paths"] - - rr_servers = { - path_key: rr_paths[path_key] - for path_key in selected_paths - if path_key in rr_paths - } - return rr_servers[rr_path_name][platform.system().lower()] - def expected_files(self, instance, path, start_frame, end_frame): """Get expected files. diff --git a/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py b/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py index f43ed1ca49..d860df4684 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/collect_rr_path_from_instance.py @@ -19,6 +19,9 @@ class CollectRRPathFromInstance(pyblish.api.InstancePlugin): # type: (pyblish.api.Instance) -> str """Get Royal Render pat name from render instance.""" + # TODO there are no "rrPaths" on instance, if Publisher should expose + # this (eg. artist could select specific server) it must be added + # to publisher instance_rr_paths = instance.data.get("rrPaths") if instance_rr_paths is None: return "default" diff --git a/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py b/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py index 5e25464186..dcec2ac810 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/submit_jobs_to_royalrender.py @@ -25,16 +25,6 @@ class SubmitJobsToRoyalRender(pyblish.api.ContextPlugin): self._submission_parameters = [] def process(self, context): - rr_settings = ( - context.data - ["system_settings"] - ["modules"] - ["royalrender"] - ) - - if rr_settings["enabled"] is not True: - self.log.warning("RoyalRender modules is disabled.") - return # iterate over all instances and try to find RRJobs jobs = [] @@ -51,7 +41,7 @@ class SubmitJobsToRoyalRender(pyblish.api.ContextPlugin): instance_rr_path = instance.data["rrPathName"] if jobs: - self._rr_root = self._resolve_rr_path(context, instance_rr_path) + self._rr_root = instance_rr_path if not self._rr_root: raise KnownPublishError( ("Missing RoyalRender root. " @@ -100,17 +90,3 @@ class SubmitJobsToRoyalRender(pyblish.api.ContextPlugin): def get_submission_parameters(self): return [SubmitterParameter("RequiredMemory", "0")] - - @staticmethod - def _resolve_rr_path(context, rr_path_name): - # type: (pyblish.api.Context, str) -> str - rr_settings = context.data["project_settings"]["royalrender"] - rr_paths = rr_settings["rr_paths"] - selected_paths = rr_settings["selected_rr_paths"] - - rr_servers = { - path_key: rr_paths[path_key] - for path_key in selected_paths - if path_key in rr_paths - } - return rr_servers[rr_path_name][platform.system().lower()] From ed39b769cfc47bf3e12cfe86987c37a018531d8d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 21 Feb 2024 12:34:00 +0100 Subject: [PATCH 149/149] added container 3 schema --- .../pipeline/schema/container-3.0.json | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 client/ayon_core/pipeline/schema/container-3.0.json diff --git a/client/ayon_core/pipeline/schema/container-3.0.json b/client/ayon_core/pipeline/schema/container-3.0.json new file mode 100644 index 0000000000..c9227bab11 --- /dev/null +++ b/client/ayon_core/pipeline/schema/container-3.0.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "title": "ayon:container-3.0", + "description": "A loaded asset", + + "type": "object", + + "additionalProperties": true, + + "required": [ + "schema", + "id", + "objectName", + "name", + "namespace", + "loader", + "representation" + ], + "properties": { + "schema": { + "description": "Schema identifier for payload", + "type": "string", + "enum": ["ayon:container-3.0"], + "example": "ayon:container-3.0" + }, + "id": { + "description": "Identifier for finding object in host", + "type": "string", + "enum": ["ayon.load.container"], + "example": "ayon.load.container" + }, + "objectName": { + "description": "Name of internal object, such as the objectSet in Maya.", + "type": "string", + "example": "Bruce_:rigDefault_CON" + }, + "loader": { + "description": "Name of loader plug-in used to produce this container", + "type": "string", + "example": "ModelLoader" + }, + "name": { + "description": "Internal object name of container in application", + "type": "string", + "example": "modelDefault_01" + }, + "namespace": { + "description": "Internal namespace of container in application", + "type": "string", + "example": "Bruce_" + }, + "representation": { + "description": "Unique id of representation in database", + "type": "string", + "example": "59523f355f8c1b5f6c5e8348" + } + } +}