From bdb201700954eb9cf63c673ec2ebfb60049f2e20 Mon Sep 17 00:00:00 2001 From: "Sveinbjorn J. Tryggvason" Date: Tue, 1 Jul 2025 10:51:14 +0000 Subject: [PATCH 01/13] allow settings to dictate item names in the inventory --- .../ayon_core/tools/sceneinventory/model.py | 55 +++++++++++++++++-- server/settings/tools.py | 40 +++++++++++++- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 885553acaf..67ff700806 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -9,6 +9,9 @@ import qtawesome from ayon_core.style import get_default_entity_icon_color from ayon_core.tools.utils import get_qt_icon from ayon_core.tools.utils.lib import format_version +from ayon_core.pipeline import template_data +from ayon_core.lib import filter_profiles +from ayon_core.settings import get_project_settings ITEM_ID_ROLE = QtCore.Qt.UserRole + 1 NAME_COLOR_ROLE = QtCore.Qt.UserRole + 2 @@ -127,13 +130,57 @@ class InventoryModel(QtGui.QStandardItemModel): def outdated(self, item): return item.get("isOutdated", True) + def generate_group_formatting_data(self, repre_info): + hierarchy_parts = repre_info.folder_path.split("/") + hierarchy_parts.pop(0) + hierarchy_parts.pop(-1) + + folder = { + "name": repre_info.folder_name, + "id": repre_info.folder_id, + "folderType": repre_info.folder_type, + "path": repre_info.folder_type + } + extra_folder_keys = template_data.construct_extra_folder_template_keys( + self._controller.get_current_project_name(), + folder, + hierarchy_parts + ) + + formatting_data = { + "folder": { + "name": repre_info.folder_name, + **extra_folder_keys + }, + "product": repre_info.product_name, + "productType": repre_info.product_type, + "representation": repre_info.representation_name + } + return formatting_data + def refresh(self, selected=None): """Refresh the model""" # for debugging or testing, injecting items from outside container_items = self._controller.get_container_items() self._clear_items() + # fetch the label settings + settings = get_project_settings( + self._controller.get_current_project_name()) + + profiles = (settings["core"]["tools"]["inventory"]["profiles"]) + + selected_profile = filter_profiles( + profiles, + { + "host_name": self._controller.get_host().name, + "task_name": self._controller.get_current_context()["task_name"] + }, + keys_order=["host_name", "task_name"]) + group_name_template = selected_profile["inventory_name_format"] + + items_by_repre_id = {} project_names = set() repre_ids_by_project = collections.defaultdict(set) version_items_by_project = collections.defaultdict(dict) @@ -250,11 +297,9 @@ class InventoryModel(QtGui.QStandardItemModel): status_name = None else: - group_name = "{}_{}: ({})".format( - repre_info.folder_path.rsplit("/")[-1], - repre_info.product_name, - repre_info.representation_name - ) + fmt_data = self.generate_group_formatting_data(repre_info) + group_name = group_name_template.format(**fmt_data) + item_icon = valid_item_icon version_items = ( diff --git a/server/settings/tools.py b/server/settings/tools.py index 815ef40f8e..72ae63c162 100644 --- a/server/settings/tools.py +++ b/server/settings/tools.py @@ -368,6 +368,28 @@ class PublishToolModel(BaseSettingsModel): ) +class InventoryTemplateNameProfile(BaseSettingsModel): + _layout = "expanded" + host_name: list[str] = SettingsField( + title="Host name", + default_factory=list + ) + task_name: list[str] = SettingsField( + title="Current task", + default_factory=list + ) + inventory_name_format: str = SettingsField( + title="Format", + default_factory=str + ) + + +class InventoryToolModel(BaseSettingsModel): + profiles: list[InventoryTemplateNameProfile] = SettingsField( + default_factory=list, + title="Inventory label templates" + ) + class GlobalToolsModel(BaseSettingsModel): ayon_menu: AYONMenuModel = SettingsField( default_factory=AYONMenuModel, @@ -389,6 +411,10 @@ class GlobalToolsModel(BaseSettingsModel): default_factory=PublishToolModel, title="Publish" ) + inventory: InventoryToolModel = SettingsField( + default_factory=InventoryToolModel, + title="Inventory" + ) DEFAULT_TOOLS_VALUES = { @@ -679,7 +705,17 @@ DEFAULT_TOOLS_VALUES = { "task_names": [], "template_name": "simpleUnrealTextureHero" } - ], - "comment_minimum_required_chars": 0, + ] + }, + "comment_minimum_required_chars": 0, + "inventory": { + "profiles": [ + { + "host_name": [], + "task_name": [], + "inventory_name_format": "{folder[name]}_{product}: ({representation})", + }, + + ] } } From 9cf63f26272241f4d51caab604eb402263aa57e7 Mon Sep 17 00:00:00 2001 From: "Sveinbjorn J. Tryggvason" Date: Tue, 1 Jul 2025 11:04:46 +0000 Subject: [PATCH 02/13] add some missing code, remove rvx-specific folder keys --- .../ayon_core/tools/sceneinventory/model.py | 21 +++++++------------ .../tools/sceneinventory/models/containers.py | 9 ++++++++ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 67ff700806..2997d5cfd8 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -131,31 +131,24 @@ class InventoryModel(QtGui.QStandardItemModel): return item.get("isOutdated", True) def generate_group_formatting_data(self, repre_info): - hierarchy_parts = repre_info.folder_path.split("/") - hierarchy_parts.pop(0) - hierarchy_parts.pop(-1) - - folder = { + fake_folder_entity = { "name": repre_info.folder_name, "id": repre_info.folder_id, "folderType": repre_info.folder_type, - "path": repre_info.folder_type + "path": repre_info.folder_path } - extra_folder_keys = template_data.construct_extra_folder_template_keys( - self._controller.get_current_project_name(), - folder, - hierarchy_parts + + folder_data = template_data.get_folder_template_data( + fake_folder_entity, + self._controller.get_current_project_name() ) formatting_data = { - "folder": { - "name": repre_info.folder_name, - **extra_folder_keys - }, "product": repre_info.product_name, "productType": repre_info.product_type, "representation": repre_info.representation_name } + formatting_data.update(folder_data) return formatting_data def refresh(self, selected=None): diff --git a/client/ayon_core/tools/sceneinventory/models/containers.py b/client/ayon_core/tools/sceneinventory/models/containers.py index f841f87c8e..c78a166abc 100644 --- a/client/ayon_core/tools/sceneinventory/models/containers.py +++ b/client/ayon_core/tools/sceneinventory/models/containers.py @@ -41,6 +41,7 @@ def representations_parent_ids_qraphql_query(): folder_field = product_field.add_field("folder") folder_field.add_field("id") folder_field.add_field("path") + folder_field.add_field("folderType") return query @@ -123,6 +124,8 @@ class RepresentationInfo: self, folder_id, folder_path, + folder_name, + folder_type, product_id, product_name, product_type, @@ -132,6 +135,8 @@ class RepresentationInfo: ): self.folder_id = folder_id self.folder_path = folder_path + self.folder_name = folder_name + self.folder_type = folder_type self.product_id = product_id self.product_name = product_name self.product_type = product_type @@ -250,6 +255,8 @@ class ContainersModel: kwargs = { "folder_id": None, "folder_path": None, + "folder_name": None, + "folder_type": None, "product_id": None, "product_name": None, "product_type": None, @@ -264,6 +271,8 @@ class ContainersModel: if folder: kwargs["folder_id"] = folder["id"] kwargs["folder_path"] = folder["path"] + kwargs["folder_name"] = folder["path"].split("/")[-1] + kwargs["folder_type"] = folder["folderType"] if product: group = product["attrib"]["productGroup"] kwargs["product_id"] = product["id"] From 42d6a74ffbd718322561894d218ae1b801c8b2e0 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:16:19 +0000 Subject: [PATCH 03/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 2997d5cfd8..52d2a94d05 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -171,7 +171,10 @@ class InventoryModel(QtGui.QStandardItemModel): "task_name": self._controller.get_current_context()["task_name"] }, keys_order=["host_name", "task_name"]) - group_name_template = selected_profile["inventory_name_format"] + group_name_template = "{folder[name]}_{product[name]}: ({representation[name]})" + if selected_profile is not None: + group_name_template = selected_profile["inventory_name_format"] + items_by_repre_id = {} project_names = set() From 06bc6baae3bb86a64fb1a0375bfa4a32c188c79f Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:16:31 +0000 Subject: [PATCH 04/13] Update server/settings/tools.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/tools.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/server/settings/tools.py b/server/settings/tools.py index 72ae63c162..875fb008fc 100644 --- a/server/settings/tools.py +++ b/server/settings/tools.py @@ -709,13 +709,6 @@ DEFAULT_TOOLS_VALUES = { }, "comment_minimum_required_chars": 0, "inventory": { - "profiles": [ - { - "host_name": [], - "task_name": [], - "inventory_name_format": "{folder[name]}_{product}: ({representation})", - }, - - ] + "profiles": [] } } From b156f18f07d2c96e9963ee048d38072b02093b02 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:16:42 +0000 Subject: [PATCH 05/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 52d2a94d05..fac1e52b50 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -144,9 +144,13 @@ class InventoryModel(QtGui.QStandardItemModel): ) formatting_data = { - "product": repre_info.product_name, - "productType": repre_info.product_type, - "representation": repre_info.representation_name + "product": { + "name": repre_info.product_name, + "type": repre_info.product_type, + }, + "representation": { + "name": repre_info.representation_name, + } } formatting_data.update(folder_data) return formatting_data From ca3817ffbac634afd5023267342525888e507320 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:16:49 +0000 Subject: [PATCH 06/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index fac1e52b50..5e1257219f 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -166,10 +166,8 @@ class InventoryModel(QtGui.QStandardItemModel): settings = get_project_settings( self._controller.get_current_project_name()) - profiles = (settings["core"]["tools"]["inventory"]["profiles"]) - selected_profile = filter_profiles( - profiles, + settings["core"]["tools"]["inventory"]["profiles"], { "host_name": self._controller.get_host().name, "task_name": self._controller.get_current_context()["task_name"] From 3393d99ea8d3db198d70d2432276c4a38ba7e5d7 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:16:59 +0000 Subject: [PATCH 07/13] Update server/settings/tools.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/settings/tools.py b/server/settings/tools.py index 875fb008fc..228d1b8d88 100644 --- a/server/settings/tools.py +++ b/server/settings/tools.py @@ -378,8 +378,8 @@ class InventoryTemplateNameProfile(BaseSettingsModel): title="Current task", default_factory=list ) - inventory_name_format: str = SettingsField( - title="Format", + template: str = SettingsField( + title="Template", default_factory=str ) From 9aab2479b21c9011acc74d031b4878839b6b1c58 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:17:06 +0000 Subject: [PATCH 08/13] Update server/settings/tools.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/settings/tools.py b/server/settings/tools.py index 228d1b8d88..cce2b90a54 100644 --- a/server/settings/tools.py +++ b/server/settings/tools.py @@ -370,12 +370,12 @@ class PublishToolModel(BaseSettingsModel): class InventoryTemplateNameProfile(BaseSettingsModel): _layout = "expanded" - host_name: list[str] = SettingsField( - title="Host name", + host_names: list[str] = SettingsField( + title="Host names", default_factory=list ) task_name: list[str] = SettingsField( - title="Current task", + title="Task names", default_factory=list ) template: str = SettingsField( From d18acdacb59d4dbfdee76188d4fa57647a4bc4b8 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:17:37 +0000 Subject: [PATCH 09/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 5e1257219f..661aeb46d7 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -130,7 +130,7 @@ class InventoryModel(QtGui.QStandardItemModel): def outdated(self, item): return item.get("isOutdated", True) - def generate_group_formatting_data(self, repre_info): + def _get_repre_info_template_data(self, repre_info): fake_folder_entity = { "name": repre_info.folder_name, "id": repre_info.folder_id, From 577db91ccddb26cce50e4c5f067692b139c84bba Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:17:44 +0000 Subject: [PATCH 10/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 661aeb46d7..6c5ab11adf 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -143,7 +143,7 @@ class InventoryModel(QtGui.QStandardItemModel): self._controller.get_current_project_name() ) - formatting_data = { + template_data = { "product": { "name": repre_info.product_name, "type": repre_info.product_type, From 5b52bbcea04ed2242329bfe1abc777704310183d Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:17:53 +0000 Subject: [PATCH 11/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index 6c5ab11adf..a828721f4c 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -152,8 +152,8 @@ class InventoryModel(QtGui.QStandardItemModel): "name": repre_info.representation_name, } } - formatting_data.update(folder_data) - return formatting_data + template_data .update(folder_data) + return template_data def refresh(self, selected=None): """Refresh the model""" From 2630ca88b6fe12eb472d442a54864c2eb41de638 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:18:00 +0000 Subject: [PATCH 12/13] Update server/settings/tools.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/tools.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server/settings/tools.py b/server/settings/tools.py index cce2b90a54..432b98d84b 100644 --- a/server/settings/tools.py +++ b/server/settings/tools.py @@ -390,6 +390,7 @@ class InventoryToolModel(BaseSettingsModel): title="Inventory label templates" ) + class GlobalToolsModel(BaseSettingsModel): ayon_menu: AYONMenuModel = SettingsField( default_factory=AYONMenuModel, From da381c423de8b4fb211bd2dad7c1baeee78c41c6 Mon Sep 17 00:00:00 2001 From: sjt-rvx <72554834+sjt-rvx@users.noreply.github.com> Date: Wed, 2 Jul 2025 10:18:07 +0000 Subject: [PATCH 13/13] Update client/ayon_core/tools/sceneinventory/model.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/tools/sceneinventory/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index a828721f4c..af5afc6d38 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -295,8 +295,8 @@ class InventoryModel(QtGui.QStandardItemModel): status_name = None else: - fmt_data = self.generate_group_formatting_data(repre_info) - group_name = group_name_template.format(**fmt_data) + template_data = self._get_repre_info_template_data(repre_info) + group_name = group_name_template.format(**template_data) item_icon = valid_item_icon