From b3c5f50f22a397e178ae067ed81295a5397d74a5 Mon Sep 17 00:00:00 2001 From: Martastain Date: Tue, 29 Oct 2024 17:07:59 +0100 Subject: [PATCH 1/5] fix: use existing project anatomy as base when patching project --- server/kitsu/anatomy.py | 19 +++++-- server/kitsu/extract_ayon_project_anatomy.py | 58 ++++++++++++++++++++ server/kitsu/push.py | 2 +- 3 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 server/kitsu/extract_ayon_project_anatomy.py diff --git a/server/kitsu/anatomy.py b/server/kitsu/anatomy.py index bf14a6f..5f8012d 100644 --- a/server/kitsu/anatomy.py +++ b/server/kitsu/anatomy.py @@ -1,6 +1,9 @@ import contextlib from typing import TYPE_CHECKING, Any +from nxtools import logging + +from ayon_server.entities import ProjectEntity from ayon_server.exceptions import AyonException from ayon_server.lib.postgres import Postgres from ayon_server.settings.anatomy import Anatomy @@ -8,11 +11,11 @@ from ayon_server.settings.anatomy.task_types import TaskType from .addon_helpers import create_short_name, remove_accents +from .extract_ayon_project_anatomy import extract_ayon_project_anatomy if TYPE_CHECKING: from .. import KitsuAddon - async def parse_task_types( addon: "KitsuAddon", kitsu_project_id: str ) -> list[TaskType]: @@ -199,6 +202,7 @@ async def get_primary_anatomy_preset() -> Anatomy: async def get_kitsu_project_anatomy( addon: "KitsuAddon", kitsu_project_id: str, + ayon_project: ProjectEntity | None = None, ) -> Anatomy: kitsu_project_response = await addon.kitsu.get( f"data/projects/{kitsu_project_id}" @@ -212,13 +216,18 @@ async def get_kitsu_project_anatomy( statuses = await parse_statuses(addon, kitsu_project_id) task_types = await parse_task_types(addon, kitsu_project_id) - anatomy_preset = await get_primary_anatomy_preset() - anatomy_dict = anatomy_preset.dict() + if ayon_project: + anatomy = extract_ayon_project_anatomy(ayon_project) + else: + anatomy = await get_primary_anatomy_preset() + + anatomy_dict = anatomy.dict() for key in anatomy_dict["attributes"]: if key in attributes: - anatomy_dict["attributes"][key]=attributes[key] + anatomy_dict["attributes"][key] = attributes[key] + logging.debug("updated", key, "to", attributes[key]) + - #anatomy_dict["attributes"] = attributes anatomy_dict["statuses"] = statuses anatomy_dict["task_types"] = task_types diff --git a/server/kitsu/extract_ayon_project_anatomy.py b/server/kitsu/extract_ayon_project_anatomy.py new file mode 100644 index 0000000..9d9a093 --- /dev/null +++ b/server/kitsu/extract_ayon_project_anatomy.py @@ -0,0 +1,58 @@ +from typing import Any +from ayon_server.entities import ProjectEntity +from ayon_server.entities.models.submodels import LinkTypeModel +from ayon_server.settings.anatomy import Anatomy + + +def dict2list(src) -> list[dict[str, Any]]: + return [{"name": k, "original_name": k, **v} for k, v in src.items()] + + +def process_aux_table(src: list[dict[str, Any]]) -> list[dict[str, Any]]: + """Process auxiliary table.""" + result = [] + for data in src: + result.append({**data, "original_name": data["name"]}) + return result + + +def process_link_types(src: list[LinkTypeModel]) -> list[dict[str, Any]]: + """Convert project linktypes sumbmodel to anatomy-style linktypes.""" + result = [] + for ltdata in src: + row = { + "link_type": ltdata.link_type, + "input_type": ltdata.input_type, + "output_type": ltdata.output_type, + } + for key in ["color", "style"]: + if value := ltdata.data.get(key): + row[key] = value + result.append(row) + return result + + +def extract_ayon_project_anatomy(project: ProjectEntity) -> Anatomy: + """Extract Anatomy object from ayon ProjectEntity.""" + + templates = project.config.get("templates", {}).get("common", {}) + for template_group, template_group_def in project.config.get( + "templates", {} + ).items(): + if template_group == "common": + continue + templates[template_group] = dict2list(template_group_def) + + result = { + "templates": templates, + "roots": dict2list(project.config.get("roots", {})), + "folder_types": process_aux_table(project.folder_types), + "task_types": process_aux_table(project.task_types), + "link_types": process_link_types(project.link_types), + "statuses": process_aux_table(project.statuses), + "tags": process_aux_table(project.tags), + "attributes": project.attrib, + } + + return Anatomy(**result) + diff --git a/server/kitsu/push.py b/server/kitsu/push.py index 757ddfd..dce2946 100644 --- a/server/kitsu/push.py +++ b/server/kitsu/push.py @@ -330,7 +330,7 @@ async def sync_project( return await addon.ensure_kitsu(mock) - anatomy = await get_kitsu_project_anatomy(addon, entity_id) + anatomy = await get_kitsu_project_anatomy(addon, entity_id, project) anatomy_data = anatomy_to_project_data(anatomy) await update_project(project.name, **anatomy_data) From 1e575d21127c3f3cef11463841b6249652cb335c Mon Sep 17 00:00:00 2001 From: Martin Wacker Date: Wed, 30 Oct 2024 13:29:13 +0100 Subject: [PATCH 2/5] Update server/kitsu/extract_ayon_project_anatomy.py Co-authored-by: Roy Nieterau --- server/kitsu/extract_ayon_project_anatomy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/kitsu/extract_ayon_project_anatomy.py b/server/kitsu/extract_ayon_project_anatomy.py index 9d9a093..e7cddd8 100644 --- a/server/kitsu/extract_ayon_project_anatomy.py +++ b/server/kitsu/extract_ayon_project_anatomy.py @@ -17,7 +17,7 @@ def process_aux_table(src: list[dict[str, Any]]) -> list[dict[str, Any]]: def process_link_types(src: list[LinkTypeModel]) -> list[dict[str, Any]]: - """Convert project linktypes sumbmodel to anatomy-style linktypes.""" + """Convert project linktypes submodel to anatomy-style linktypes.""" result = [] for ltdata in src: row = { From 08bf4ce3feec4dc319342bcf645a3a64d0528228 Mon Sep 17 00:00:00 2001 From: Martin Wacker Date: Wed, 30 Oct 2024 13:29:36 +0100 Subject: [PATCH 3/5] Update server/kitsu/anatomy.py Co-authored-by: Roy Nieterau --- server/kitsu/anatomy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/kitsu/anatomy.py b/server/kitsu/anatomy.py index 5f8012d..2694e3e 100644 --- a/server/kitsu/anatomy.py +++ b/server/kitsu/anatomy.py @@ -225,7 +225,7 @@ async def get_kitsu_project_anatomy( for key in anatomy_dict["attributes"]: if key in attributes: anatomy_dict["attributes"][key] = attributes[key] - logging.debug("updated", key, "to", attributes[key]) + logging.debug("updated project", ayon_project.name, "anatomy attribute", key, "to", attributes[key]) anatomy_dict["statuses"] = statuses From c4bc5aad9cef8c93628a94e8105ab632553342dc Mon Sep 17 00:00:00 2001 From: Martastain Date: Fri, 8 Nov 2024 15:16:43 +0100 Subject: [PATCH 4/5] doc: add note about backwards compatibility of extract anatomy function --- server/kitsu/extract_ayon_project_anatomy.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/server/kitsu/extract_ayon_project_anatomy.py b/server/kitsu/extract_ayon_project_anatomy.py index e7cddd8..7fdc015 100644 --- a/server/kitsu/extract_ayon_project_anatomy.py +++ b/server/kitsu/extract_ayon_project_anatomy.py @@ -1,3 +1,16 @@ +"""Extract Anatomy object from ayon ProjectEntity. + +This file is for the backwards compatibility with Ayon server. + +This funciton is a part of the server from version 1.5.1, so we +can remove this file after a grace period. + +``` +from ayon_server.helpers.extract_anatomy import extract_project_anatomy +``` + +""" + from typing import Any from ayon_server.entities import ProjectEntity from ayon_server.entities.models.submodels import LinkTypeModel From f1ab2bf8ceced826f85c9b1012cbe57061dff8cc Mon Sep 17 00:00:00 2001 From: Martastain Date: Fri, 8 Nov 2024 15:56:49 +0100 Subject: [PATCH 5/5] chore: linting, fix project name --- server/kitsu/anatomy.py | 19 +++++++++++++++---- server/kitsu/extract_ayon_project_anatomy.py | 2 +- server/kitsu/push.py | 7 +++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/server/kitsu/anatomy.py b/server/kitsu/anatomy.py index 2694e3e..ac2cc8e 100644 --- a/server/kitsu/anatomy.py +++ b/server/kitsu/anatomy.py @@ -1,14 +1,13 @@ import contextlib from typing import TYPE_CHECKING, Any -from nxtools import logging - from ayon_server.entities import ProjectEntity from ayon_server.exceptions import AyonException from ayon_server.lib.postgres import Postgres from ayon_server.settings.anatomy import Anatomy from ayon_server.settings.anatomy.statuses import Status from ayon_server.settings.anatomy.task_types import TaskType +from nxtools import logging from .addon_helpers import create_short_name, remove_accents from .extract_ayon_project_anatomy import extract_ayon_project_anatomy @@ -16,6 +15,7 @@ if TYPE_CHECKING: from .. import KitsuAddon + async def parse_task_types( addon: "KitsuAddon", kitsu_project_id: str ) -> list[TaskType]: @@ -221,12 +221,23 @@ async def get_kitsu_project_anatomy( else: anatomy = await get_primary_anatomy_preset() + if ayon_project: + prj_name = ayon_project.name + else: + prj_name = "new project" + anatomy_dict = anatomy.dict() for key in anatomy_dict["attributes"]: if key in attributes: anatomy_dict["attributes"][key] = attributes[key] - logging.debug("updated project", ayon_project.name, "anatomy attribute", key, "to", attributes[key]) - + logging.debug( + "updated project", + prj_name, + "anatomy attribute", + key, + "to", + attributes[key], + ) anatomy_dict["statuses"] = statuses anatomy_dict["task_types"] = task_types diff --git a/server/kitsu/extract_ayon_project_anatomy.py b/server/kitsu/extract_ayon_project_anatomy.py index 7fdc015..4320997 100644 --- a/server/kitsu/extract_ayon_project_anatomy.py +++ b/server/kitsu/extract_ayon_project_anatomy.py @@ -1,6 +1,6 @@ """Extract Anatomy object from ayon ProjectEntity. -This file is for the backwards compatibility with Ayon server. +This file is for the backwards compatibility with Ayon server. This funciton is a part of the server from version 1.5.1, so we can remove this file after a grace period. diff --git a/server/kitsu/push.py b/server/kitsu/push.py index dce2946..7bdaf36 100644 --- a/server/kitsu/push.py +++ b/server/kitsu/push.py @@ -550,6 +550,13 @@ async def sync_task( return logging.info(f"Creating {entity_dict['type']} '{entity_dict['name']}'") + + if "task_type_name" not in entity_dict: + logging.warning( + f"Task type not found for {entity_dict['name']}'" + ) + return + target_task = await create_task( project_name=project.name, folder_id=parent_id,