From 062f756413ec17332005d59ce7039cedf76cff21 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 22 Oct 2025 16:07:26 +0200 Subject: [PATCH 01/27] Typing At least some, dont know how to import NewFolderDict --- .../tools/push_to_project/models/integrate.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 ef49838152..472500a55d 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -5,7 +5,7 @@ import itertools import sys import traceback import uuid -from typing import Optional, Dict +from typing import Optional, Dict, Any import ayon_api from ayon_api.utils import create_entity_id @@ -650,10 +650,10 @@ class ProjectPushItemProcess: def _create_folder( self, - src_folder_entity, - project_entity, - parent_folder_entity, - folder_name + src_folder_entity: Dict[str, Any], + project_entity: Dict[str, Any], + parent_folder_entity: Dict[str, Any], + folder_name: str ): parent_id = None if parent_folder_entity: From 475d4800a2e86f83ed508e0b33c425a7d6ab9eb7 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 22 Oct 2025 16:13:44 +0200 Subject: [PATCH 02/27] Check that source folder type could be pushed to destination --- .../tools/push_to_project/models/integrate.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) 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 472500a55d..bd309d935f 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -702,7 +702,11 @@ class ProjectPushItemProcess: if new_folder_name != folder_name: folder_label = folder_name - # TODO find out how to define folder type + src_folder_type = src_folder_entity["folderType"] + self._check_src_folder_type( + project_entity, + src_folder_type + ) folder_entity = new_folder_entity( folder_name, "Folder", @@ -727,6 +731,24 @@ class ProjectPushItemProcess: folder_entity["path"] = "/".join([parent_path, folder_name]) return folder_entity + def _check_src_folder_type( + self, + project_entity: Dict[str, Any], + src_folder_type: str + ): + """Confirm that folder type exists in destination project""" + folder_types = [ + folder_type["name"].lower() + for folder_type in project_entity["folderTypes"] + ] + + if src_folder_type.lower() not in folder_types: + self._status.set_failed( + f"'{src_folder_type}' folder type is not configured in " + f"project Anatomy." + ) + raise PushToProjectError(self._status.fail_reason) + def _fill_or_create_destination_folder(self): dst_project_name = self._item.dst_project_name dst_folder_id = self._item.dst_folder_id @@ -1205,7 +1227,7 @@ class ProjectPushItemProcess: value_to_update = formatting_data.get(context_key) if value_to_update: repre_context[context_key] = value_to_update - if "task" not in formatting_data: + if "task" not in formatting_data and "task" in repre_context: repre_context.pop("task") return repre_context From 9340df7a250543658d673d95716047931ea981fa Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 22 Oct 2025 16:14:01 +0200 Subject: [PATCH 03/27] Copy source folder type to destination --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bd309d935f..22fcb5cf9f 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -709,7 +709,7 @@ class ProjectPushItemProcess: ) folder_entity = new_folder_entity( folder_name, - "Folder", + src_folder_type, parent_id=parent_id, attribs=new_folder_attrib ) From 0d235ed8cacffb9196a54e1b3cf40fbcc36fd57e Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 22 Oct 2025 18:58:20 +0200 Subject: [PATCH 04/27] Create destination task if no task selected --- .../tools/push_to_project/models/integrate.py | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) 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 ef49838152..a7cb1de95a 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -762,8 +762,11 @@ class ProjectPushItemProcess: ) self._folder_entity = folder_entity if not dst_task_name: - self._task_info = {} - return + dst_task_name = self._make_sure_task_exists(folder_entity) + + if not dst_task_name: # really no task selected nor on source + self._task_info = {} + return folder_path = folder_entity["path"] folder_tasks = { @@ -962,6 +965,28 @@ class ProjectPushItemProcess: ) self._version_entity = version_entity + def _make_sure_task_exists(self, folder_entity: Dict[str, Any]) -> str: + """Creates destination task from source task information""" + project_name = self._item.dst_project_name + src_version_entity = self._src_version_entity + src_task = ayon_api.get_task_by_id( + self._item.src_project_name, src_version_entity["taskId"] + ) + if not src_task: + self._status.set_failed( + f"No task selected and couldn't find source task" + ) + raise PushToProjectError(self._status.fail_reason) + _task_id = ayon_api.create_task( + project_name, + src_task["name"], + folder_id=folder_entity["id"], + task_type=src_task["taskType"], + attrib=src_task["attrib"], + ) + + return src_task["name"] + def _integrate_representations(self): try: self._real_integrate_representations() From 0ebbd0a23224e4fd539f8b1a479892de38af96dc Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 10:55:37 +0200 Subject: [PATCH 05/27] Extracted logic to methods --- .../tools/push_to_project/models/integrate.py | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) 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 a7cb1de95a..9365379148 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -482,6 +482,8 @@ class ProjectPushItemProcess: self._log_info("Destination project was found") self._fill_or_create_destination_folder() self._log_info("Destination folder was determined") + self._fill_or_create_destination_task() + self._log_info("Destination task was determined") self._determine_product_type() self._determine_publish_template_name() self._determine_product_name() @@ -730,7 +732,6 @@ class ProjectPushItemProcess: def _fill_or_create_destination_folder(self): dst_project_name = self._item.dst_project_name dst_folder_id = self._item.dst_folder_id - dst_task_name = self._item.dst_task_name new_folder_name = self._item.new_folder_name if not dst_folder_id and not new_folder_name: self._status.set_failed( @@ -761,12 +762,11 @@ class ProjectPushItemProcess: new_folder_name ) self._folder_entity = folder_entity - if not dst_task_name: - dst_task_name = self._make_sure_task_exists(folder_entity) - if not dst_task_name: # really no task selected nor on source - self._task_info = {} - return + def _fill_or_create_destination_task(self): + folder_entity = self._folder_entity + dst_task_name = self._item.dst_task_name + dst_project_name = self._item.dst_project_name folder_path = folder_entity["path"] folder_tasks = { @@ -775,6 +775,21 @@ class ProjectPushItemProcess: dst_project_name, folder_ids=[folder_entity["id"]] ) } + + if not dst_task_name: + src_task_info = self._get_src_task_info() + if not src_task_info: # really no task selected nor on source + self._task_info = {} + return + + dst_task_name = src_task_info["name"].lower() + if dst_task_name not in folder_tasks: + self._make_sure_task_exists( + folder_entity, src_task_info + ) + task_info = copy.deepcopy(src_task_info) + folder_tasks[dst_task_name] = task_info + task_info = folder_tasks.get(dst_task_name.lower()) if not task_info: self._status.set_failed( @@ -965,9 +980,22 @@ class ProjectPushItemProcess: ) self._version_entity = version_entity - def _make_sure_task_exists(self, folder_entity: Dict[str, Any]) -> str: + def _make_sure_task_exists( + self, + folder_entity: Dict[str, Any], + task_info: Dict[str, Any], + ): """Creates destination task from source task information""" project_name = self._item.dst_project_name + _task_id = ayon_api.create_task( + project_name, + task_info["name"], + folder_id=folder_entity["id"], + task_type=task_info["taskType"], + attrib=task_info["attrib"], + ) + + def _get_src_task_info(self): src_version_entity = self._src_version_entity src_task = ayon_api.get_task_by_id( self._item.src_project_name, src_version_entity["taskId"] @@ -977,15 +1005,7 @@ class ProjectPushItemProcess: f"No task selected and couldn't find source task" ) raise PushToProjectError(self._status.fail_reason) - _task_id = ayon_api.create_task( - project_name, - src_task["name"], - folder_id=folder_entity["id"], - task_type=src_task["taskType"], - attrib=src_task["attrib"], - ) - - return src_task["name"] + return src_task def _integrate_representations(self): try: From d8dd2a23a895b06a45ec27a1c24842729aaa7189 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 10:55:48 +0200 Subject: [PATCH 06/27] Typing --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9365379148..b2475ac7d1 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -5,7 +5,7 @@ import itertools import sys import traceback import uuid -from typing import Optional, Dict +from typing import Optional, Dict, Any import ayon_api from ayon_api.utils import create_entity_id From f0230e24a7bc3a2e321caeb14bf7e33acd523eab Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 11:20:03 +0200 Subject: [PATCH 07/27] Fix use operations instead of ayon_api Must be in same session as create folder if 'Create New Folder' --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 b2475ac7d1..027416922b 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -987,7 +987,7 @@ class ProjectPushItemProcess: ): """Creates destination task from source task information""" project_name = self._item.dst_project_name - _task_id = ayon_api.create_task( + _task_id = self._operations.create_task( project_name, task_info["name"], folder_id=folder_entity["id"], From f13a40aa73b740e4cc715cd54acadf564fdb750a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 11:24:41 +0200 Subject: [PATCH 08/27] Fix typing Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/push_to_project/models/integrate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 22fcb5cf9f..6871936e2c 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -650,9 +650,9 @@ class ProjectPushItemProcess: def _create_folder( self, - src_folder_entity: Dict[str, Any], - project_entity: Dict[str, Any], - parent_folder_entity: Dict[str, Any], + src_folder_entity: dict[str, Any], + project_entity: dict[str, Any], + parent_folder_entity: dict[str, Any], folder_name: str ): parent_id = None From 87f1d458b8c6cab2195583e0e3beeef8b80e6db1 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 11:25:44 +0200 Subject: [PATCH 09/27] Change return of _check_src_folder_type Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../tools/push_to_project/models/integrate.py | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) 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 6871936e2c..bf14034673 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -731,23 +731,21 @@ class ProjectPushItemProcess: folder_entity["path"] = "/".join([parent_path, folder_name]) return folder_entity - def _check_src_folder_type( + def _get_dst_folder_type( self, - project_entity: Dict[str, Any], + project_entity: dict[str, Any], src_folder_type: str - ): - """Confirm that folder type exists in destination project""" - folder_types = [ - folder_type["name"].lower() - for folder_type in project_entity["folderTypes"] - ] + ) -> str: + """Get new folder type.""" + for folder_type in project_entity["folderTypes"]: + if folder_type["name"].lower() == src_folder_type.lower(): + return folder_type["name"] - if src_folder_type.lower() not in folder_types: - self._status.set_failed( - f"'{src_folder_type}' folder type is not configured in " - f"project Anatomy." - ) - raise PushToProjectError(self._status.fail_reason) + self._status.set_failed( + f"'{src_folder_type}' folder type is not configured in " + f"project Anatomy." + ) + raise PushToProjectError(self._status.fail_reason) def _fill_or_create_destination_folder(self): dst_project_name = self._item.dst_project_name From c50406a279b61651ef6f099862dfe6874d7dcb10 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 11:26:09 +0200 Subject: [PATCH 10/27] Simplify pop Co-authored-by: Roy Nieterau --- client/ayon_core/tools/push_to_project/models/integrate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 bf14034673..48e5763345 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1225,8 +1225,8 @@ class ProjectPushItemProcess: value_to_update = formatting_data.get(context_key) if value_to_update: repre_context[context_key] = value_to_update - if "task" not in formatting_data and "task" in repre_context: - repre_context.pop("task") + if "task" not in formatting_data: + repre_context.pop("task", None) return repre_context From 0bade2d940ced81d27d70240b153a813abf8a6c8 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 11:28:33 +0200 Subject: [PATCH 11/27] Update usage of renamed _get_dst_folder_type --- client/ayon_core/tools/push_to_project/models/integrate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 48e5763345..68a0e2affb 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -703,13 +703,13 @@ class ProjectPushItemProcess: folder_label = folder_name src_folder_type = src_folder_entity["folderType"] - self._check_src_folder_type( + dst_folder_type = self._get_dst_folder_type( project_entity, src_folder_type ) folder_entity = new_folder_entity( folder_name, - src_folder_type, + dst_folder_type, parent_id=parent_id, attribs=new_folder_attrib ) From 1ee701b52fdaafcabe9ce6a726f4d74e9a8a9da5 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 11:32:30 +0200 Subject: [PATCH 12/27] Fix dict typing --- .../tools/push_to_project/models/integrate.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 027416922b..1ecf8a8a59 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -5,7 +5,7 @@ import itertools import sys import traceback import uuid -from typing import Optional, Dict, Any +from typing import Optional, Any import ayon_api from ayon_api.utils import create_entity_id @@ -225,8 +225,8 @@ class ProjectPushRepreItem: but filenames are not template based. Args: - repre_entity (Dict[str, Ant]): Representation entity. - roots (Dict[str, str]): Project roots (based on project anatomy). + repre_entity (dict[str, Ant]): Representation entity. + roots (dict[str, str]): Project roots (based on project anatomy). """ def __init__(self, repre_entity, roots): @@ -982,8 +982,8 @@ class ProjectPushItemProcess: def _make_sure_task_exists( self, - folder_entity: Dict[str, Any], - task_info: Dict[str, Any], + folder_entity: dict[str, Any], + task_info: dict[str, Any], ): """Creates destination task from source task information""" project_name = self._item.dst_project_name @@ -1326,6 +1326,6 @@ class IntegrateModel: return item.integrate() - def get_items(self) -> Dict[str, ProjectPushItemProcess]: + def get_items(self) -> dict[str, ProjectPushItemProcess]: """Returns dict of all ProjectPushItemProcess items """ return self._process_items From 7b5ca16993bbc844d14ca27bc042e23ee58ce9bf Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 17:03:50 +0200 Subject: [PATCH 13/27] Use lower only for comparison Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/push_to_project/models/integrate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1ecf8a8a59..1cd9e2deaf 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -782,8 +782,8 @@ class ProjectPushItemProcess: self._task_info = {} return - dst_task_name = src_task_info["name"].lower() - if dst_task_name not in folder_tasks: + dst_task_name = src_task_info["name"] + if dst_task_name.lower() not in folder_tasks: self._make_sure_task_exists( folder_entity, src_task_info ) From 67994bb5a3bc8dc527a4fd09f6110049c551238e Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 17:04:07 +0200 Subject: [PATCH 14/27] Remove unnecessary variable Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1cd9e2deaf..2030027bb0 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -987,7 +987,7 @@ class ProjectPushItemProcess: ): """Creates destination task from source task information""" project_name = self._item.dst_project_name - _task_id = self._operations.create_task( + self._operations.create_task( project_name, task_info["name"], folder_id=folder_entity["id"], From cea56fbe5322075dbdb0826e78d0b2a27069b5ac Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 17:04:32 +0200 Subject: [PATCH 15/27] Formatting change Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2030027bb0..7e92d82f41 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1002,7 +1002,7 @@ class ProjectPushItemProcess: ) if not src_task: self._status.set_failed( - f"No task selected and couldn't find source task" + "No task selected and couldn't find source task" ) raise PushToProjectError(self._status.fail_reason) return src_task From 04322ef94d673cd3b4356afb6897ec7d30d8d8bb Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 17:08:35 +0200 Subject: [PATCH 16/27] Removed hard fail, unnecessary --- client/ayon_core/tools/push_to_project/models/integrate.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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 5127afd0ee..164b73e0ef 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1020,11 +1020,7 @@ class ProjectPushItemProcess: src_task = ayon_api.get_task_by_id( self._item.src_project_name, src_version_entity["taskId"] ) - if not src_task: - self._status.set_failed( - f"No task selected and couldn't find source task" - ) - raise PushToProjectError(self._status.fail_reason) + return src_task def _integrate_representations(self): From 42722c08960e528a9e9cfa735aedfd7023533bde Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 23 Oct 2025 17:20:16 +0200 Subject: [PATCH 17/27] Added validation that task type is in destination project --- .../tools/push_to_project/models/integrate.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) 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 164b73e0ef..e80a525204 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1007,11 +1007,26 @@ class ProjectPushItemProcess: ): """Creates destination task from source task information""" project_name = self._item.dst_project_name + found_task_type = False + src_task_type = task_info["taskType"] + for task_type in self._project_entity["taskTypes"]: + if task_type["name"].lower() == src_task_type.lower(): + found_task_type = True + break + + if not found_task_type: + self._status.set_failed( + f"'{src_task_type}' task type is not configured in " + "project Anatomy." + ) + + raise PushToProjectError(self._status.fail_reason) + _task_id = self._operations.create_task( project_name, task_info["name"], folder_id=folder_entity["id"], - task_type=task_info["taskType"], + task_type=src_task_type, attrib=task_info["attrib"], ) From 7e3e5855b86a31e1206c199478bddeb9829a6c80 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 11:01:24 +0200 Subject: [PATCH 18/27] Fix use of lower task name --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5370a35c37..a98c045893 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -808,7 +808,7 @@ class ProjectPushItemProcess: folder_entity, src_task_info ) task_info = copy.deepcopy(src_task_info) - folder_tasks[dst_task_name] = task_info + folder_tasks[dst_task_name.lower()] = task_info task_info = folder_tasks.get(dst_task_name.lower()) if not task_info: From f33b13c19449aed3ab9b1aa9fb45716c6418d52e Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 11:22:13 +0200 Subject: [PATCH 19/27] Fix if source version doesn't have task Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 ++ 1 file changed, 2 insertions(+) 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 a98c045893..a8cd3be2cc 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1032,6 +1032,8 @@ class ProjectPushItemProcess: def _get_src_task_info(self): src_version_entity = self._src_version_entity + if not src_version_entity["taskId"]: + return None src_task = ayon_api.get_task_by_id( self._item.src_project_name, src_version_entity["taskId"] ) From f6e4d50137f4dbcbc830639bc6e73efc054d27e1 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 12:19:31 +0200 Subject: [PATCH 20/27] Fix overwriting real task name with name of task type --- client/ayon_core/tools/push_to_project/models/integrate.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 a98c045893..5be7dbe2c1 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -828,7 +828,10 @@ class ProjectPushItemProcess: task_type["name"]: task_type for task_type in self._project_entity["taskTypes"] } - task_type_info = task_types_by_name.get(task_type_name, {}) + task_type_info = copy.deepcopy( + task_types_by_name.get(task_type_name, {}) + ) + task_type_info.pop("name") # do not overwrite real task name task_info.update(task_type_info) self._task_info = task_info From efec97fda3938f883b166fa4de26b127fc488920 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 12:20:14 +0200 Subject: [PATCH 21/27] Return task info from created object --- .../ayon_core/tools/push_to_project/models/integrate.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 5be7dbe2c1..2d02316db0 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -804,10 +804,9 @@ class ProjectPushItemProcess: dst_task_name = src_task_info["name"] if dst_task_name.lower() not in folder_tasks: - self._make_sure_task_exists( + task_info = self._make_sure_task_exists( folder_entity, src_task_info ) - task_info = copy.deepcopy(src_task_info) folder_tasks[dst_task_name.lower()] = task_info task_info = folder_tasks.get(dst_task_name.lower()) @@ -1007,7 +1006,7 @@ class ProjectPushItemProcess: self, folder_entity: dict[str, Any], task_info: dict[str, Any], - ): + ) -> dict[str, Any]: """Creates destination task from source task information""" project_name = self._item.dst_project_name found_task_type = False @@ -1025,13 +1024,15 @@ class ProjectPushItemProcess: raise PushToProjectError(self._status.fail_reason) - self._operations.create_task( + task_info = self._operations.create_task( project_name, task_info["name"], folder_id=folder_entity["id"], task_type=src_task_type, attrib=task_info["attrib"], ) + self._task_info = task_info.data + return self._task_info def _get_src_task_info(self): src_version_entity = self._src_version_entity From 636ef024b786dafe45233522aea2d92ecccd8440 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 12:20:34 +0200 Subject: [PATCH 22/27] Task is optional --- client/ayon_core/tools/push_to_project/models/integrate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 2d02316db0..fc61204bf3 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -965,8 +965,8 @@ class ProjectPushItemProcess: version = get_versioning_start( project_name, self.host_name, - task_name=self._task_info["name"], - task_type=self._task_info["taskType"], + task_name=self._task_info.get("name"), + task_type=self._task_info.get("taskType"), product_type=product_type, product_name=product_entity["name"], ) From 49162f228e9cb3bd8ceee2bad8ad54ca665b4c75 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 12:20:54 +0200 Subject: [PATCH 23/27] Fix pushed products not attaching to version --- client/ayon_core/tools/push_to_project/models/integrate.py | 1 + 1 file changed, 1 insertion(+) 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 fc61204bf3..45035671b2 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -994,6 +994,7 @@ class ProjectPushItemProcess: version_entity = new_version_entity( version, product_id, + task_id=self._task_info.get("id"), attribs=dst_attrib, thumbnail_id=thumbnail_id, ) From fcc82a8e463388e205aac4460a73fbff16552386 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 14:14:21 +0200 Subject: [PATCH 24/27] Transfer status and tags --- .../tools/push_to_project/models/integrate.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) 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 f8360c520b..8c125dd3dc 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -990,10 +990,15 @@ class ProjectPushItemProcess: existing_version_entity["attrib"].update(dst_attrib) self._version_entity = existing_version_entity return + copied_tags = self._get_transferable_tags(src_version_entity) + copied_status = self._get_transferable_status(src_version_entity) version_entity = new_version_entity( version, product_id, + author=src_version_entity["author"], + status=copied_status, + tags=copied_tags, task_id=self._task_info.get("id"), attribs=dst_attrib, thumbnail_id=thumbnail_id, @@ -1291,6 +1296,30 @@ class ProjectPushItemProcess: repre_context.pop("task", None) return repre_context + def _get_transferable_tags(self, src_version_entity): + """Copy over only tags present in destination project""" + dst_project_tags = [ + tag["name"] for tag in self._project_entity["tags"] + ] + copied_tags = [] + for src_tag in src_version_entity["tags"]: + if src_tag in dst_project_tags: + copied_tags.append(src_tag) + return copied_tags + + def _get_transferable_status(self, src_version_entity): + """Copy over status, first status if not matching found""" + dst_project_statuses = { + status["name"]: status + for status in self._project_entity["statuses"] + } + copied_status = dst_project_statuses.get(src_version_entity["status"]) + if not copied_status: + copied_status = dst_project_statuses[ + dst_project_statuses.keys()[0] + ] + return copied_status["name"] + class IntegrateModel: def __init__(self, controller): From 3104e07c78dd62ff438b122c97dbe63cf1e3b665 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 15:30:52 +0200 Subject: [PATCH 25/27] Fix access to dict keys --- client/ayon_core/tools/push_to_project/models/integrate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8c125dd3dc..838bf079ec 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1316,7 +1316,7 @@ class ProjectPushItemProcess: copied_status = dst_project_statuses.get(src_version_entity["status"]) if not copied_status: copied_status = dst_project_statuses[ - dst_project_statuses.keys()[0] + next(iter(dst_project_statuses)) ] return copied_status["name"] From 542acd0896e1ad266f7764811817212dc4ab6d06 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 15:33:15 +0200 Subject: [PATCH 26/27] Fix access to dict keys --- client/ayon_core/tools/push_to_project/models/integrate.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 838bf079ec..e23d2a8eb2 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1313,8 +1313,13 @@ class ProjectPushItemProcess: status["name"]: status for status in self._project_entity["statuses"] } - copied_status = dst_project_statuses.get(src_version_entity["status"]) + source_status = src_version_entity["status"] + copied_status = dst_project_statuses.get(source_status) if not copied_status: + self._log_warning( + f"'{source_status}' not found in destination project. " + "Used first configured status from there." + ) copied_status = dst_project_statuses[ next(iter(dst_project_statuses)) ] From fcebdaf13006aeeefd2979ceac24304dee9cd618 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Oct 2025 16:00:42 +0200 Subject: [PATCH 27/27] Do not send dummy status if not found --- .../tools/push_to_project/models/integrate.py | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) 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 e23d2a8eb2..2adc708cf3 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -1284,10 +1284,12 @@ class ProjectPushItemProcess: if context_value and isinstance(context_value, dict): for context_sub_key in context_value.keys(): value_to_update = formatting_data.get(context_key, {}).get( - context_sub_key) + context_sub_key + ) if value_to_update: - repre_context[context_key][ - context_sub_key] = value_to_update + repre_context[context_key][context_sub_key] = ( + value_to_update + ) else: value_to_update = formatting_data.get(context_key) if value_to_update: @@ -1313,17 +1315,10 @@ class ProjectPushItemProcess: status["name"]: status for status in self._project_entity["statuses"] } - source_status = src_version_entity["status"] - copied_status = dst_project_statuses.get(source_status) - if not copied_status: - self._log_warning( - f"'{source_status}' not found in destination project. " - "Used first configured status from there." - ) - copied_status = dst_project_statuses[ - next(iter(dst_project_statuses)) - ] - return copied_status["name"] + copied_status = dst_project_statuses.get(src_version_entity["status"]) + if copied_status: + return copied_status["name"] + return None class IntegrateModel: