From 3d6099e5b001038148ed8dace0a6bae1a345c19d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 24 Apr 2024 16:15:34 +0200 Subject: [PATCH 01/22] Update data dictionary to set sync status to "Failed" if ID is not set. Improve readability and avoid conflicts with Ayon attributes. --- services/shotgrid_common/utils.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 9bda87ba..47c98b56 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -78,7 +78,15 @@ def _sg_to_ay_dict( SHOTGRID_TYPE_ATTRIB: sg_entity["type"], }, "data": { - CUST_FIELD_CODE_SYNC: sg_entity.get(CUST_FIELD_CODE_SYNC), + # We store the ShotGrid ID and the Sync status in the data + # dictionary so we can easily access them when needed + # And avoid any conflicts with the Ayon attributes we only set + # sync status to "Failed" if the ID is not set + CUST_FIELD_CODE_SYNC: ( + sg_entity.get(CUST_FIELD_CODE_SYNC) + if sg_entity.get(CUST_FIELD_CODE_ID) + else "Failed" + ), CUST_FIELD_CODE_ID: sg_entity.get(CUST_FIELD_CODE_ID), } } From 75c31bdb2fd954113324a6b21622fa73061a4df3 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 25 Apr 2024 16:13:07 +0200 Subject: [PATCH 02/22] Update Ayon entities from ShotGrid events, handle status sync and entity creation. Add logging for errors and warnings. --- .../ayon_shotgrid_hub/__init__.py | 2 ++ .../match_shotgrid_hierarchy_in_ayon.py | 15 ++++++++-- .../ayon_shotgrid_hub/update_from_shotgrid.py | 28 +++++++++++++++++-- services/shotgrid_common/utils.py | 10 +++++-- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/__init__.py b/services/shotgrid_common/ayon_shotgrid_hub/__init__.py index cafa4504..921aad12 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/__init__.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/__init__.py @@ -363,8 +363,10 @@ def react_to_shotgrid_event(self, sg_event): case "attribute_change": update_ayon_entity_from_sg_event( sg_event, + self._sg_project, self._sg, self._ay_project, + self.sg_enabled_entities, self.sg_project_code_field, self.custom_attribs_map, ) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index 2dc7c1c0..2e6008bc 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -171,7 +171,7 @@ def match_shotgrid_hierarchy_in_ayon( for ay_attrib, sg_attrib in custom_attribs_map.items(): attrib_value = sg_project.get(sg_attrib) \ or sg_project.get(f"sg_{sg_attrib}") - + logging.debug(f"Checking {sg_attrib} -> {attrib_value}") if attrib_value is None: continue @@ -229,11 +229,20 @@ def _create_new_entity(entity_hub, parent_entity, sg_ay_dict): attribs=sg_ay_dict["attribs"], data=sg_ay_dict["data"], ) - + # TODO: this doesn't work yet status = sg_ay_dict["attribs"].get("status") if status: - ay_entity.status = status + logging.debug(f"Entity '{sg_ay_dict['name']}' status sync: '{status}'") + # TODO: Implement status update + try: + # INFO: it was causing error so trying to set status directly + logging.warning("Status update is not supported yet.") + ay_entity.status = status + except ValueError as e: + # `ValueError: Status ip is not available on project.` + logging.error(f"Error updating status: {e}") + tags = sg_ay_dict["attribs"].get("tags") if tags: diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index 4bc9027a..f643fecb 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -214,17 +214,21 @@ def create_ay_entity_from_sg_event( def update_ayon_entity_from_sg_event( sg_event, + sg_project, sg_session, ayon_entity_hub, + sg_enabled_entities, project_code_field, - custom_attribs_map + custom_attribs_map=None, ): """Try to update an entity in Ayon. Args: sg_event (dict): The `meta` key from a ShotGrid Event. + sg_project (dict): The ShotGrid project. sg_session (shotgun_api3.Shotgun): The ShotGrid API session. ayon_entity_hub (ayon_api.entity_hub.EntityHub): The AYON EntityHub. + sg_enabled_entities (list[str]): List of entity strings enabled. project_code_field (str): The ShotGrid project code field. custom_attribs_map (dict): A dictionary that maps ShotGrid attributes to Ayon attributes. @@ -242,7 +246,27 @@ def update_ayon_entity_from_sg_event( ) if not sg_ay_dict["data"].get(CUST_FIELD_CODE_ID): - logging.warning("ShotGrid Missing Ayon ID") + # if the entity does not have an Ayon ID, try to create it + logging.warning("ShotGrid Missing Ayon ID.") + + logging.debug(f"Creating Ayon Entity: {sg_ay_dict}") + try: + create_ay_entity_from_sg_event( + sg_event, + sg_project, + sg_session, + ayon_entity_hub, + sg_enabled_entities, + project_code_field, + custom_attribs_map + ) + except Exception as e: + logging.error(f"Ayon Entity could not be created: {e}") + logging.warning( + "Skipping update of Ayon Entity. ShotGrid ID missing " + "and entity could not be created." + ) + return ay_entity = ayon_entity_hub.get_or_query_entity_by_id( sg_ay_dict["data"].get(CUST_FIELD_CODE_ID), diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 47c98b56..3f1696a0 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -992,6 +992,12 @@ def update_ay_entity_custom_attributes( ay_entity.tags = [tag["name"] for tag in attrib_value] elif ay_attrib == "status": logging.warning("Status update is not supported yet.") - ay_entity.status = attrib_value + # TODO: Implement status update + try: + # INFO: it was causing error so trying to set status directly + ay_entity.status = attrib_value + except ValueError as e: + # `ValueError: Status ip is not available on project.` + logging.error(f"Error updating status: {e}") else: - ay_entity.attribs.set(ay_attrib, attrib_value) \ No newline at end of file + ay_entity.attribs.set(ay_attrib, attrib_value) From 59d0ede5f9a9ab1e6557d3e091c72ef2ff6ffa38 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 29 Apr 2024 12:53:17 +0200 Subject: [PATCH 03/22] Update custom attributes mapping and add TODO for handling status_list and tags. Improve code readability. --- services/leecher/leecher/listener.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/services/leecher/leecher/listener.py b/services/leecher/leecher/listener.py index bbb1ae19..11918918 100644 --- a/services/leecher/leecher/listener.py +++ b/services/leecher/leecher/listener.py @@ -71,10 +71,12 @@ def __init__(self, func: Union[Callable, None] = None): for attr in self.settings["compatibility_settings"]["custom_attribs_map"] # noqa: E501 if attr["sg"] } - self.custom_attribs_map.update({ - "status": "status_list", - "tags": "tags" - }) + + # TODO: implement a way to handle status_list and tags + # self.custom_attribs_map.update({ + # "status": "status_list", + # "tags": "tags" + # }) self.sg_enabled_entities = self.settings["compatibility_settings"]["shotgrid_enabled_entities"] # noqa: E501 From c865427c478d0ff6b9972806807e2e39f97a8373 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 29 Apr 2024 12:54:08 +0200 Subject: [PATCH 04/22] Update custom attributes handling and entity creation logic in AyonShotgridHub. Refactor attribute types assignment. Improve entity creation based on Shotgrid events, considering asset type and parent entity type for better accuracy. --- .../shotgrid_common/ayon_shotgrid_hub/__init__.py | 3 +-- .../ayon_shotgrid_hub/update_from_shotgrid.py | 11 +++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/__init__.py b/services/shotgrid_common/ayon_shotgrid_hub/__init__.py index 921aad12..94993e77 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/__init__.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/__init__.py @@ -107,8 +107,7 @@ def __init__(self, if custom_attribs_map: self.custom_attribs_map.update(custom_attribs_map) - if custom_attribs_types: - self.custom_attribs_types = custom_attribs_types + self.custom_attribs_types = custom_attribs_types if sg_enabled_entities: self.sg_enabled_entities = sg_enabled_entities diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index f643fecb..78927b55 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -139,7 +139,7 @@ def create_ay_entity_from_sg_event( ay_parent_entity = get_asset_category( ayon_entity_hub, ayon_entity_hub.project_entity, - sg_ay_dict.get("sg_asset_type").lower() + sg_ay_dict["data"].get("sg_asset_type").lower(), ) else: @@ -155,9 +155,12 @@ def create_ay_entity_from_sg_event( ay_parent_entity = ayon_entity_hub.get_or_query_entity_by_id( sg_parent_entity_dict["data"].get(CUST_FIELD_CODE_ID), [ - "task" if sg_parent_entity_dict["data"].get( - CUST_FIELD_CODE_ID).lower() == "task" else "folder" - ] + ( + "task" + if sg_parent_entity_dict["type"] == "task" + else "folder" + ) + ], ) if not ay_parent_entity: From 1b5f9be31d640e7ad44573cc782c7b8558ca7839 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 2 May 2024 15:02:39 +0200 Subject: [PATCH 05/22] Update custom attributes map and logging in ShotgridListener. Refactor match_shotgrid_hierarchy_in_ayon for efficiency, add debug logs. Create or find AssetCategory in AYON based on ShotGrid entity. Fix create_sg_entities_in_ay function signature and add missing code block in get_asset_category function. --- services/leecher/leecher/listener.py | 15 +++-- .../match_shotgrid_hierarchy_in_ayon.py | 43 +++++++++---- .../ayon_shotgrid_hub/update_from_shotgrid.py | 2 +- services/shotgrid_common/utils.py | 64 +++++++++++++++++-- 4 files changed, 101 insertions(+), 23 deletions(-) diff --git a/services/leecher/leecher/listener.py b/services/leecher/leecher/listener.py index 11918918..2391ba5e 100644 --- a/services/leecher/leecher/listener.py +++ b/services/leecher/leecher/listener.py @@ -73,10 +73,10 @@ def __init__(self, func: Union[Callable, None] = None): } # TODO: implement a way to handle status_list and tags - # self.custom_attribs_map.update({ - # "status": "status_list", - # "tags": "tags" - # }) + self.custom_attribs_map.update({ + # "status": "status_list", + "tags": "tags" + }) self.sg_enabled_entities = self.settings["compatibility_settings"]["shotgrid_enabled_entities"] # noqa: E501 @@ -223,7 +223,12 @@ def start_listening(self): event["event_type"].endswith("_Change") and event["attribute_name"].replace("sg_", "") not in list(self.custom_attribs_map.values()) ): - logging.debug(f"Skipping event for attribute change '{event['attribute_name'].replace('sg_', '')}', as we can't handle it.") + logging.debug( + f"Skipping event for attribute change " + f"'{event['attribute_name'].replace('sg_', '')}', " + "as we can't handle it." + ) + logging.debug(f"Event: {event}") last_event_id = event.get("id", None) continue diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index 2e6008bc..1f2c552e 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -1,4 +1,5 @@ import collections +from pprint import pformat from ayon_api import slugify_string @@ -29,9 +30,9 @@ def match_shotgrid_hierarchy_in_ayon( """Replicate a Shotgrid project into AYON. This function creates a "deck" which we keep increasing while traversing - the Shotgrid project and finding new childrens, this is more efficient than - creating a dictionary with the whle Shotgrid project structure since we - `popleft` the elements when procesing them. + the Shotgrid project and finding new children, this is more efficient than + creating a dictionary with the while Shotgrid project structure since we + `popleft` the elements when processing them. Args: entity_hub (ayon_api.entity_hub.EntityHub): The AYON EntityHub. @@ -59,6 +60,7 @@ def match_shotgrid_hierarchy_in_ayon( while sg_ay_dicts_deck: (ay_parent_entity, sg_ay_dict) = sg_ay_dicts_deck.popleft() logging.debug(f"Processing {sg_ay_dict} with parent {ay_parent_entity}") + logging.debug(f"Deck size: {len(sg_ay_dicts_deck)}") ay_entity = None sg_entity_sync_status = "Synced" @@ -68,6 +70,7 @@ def match_shotgrid_hierarchy_in_ayon( ay_entity = entity_hub.get_or_query_entity_by_id( ay_id, [sg_ay_dict["type"]]) + logging.debug(f"Found entity {ay_entity} with ID {ay_id}") # If we haven't found the ay_entity by its id, check by its name # to avoid creating duplicates and erroring out if ay_entity is None: @@ -86,7 +89,7 @@ def match_shotgrid_hierarchy_in_ayon( ay_entity = get_asset_category( entity_hub, ay_parent_entity, - sg_ay_dict["name"] + sg_ay_dict ) if not ay_entity: @@ -97,7 +100,7 @@ def match_shotgrid_hierarchy_in_ayon( ) else: logging.debug( - f"Entity {ay_entity.name} <{ay_entity.id}> exists in AYON. " + f"Entity '{ay_entity.name}' <{ay_entity.id}> exists in AYON. " "Making sure the stored ShotGrid Data matches." ) @@ -105,7 +108,8 @@ def match_shotgrid_hierarchy_in_ayon( SHOTGRID_ID_ATTRIB ) - if ay_sg_id_attrib != str(sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]): # noqa + # If the ShotGrid ID in AYON doesn't match the one in ShotGrid + if str(ay_sg_id_attrib) != str(sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]): # noqa logging.error( f"The AYON entity {ay_entity.name} <{ay_entity.id}> has the " # noqa f"ShotgridId {ay_sg_id_attrib}, while the ShotGrid ID " # noqa @@ -118,12 +122,16 @@ def match_shotgrid_hierarchy_in_ayon( ay_entity, sg_ay_dict, custom_attribs_map ) + # skip if no ay_entity is found + # perhaps due Task with project entity as parent + if not ay_entity: + logging.error(f"Entity {sg_ay_dict} not found in AYON.") + continue + # Update SG entity with new created data - sg_ay_dict["data"][CUST_FIELD_CODE_ID] = ay_entity.id + sg_ay_dict["data"][CUST_FIELD_CODE_ID] = entity_id = ay_entity.id sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict - entity_id = sg_ay_dict["name"] - # If the entity is not a "Folder" or "AssetCategory" we update the # entity ID and sync status in Shotgrid and AYON if sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB] not in [ @@ -133,11 +141,13 @@ def match_shotgrid_hierarchy_in_ayon( sg_ay_dict["data"][CUST_FIELD_CODE_ID] != ay_entity.id or sg_ay_dict["data"][CUST_FIELD_CODE_SYNC] != sg_entity_sync_status # noqa ): - logging.debug("Updating AYON entity ID and sync status in SG and AYON") + logging.debug( + "Updating AYON entity ID and sync status in SG and AYON") update_data = { CUST_FIELD_CODE_ID: ay_entity.id, CUST_FIELD_CODE_SYNC: sg_entity_sync_status } + # Update Shotgrid entity with Ayon ID and sync status sg_session.update( sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB], sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB], @@ -146,8 +156,9 @@ def match_shotgrid_hierarchy_in_ayon( ay_entity.data.update( update_data ) + logging.debug(f"Updated entity {ay_entity.name} <{ay_entity.id}> data with '{update_data}'") - entity_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] + entity_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] try: entity_hub.commit_changes() @@ -157,6 +168,7 @@ def match_shotgrid_hierarchy_in_ayon( # If the entity has children, add it to the deck for sg_child in sg_ay_dicts_parents.get(entity_id, []): + logging.debug(f"Adding {sg_child} to the deck.") sg_ay_dicts_deck.append((ay_entity, sg_child)) # Sync project attributes from Shotgrid to AYON @@ -210,6 +222,14 @@ def _create_new_entity(entity_hub, parent_entity, sg_ay_dict): sg_ay_dict (dict): Ayon ShotGrid entity to create. """ if sg_ay_dict["type"].lower() == "task": + # only create if parent_entity type is not project + if parent_entity.entity_type == "project": + logging.warning( + f"Can't create task '{sg_ay_dict['name']}' under project " + "'{parent_entity.name}'. Parent should not be project it self!" + ) + return + ay_entity = entity_hub.add_new_task( sg_ay_dict["task_type"], name=sg_ay_dict["name"], @@ -243,7 +263,6 @@ def _create_new_entity(entity_hub, parent_entity, sg_ay_dict): # `ValueError: Status ip is not available on project.` logging.error(f"Error updating status: {e}") - tags = sg_ay_dict["attribs"].get("tags") if tags: ay_entity.tags = [tag["name"] for tag in tags] diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index 78927b55..d41ec008 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -139,7 +139,7 @@ def create_ay_entity_from_sg_event( ay_parent_entity = get_asset_category( ayon_entity_hub, ayon_entity_hub.project_entity, - sg_ay_dict["data"].get("sg_asset_type").lower(), + sg_ay_dict, ) else: diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 3f1696a0..fa1de209 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -331,7 +331,43 @@ def create_sg_entities_in_ay( return sg_folder_entities, sg_steps -def get_asset_category(entity_hub, parent_entity, asset_category_name): +def create_asset_category(entity_hub, parent_entity, sg_ay_dict): + """Create an "AssetCategory" folder in AYON. + + Args: + entity_hub (ayon_api.EntityHub): The project's entity hub. + parent_entity: Ayon parent entity. + sg_ay_dict (dict): The ShotGrid entity ready for Ayon consumption. + """ + logging.debug( + "It's an AssetCategory, creating it." + ) + asset_category = sg_ay_dict["data"]["sg_asset_type"] + # asset category entity name + cat_ent_name = slugify_string(asset_category).lower() + + asset_category_entity = { + "label": asset_category, + "name": cat_ent_name, + "attribs": { + SHOTGRID_ID_ATTRIB: slugify_string(asset_category).lower(), + SHOTGRID_TYPE_ATTRIB: "AssetCategory", + }, + "parent_id": parent_entity.id, + "data": { + CUST_FIELD_CODE_ID: None, + CUST_FIELD_CODE_SYNC: None, + }, + "folder_type": "AssetCategory", + } + + asset_category_entity = entity_hub.add_new_folder(**asset_category_entity) + + logging.debug(f"Created AssetCategory: {asset_category_entity}") + return asset_category_entity + + +def get_asset_category(entity_hub, parent_entity, sg_ay_dict): """Look for existing "AssetCategory" folders in AYON. Asset categories are not entities per se in ShotGrid, they are @@ -342,7 +378,7 @@ def get_asset_category(entity_hub, parent_entity, asset_category_name): Args: entity_hub (ayon_api.EntityHub): The project's entity hub. parent_entity: Ayon parent entity. - asset_category_name (str): The Asset Category name. + sg_ay_dict (dict): The ShotGrid entity ready for Ayon consumption. """ logging.debug( "It's an AssetCategory, checking if it exists already." @@ -356,6 +392,13 @@ def get_asset_category(entity_hub, parent_entity, asset_category_name): logging.debug(f"Found existing 'AssetCategory'(s)\n{asset_categories}") + # just in case the asset type doesn't exist yet + if not sg_ay_dict["data"].get("sg_asset_type"): + sg_ay_dict["data"]["sg_asset_type"] = sg_ay_dict["name"] + + asset_category_name = slugify_string( + sg_ay_dict["data"]["sg_asset_type"]).lower() + for asset_category in asset_categories: if ( asset_category.name == asset_category_name @@ -365,6 +408,12 @@ def get_asset_category(entity_hub, parent_entity, asset_category_name): return asset_category logging.debug(f"Unable to find AssetCategory. {asset_category_name}") + + try: + return create_asset_category(entity_hub, parent_entity, sg_ay_dict) + except Exception as e: + logging.error(f"Unable to create AssetCategory. {e}") + return None @@ -542,6 +591,7 @@ def get_sg_entities( ): parent_id = sg_entity[parent_field]["id"] elif entity_name == "Asset" and sg_entity["sg_asset_type"]: + # TODO: Add support for AssetCategory and Asset # Asset Categories (sg_asset_type) are not entities # (or at least aren't queryable) in ShotGrid # thus here we create common folders. @@ -567,8 +617,8 @@ def get_sg_entities( if not sg_ay_dicts.get(cat_ent_name): sg_ay_dicts[cat_ent_name] = asset_category_entity - sg_ay_dicts_parents[ - sg_project["id"]].append(asset_category_entity) + sg_ay_dicts_parents[sg_project["id"]].append( + asset_category_entity) parent_id = cat_ent_name @@ -577,6 +627,10 @@ def get_sg_entities( project_code_field, custom_attribs_map, ) + logging.debug(f"ShotGrid entity {sg_entity} as Ayon dict: {sg_ay_dict}") + logging.debug(f"Parent ID: {parent_id}") + logging.debug("_" * 80) + sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict sg_ay_dicts_parents[parent_id].append(sg_ay_dict) @@ -998,6 +1052,6 @@ def update_ay_entity_custom_attributes( ay_entity.status = attrib_value except ValueError as e: # `ValueError: Status ip is not available on project.` - logging.error(f"Error updating status: {e}") + logging.warning(f"Error updating status: {e}") else: ay_entity.attribs.set(ay_attrib, attrib_value) From 4d260dbb7015a86dc539e783406fd7b55a1e83d3 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 2 May 2024 16:43:19 +0200 Subject: [PATCH 06/22] Refactor commit_changes handling in match_shotgrid_hierarchy_in_ayon Improve error handling for entity creation and commit_changes. --- .../match_shotgrid_hierarchy_in_ayon.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index 1f2c552e..6cc50e7a 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -160,17 +160,17 @@ def match_shotgrid_hierarchy_in_ayon( entity_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] - try: - entity_hub.commit_changes() - except Exception as e: - logging.error(f"Unable to create entity {sg_ay_dict} in AYON!") - log_traceback(e) - # If the entity has children, add it to the deck for sg_child in sg_ay_dicts_parents.get(entity_id, []): logging.debug(f"Adding {sg_child} to the deck.") sg_ay_dicts_deck.append((ay_entity, sg_child)) + try: + entity_hub.commit_changes() + except Exception as e: + logging.error(f"Unable to create entity {sg_ay_dict} in AYON!") + log_traceback(e) + # Sync project attributes from Shotgrid to AYON entity_hub.project_entity.attribs.set( SHOTGRID_ID_ATTRIB, From 1651b662cdf2bbf99dad733b409eedaceed6012d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 2 May 2024 17:09:17 +0200 Subject: [PATCH 07/22] warning is not generating events --- .../ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index 6cc50e7a..cb5e468c 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -261,7 +261,7 @@ def _create_new_entity(entity_hub, parent_entity, sg_ay_dict): ay_entity.status = status except ValueError as e: # `ValueError: Status ip is not available on project.` - logging.error(f"Error updating status: {e}") + logging.warning(f"Error updating status: {e}") tags = sg_ay_dict["attribs"].get("tags") if tags: From d032c83fb5574342fa5a461ce28ddb1510c89c92 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 2 May 2024 17:10:03 +0200 Subject: [PATCH 08/22] ayon python api version increase --- service_tools/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service_tools/requirements.txt b/service_tools/requirements.txt index c5c3b560..d1ab25d6 100644 --- a/service_tools/requirements.txt +++ b/service_tools/requirements.txt @@ -1,6 +1,6 @@ annotated-types==0.6.0 appdirs==1.4.4 -ayon-python-api==1.0.4 +ayon-python-api>=1.0.4 certifi==2024.2.2 charset-normalizer==3.3.2 colorama==0.4.6 From ebd8b25847a3862db5c7f102bc2f718cb0609bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Thu, 2 May 2024 17:12:03 +0200 Subject: [PATCH 09/22] Update services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index d41ec008..0bb9596f 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -264,9 +264,9 @@ def update_ayon_entity_from_sg_event( custom_attribs_map ) except Exception as e: - logging.error(f"Ayon Entity could not be created: {e}") + logging.error(f"AYON Entity could not be created: {e}") logging.warning( - "Skipping update of Ayon Entity. ShotGrid ID missing " + "Skipping update of AYON Entity. ShotGrid ID missing " "and entity could not be created." ) return From bcf7ef559839e35e5e803966c098a3c3c6b4ce10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Thu, 2 May 2024 17:12:14 +0200 Subject: [PATCH 10/22] Update services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index 0bb9596f..f17667c8 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -252,7 +252,7 @@ def update_ayon_entity_from_sg_event( # if the entity does not have an Ayon ID, try to create it logging.warning("ShotGrid Missing Ayon ID.") - logging.debug(f"Creating Ayon Entity: {sg_ay_dict}") + logging.debug(f"Creating AYON Entity: {sg_ay_dict}") try: create_ay_entity_from_sg_event( sg_event, From 6f208d7b88565a37f6c10345993f4661ad03aef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Thu, 2 May 2024 17:12:23 +0200 Subject: [PATCH 11/22] Update services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index f17667c8..6050fabe 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -249,8 +249,8 @@ def update_ayon_entity_from_sg_event( ) if not sg_ay_dict["data"].get(CUST_FIELD_CODE_ID): - # if the entity does not have an Ayon ID, try to create it - logging.warning("ShotGrid Missing Ayon ID.") + # if the entity does not have an AYON id, try to create it + logging.warning("ShotGrid Missing AYON id.") logging.debug(f"Creating AYON Entity: {sg_ay_dict}") try: From 0cd159e6c3bc594ed727e66cd2f5cbb339c80659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Thu, 2 May 2024 17:12:38 +0200 Subject: [PATCH 12/22] Update services/shotgrid_common/utils.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- services/shotgrid_common/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index fa1de209..4dd450ba 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -627,9 +627,10 @@ def get_sg_entities( project_code_field, custom_attribs_map, ) - logging.debug(f"ShotGrid entity {sg_entity} as Ayon dict: {sg_ay_dict}") - logging.debug(f"Parent ID: {parent_id}") - logging.debug("_" * 80) + logging.debug( + f"ShotGrid entity {sg_entity} as AYON dict: {sg_ay_dict}" + f" Parent ID: {parent_id}" + ) sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict sg_ay_dicts_parents[parent_id].append(sg_ay_dict) From 5c72f96a24d414a4ed57aef695375d19d4fe2ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Thu, 2 May 2024 17:13:03 +0200 Subject: [PATCH 13/22] Update services/shotgrid_common/utils.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- services/shotgrid_common/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 4dd450ba..4defb92d 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -336,7 +336,7 @@ def create_asset_category(entity_hub, parent_entity, sg_ay_dict): Args: entity_hub (ayon_api.EntityHub): The project's entity hub. - parent_entity: Ayon parent entity. + parent_entity: AYON parent entity. sg_ay_dict (dict): The ShotGrid entity ready for Ayon consumption. """ logging.debug( From 4884df374a1bd23776f5c78814d7561b87d9c1bc Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 2 May 2024 17:17:02 +0200 Subject: [PATCH 14/22] Update Ayon entity creation and update process - Added a check to create Ayon entity if missing ID - Improved logging messages for clarity --- .../ayon_shotgrid_hub/update_from_shotgrid.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index d41ec008..8ecd6ef8 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -248,8 +248,9 @@ def update_ayon_entity_from_sg_event( custom_attribs_map=custom_attribs_map ) + # if the entity does not have an Ayon ID, try to create it + # and no need to update if not sg_ay_dict["data"].get(CUST_FIELD_CODE_ID): - # if the entity does not have an Ayon ID, try to create it logging.warning("ShotGrid Missing Ayon ID.") logging.debug(f"Creating Ayon Entity: {sg_ay_dict}") @@ -291,7 +292,7 @@ def update_ayon_entity_from_sg_event( logging.error("Mismatching ShotGrid IDs, aborting...") raise ValueError("Mismatching ShotGrid IDs, aborting...") - logging.debug("Updating Ayon entity with '%s'" % sg_ay_dict) + logging.debug(f"Updating Ayon entity with '{sg_ay_dict}'") ay_entity.name = sg_ay_dict["name"] ay_entity.label = sg_ay_dict["label"] From 37e4272969d64b7ecd304de0623646aaf0a424b4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 3 May 2024 11:48:08 +0200 Subject: [PATCH 15/22] removed unused variable --- .../ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index cb5e468c..0986d0a7 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -129,7 +129,7 @@ def match_shotgrid_hierarchy_in_ayon( continue # Update SG entity with new created data - sg_ay_dict["data"][CUST_FIELD_CODE_ID] = entity_id = ay_entity.id + sg_ay_dict["data"][CUST_FIELD_CODE_ID] = ay_entity.id sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict # If the entity is not a "Folder" or "AssetCategory" we update the From 2ebc3973bbf467e2d0e72d9b1f8ce0adeede295a Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 3 May 2024 11:49:13 +0200 Subject: [PATCH 16/22] removed unnecessary condition --- services/shotgrid_common/utils.py | 107 +++++++++++++++--------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 4defb92d..4e4a7aac 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -580,60 +580,59 @@ def get_sg_entities( filters=[["project", "is", sg_project]], fields=query_fields, ) - if sg_entities: - for sg_entity in sg_entities: - parent_id = sg_project["id"] - - if ( - parent_field != "project" - and sg_entity[parent_field] - and entity_name != "Asset" - ): - parent_id = sg_entity[parent_field]["id"] - elif entity_name == "Asset" and sg_entity["sg_asset_type"]: - # TODO: Add support for AssetCategory and Asset - # Asset Categories (sg_asset_type) are not entities - # (or at least aren't queryable) in ShotGrid - # thus here we create common folders. - asset_category = sg_entity["sg_asset_type"] - # asset category entity name - cat_ent_name = slugify_string(asset_category).lower() - - asset_category_entity = { - "label": asset_category, - "name": cat_ent_name, - "attribs": { - SHOTGRID_ID_ATTRIB: slugify_string( - asset_category).lower(), - SHOTGRID_TYPE_ATTRIB: "AssetCategory", - }, - "data": { - CUST_FIELD_CODE_ID: None, - CUST_FIELD_CODE_SYNC: None, - }, - "type": "folder", - "folder_type": "AssetCategory", - } - - if not sg_ay_dicts.get(cat_ent_name): - sg_ay_dicts[cat_ent_name] = asset_category_entity - sg_ay_dicts_parents[sg_project["id"]].append( - asset_category_entity) - - parent_id = cat_ent_name - - sg_ay_dict = _sg_to_ay_dict( - sg_entity, - project_code_field, - custom_attribs_map, - ) - logging.debug( - f"ShotGrid entity {sg_entity} as AYON dict: {sg_ay_dict}" - f" Parent ID: {parent_id}" - ) - - sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict - sg_ay_dicts_parents[parent_id].append(sg_ay_dict) + for sg_entity in sg_entities: + parent_id = sg_project["id"] + + if ( + parent_field != "project" + and sg_entity[parent_field] + and entity_name != "Asset" + ): + parent_id = sg_entity[parent_field]["id"] + + elif entity_name == "Asset" and sg_entity["sg_asset_type"]: + # Asset Categories (sg_asset_type) are not entities + # (or at least aren't queryable) in ShotGrid + # thus here we create common folders. + asset_category = sg_entity["sg_asset_type"] + # asset category entity name + cat_ent_name = slugify_string(asset_category).lower() + + asset_category_entity = { + "label": asset_category, + "name": cat_ent_name, + "attribs": { + SHOTGRID_ID_ATTRIB: slugify_string( + asset_category).lower(), + SHOTGRID_TYPE_ATTRIB: "AssetCategory", + }, + "data": { + CUST_FIELD_CODE_ID: None, + CUST_FIELD_CODE_SYNC: None, + }, + "type": "folder", + "folder_type": "AssetCategory", + } + + if not sg_ay_dicts.get(cat_ent_name): + sg_ay_dicts[cat_ent_name] = asset_category_entity + sg_ay_dicts_parents[sg_project["id"]].append( + asset_category_entity) + + parent_id = cat_ent_name + + sg_ay_dict = _sg_to_ay_dict( + sg_entity, + project_code_field, + custom_attribs_map, + ) + logging.debug( + f"ShotGrid entity {sg_entity} as AYON dict: {sg_ay_dict}" + f" Parent ID: {parent_id}" + ) + + sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict + sg_ay_dicts_parents[parent_id].append(sg_ay_dict) return sg_ay_dicts, sg_ay_dicts_parents From ed21f1fd7617d8daebc292f37a2371bc0a5c947e Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 3 May 2024 11:49:28 +0200 Subject: [PATCH 17/22] move indentation --- .../match_shotgrid_hierarchy_in_ayon.py | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index 0986d0a7..8693f1c3 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -1,5 +1,4 @@ import collections -from pprint import pformat from ayon_api import slugify_string @@ -134,29 +133,29 @@ def match_shotgrid_hierarchy_in_ayon( # If the entity is not a "Folder" or "AssetCategory" we update the # entity ID and sync status in Shotgrid and AYON - if sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB] not in [ - "Folder", "AssetCategory" - ]: - if ( + if ( + sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB] not in [ + "Folder", "AssetCategory" + ] + and ( sg_ay_dict["data"][CUST_FIELD_CODE_ID] != ay_entity.id or sg_ay_dict["data"][CUST_FIELD_CODE_SYNC] != sg_entity_sync_status # noqa - ): - logging.debug( - "Updating AYON entity ID and sync status in SG and AYON") - update_data = { - CUST_FIELD_CODE_ID: ay_entity.id, - CUST_FIELD_CODE_SYNC: sg_entity_sync_status - } - # Update Shotgrid entity with Ayon ID and sync status - sg_session.update( - sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB], - sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB], - update_data - ) - ay_entity.data.update( - update_data - ) - logging.debug(f"Updated entity {ay_entity.name} <{ay_entity.id}> data with '{update_data}'") + ) + ): + logging.debug( + "Updating AYON entity ID and sync status in SG and AYON") + update_data = { + CUST_FIELD_CODE_ID: ay_entity.id, + CUST_FIELD_CODE_SYNC: sg_entity_sync_status + } + # Update Shotgrid entity with Ayon ID and sync status + sg_session.update( + sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB], + sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB], + update_data + ) + ay_entity.data.update(update_data) + logging.debug(f"Updated entity {ay_entity.name} <{ay_entity.id}> data with '{update_data}'") entity_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] From 7bcfe0cece159e42f7ec63f30ac56176ccbcc8da Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 3 May 2024 11:56:31 +0200 Subject: [PATCH 18/22] Refactor entity retrieval to prevent duplicates Adjust how entities are fetched to avoid duplicate entries. Introduce a dictionary structure for storing entities and iterate through its values instead of directly processing the list returned by the API call. --- services/shotgrid_common/utils.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 4e4a7aac..8290d50b 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -575,12 +575,17 @@ def get_sg_entities( if entity_name in entities_to_ignore: continue - sg_entities = sg_session.find( - entity_name, - filters=[["project", "is", sg_project]], - fields=query_fields, - ) - for sg_entity in sg_entities: + # Potential fix when shotgrid api returns the same entity more than + # once, we store the entities in a dictionary to avoid duplicates + sg_entities = { + entity["id"]: entity + for entity in sg_session.find( + entity_name, + filters=[["project", "is", sg_project]], + fields=query_fields, + ) + } + for sg_entity in sg_entities.values(): parent_id = sg_project["id"] if ( From 281e531d3748da2491fc1a66fc27fa3a2caf89cc Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 3 May 2024 14:16:52 +0200 Subject: [PATCH 19/22] Remove debug logging statements and update entity creation and processing logic in Shotgrid-related services. Improve error handling and sync status updates. --- services/leecher/leecher/listener.py | 10 -- services/processor/processor/processor.py | 6 +- .../match_ayon_hierarchy_in_shotgrid.py | 10 +- .../match_shotgrid_hierarchy_in_ayon.py | 73 +++++++------- .../ayon_shotgrid_hub/update_from_ayon.py | 11 --- .../ayon_shotgrid_hub/update_from_shotgrid.py | 13 --- services/shotgrid_common/utils.py | 97 ++++++------------- .../transmitter/transmitter/transmitter.py | 6 -- 8 files changed, 76 insertions(+), 150 deletions(-) diff --git a/services/leecher/leecher/listener.py b/services/leecher/leecher/listener.py index 2391ba5e..57778f9b 100644 --- a/services/leecher/leecher/listener.py +++ b/services/leecher/leecher/listener.py @@ -38,8 +38,6 @@ def __init__(self, func: Union[Callable, None] = None): else: self.func = func - logging.debug(f"Callback method is {self.func}.") - try: ayon_api.init_service() self.settings = ayon_api.get_service_addon_settings() @@ -173,8 +171,6 @@ def _get_last_event_processed(self, sg_filters): ) last_event_id = last_event["id"] - logging.debug(f"Last non-processed SG Event is {last_event}") - return last_event_id def start_listening(self): @@ -223,12 +219,6 @@ def start_listening(self): event["event_type"].endswith("_Change") and event["attribute_name"].replace("sg_", "") not in list(self.custom_attribs_map.values()) ): - logging.debug( - f"Skipping event for attribute change " - f"'{event['attribute_name'].replace('sg_', '')}', " - "as we can't handle it." - ) - logging.debug(f"Event: {event}") last_event_id = event.get("id", None) continue diff --git a/services/processor/processor/processor.py b/services/processor/processor/processor.py index 7ed3e166..c51d061d 100644 --- a/services/processor/processor/processor.py +++ b/services/processor/processor/processor.py @@ -97,7 +97,7 @@ def __init__(self): if not self.handlers_map: logging.error("No handlers found for the processor, aborting.") else: - logging.debug(f"Found these handlers: {self.handlers_map}") + pass def _get_handlers(self): """ Import the handlers found in the `handlers` directory. @@ -145,10 +145,6 @@ def start_processing(self): will trigger the `handlers/project_sync.py` since that one has the attribute REGISTER_EVENT_TYPE = ["create-project"] """ - logging.debug( - "Querying for `shotgrid.event` events " - f"every {self.sg_polling_frequency} seconds..." - ) while True: try: event = ayon_api.enroll_event_job( diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_ayon_hierarchy_in_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/match_ayon_hierarchy_in_shotgrid.py index c7ac02e8..9ba5d512 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_ayon_hierarchy_in_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_ayon_hierarchy_in_shotgrid.py @@ -66,7 +66,6 @@ def match_ayon_hierarchy_in_shotgrid( while sg_ay_dicts_deck: (sg_ay_parent_entity, ay_entity) = sg_ay_dicts_deck.popleft() - logging.debug(f"Processing {ay_entity})") sg_ay_dict = None @@ -85,7 +84,8 @@ def match_ayon_hierarchy_in_shotgrid( if sg_entity_id in sg_ay_dicts: sg_ay_dict = sg_ay_dicts[sg_entity_id] - logging.info(f"Entity already exists in Shotgrid {sg_ay_dict}") + logging.info( + f"Entity already exists in Shotgrid {sg_ay_dict['name']}") if sg_ay_dict["data"][CUST_FIELD_CODE_ID] != ay_entity.id: logging.error( @@ -148,7 +148,8 @@ def match_ayon_hierarchy_in_shotgrid( SHOTGRID_TYPE_ATTRIB, sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB] ) - entity_hub.commit_changes() + + entity_hub.commit_changes() if sg_ay_dict is None: # Shotgrid doesn't have the concept of "Folders" @@ -268,9 +269,6 @@ def _create_new_entity( log_traceback(e) raise e - logging.debug(f"Created new entity: {sg_entity}") - logging.debug(f"Parent is: {sg_parent_entity}") - sg_ay_dict = get_sg_entity_as_ay_dict( sg_session, sg_entity["type"], diff --git a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py index 8693f1c3..037fc294 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/match_shotgrid_hierarchy_in_ayon.py @@ -51,15 +51,34 @@ def match_shotgrid_hierarchy_in_ayon( sg_ay_dicts_deck = collections.deque() # Append the project's direct children. - for sg_ay_dict_child in sg_ay_dicts_parents[sg_project["id"]]: - sg_ay_dicts_deck.append((entity_hub.project_entity, sg_ay_dict_child)) + for sg_ay_dict_child_id in sg_ay_dicts_parents[sg_project["id"]]: + sg_ay_dicts_deck.append( + (entity_hub.project_entity, sg_ay_dict_child_id) + ) sg_project_sync_status = "Synced" + processed_ids = set() while sg_ay_dicts_deck: - (ay_parent_entity, sg_ay_dict) = sg_ay_dicts_deck.popleft() - logging.debug(f"Processing {sg_ay_dict} with parent {ay_parent_entity}") - logging.debug(f"Deck size: {len(sg_ay_dicts_deck)}") + (ay_parent_entity, sg_ay_dict_child_id) = sg_ay_dicts_deck.popleft() + sg_ay_dict = sg_ay_dicts[sg_ay_dict_child_id] + sg_entity_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] + if sg_entity_id in processed_ids: + msg = ( + f"Entity {sg_entity_id} already processed, skipping..." + f"Sg Ay Dict: {sg_ay_dict} - " + f"Ay Parent Entity: {ay_parent_entity}" + ) + logging.warning(msg) + + # append msg to temp file for debugging + with open("/service/processed_ids.txt", "a") as f: + f.write(f"{msg}\n") + continue + + processed_ids.add(sg_entity_id) + + logging.info(f"Deck size: {len(sg_ay_dicts_deck)}") ay_entity = None sg_entity_sync_status = "Synced" @@ -69,7 +88,6 @@ def match_shotgrid_hierarchy_in_ayon( ay_entity = entity_hub.get_or_query_entity_by_id( ay_id, [sg_ay_dict["type"]]) - logging.debug(f"Found entity {ay_entity} with ID {ay_id}") # If we haven't found the ay_entity by its id, check by its name # to avoid creating duplicates and erroring out if ay_entity is None: @@ -77,9 +95,6 @@ def match_shotgrid_hierarchy_in_ayon( for child in ay_parent_entity.children: if child.name.lower() == name.lower(): ay_entity = child - logging.debug( - f"Found another entity with the same name: {ay_entity.name} <{ay_entity.id}>." - ) break # If we couldn't find it we create it. @@ -98,21 +113,16 @@ def match_shotgrid_hierarchy_in_ayon( sg_ay_dict ) else: - logging.debug( - f"Entity '{ay_entity.name}' <{ay_entity.id}> exists in AYON. " - "Making sure the stored ShotGrid Data matches." - ) - ay_sg_id_attrib = ay_entity.attribs.get( SHOTGRID_ID_ATTRIB ) # If the ShotGrid ID in AYON doesn't match the one in ShotGrid - if str(ay_sg_id_attrib) != str(sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]): # noqa + if str(ay_sg_id_attrib) != str(sg_entity_id): # noqa logging.error( f"The AYON entity {ay_entity.name} <{ay_entity.id}> has the " # noqa f"ShotgridId {ay_sg_id_attrib}, while the ShotGrid ID " # noqa - f"should be {sg_ay_dict['attribs'][SHOTGRID_ID_ATTRIB]}" + f"should be {sg_entity_id}" ) sg_entity_sync_status = "Failed" sg_project_sync_status = "Failed" @@ -129,7 +139,7 @@ def match_shotgrid_hierarchy_in_ayon( # Update SG entity with new created data sg_ay_dict["data"][CUST_FIELD_CODE_ID] = ay_entity.id - sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict + sg_ay_dicts[sg_entity_id] = sg_ay_dict # If the entity is not a "Folder" or "AssetCategory" we update the # entity ID and sync status in Shotgrid and AYON @@ -142,8 +152,8 @@ def match_shotgrid_hierarchy_in_ayon( or sg_ay_dict["data"][CUST_FIELD_CODE_SYNC] != sg_entity_sync_status # noqa ) ): - logging.debug( - "Updating AYON entity ID and sync status in SG and AYON") + # logging.debug( + # "Updating AYON entity ID and sync status in SG and AYON") update_data = { CUST_FIELD_CODE_ID: ay_entity.id, CUST_FIELD_CODE_SYNC: sg_entity_sync_status @@ -151,25 +161,25 @@ def match_shotgrid_hierarchy_in_ayon( # Update Shotgrid entity with Ayon ID and sync status sg_session.update( sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB], - sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB], + sg_entity_id, update_data ) ay_entity.data.update(update_data) - logging.debug(f"Updated entity {ay_entity.name} <{ay_entity.id}> data with '{update_data}'") - - entity_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] # If the entity has children, add it to the deck - for sg_child in sg_ay_dicts_parents.get(entity_id, []): - logging.debug(f"Adding {sg_child} to the deck.") - sg_ay_dicts_deck.append((ay_entity, sg_child)) + for sg_child_id in sg_ay_dicts_parents.get(sg_entity_id, []): + sg_ay_dicts_deck.append((ay_entity, sg_child_id)) try: entity_hub.commit_changes() except Exception as e: - logging.error(f"Unable to create entity {sg_ay_dict} in AYON!") + logging.error("Unable to commit all entities to AYON!") log_traceback(e) + logging.info( + "Processed entities successfully!. " + f"Amount of entities: {len(processed_ids)}" + ) # Sync project attributes from Shotgrid to AYON entity_hub.project_entity.attribs.set( SHOTGRID_ID_ATTRIB, @@ -183,7 +193,6 @@ def match_shotgrid_hierarchy_in_ayon( attrib_value = sg_project.get(sg_attrib) \ or sg_project.get(f"sg_{sg_attrib}") - logging.debug(f"Checking {sg_attrib} -> {attrib_value}") if attrib_value is None: continue @@ -252,20 +261,18 @@ def _create_new_entity(entity_hub, parent_entity, sg_ay_dict): # TODO: this doesn't work yet status = sg_ay_dict["attribs"].get("status") if status: - logging.debug(f"Entity '{sg_ay_dict['name']}' status sync: '{status}'") # TODO: Implement status update try: # INFO: it was causing error so trying to set status directly - logging.warning("Status update is not supported yet.") ay_entity.status = status except ValueError as e: # `ValueError: Status ip is not available on project.` - logging.warning(f"Error updating status: {e}") + # logging.warning(f"Status sync not implemented: {e}") + pass tags = sg_ay_dict["attribs"].get("tags") if tags: ay_entity.tags = [tag["name"] for tag in tags] - logging.debug(f"Created new entity: {ay_entity.name} ({ay_entity.id})") - logging.debug(f"Parent is: {parent_entity.name} ({parent_entity.id})") + logging.info(f"Created new entity: {ay_entity.name} ({ay_entity.id})") return ay_entity diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_ayon.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_ayon.py index be228185..d32a6964 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_ayon.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_ayon.py @@ -39,8 +39,6 @@ def create_sg_entity_from_ayon_event( ay_entity (ayon_api.entity_hub.EntityHub.Entity): The newly created entity. """ - logging.debug(f"Processing event {ayon_event}") - ay_id = ayon_event["summary"]["entityId"] ay_entity = ayon_entity_hub.get_or_query_entity_by_id( ay_id, ["folder", "task"]) @@ -62,10 +60,7 @@ def create_sg_entity_from_ayon_event( sg_entity = None - logging.debug(f"Creating {ay_entity} ({sg_type} <{ay_id}>) in Shotgrid.") - if sg_id and sg_type: - logging.debug(f"Querying Shotgrid for {sg_type} <{sg_id}>") sg_entity = sg_session.find_one(sg_type, [["id", "is", int(sg_id)]]) if sg_entity: @@ -115,7 +110,6 @@ def update_sg_entity_from_ayon_event( sg_entity (dict): The modified Shotgrid entity. """ - logging.debug(f"Processing event {ayon_event}") ay_id = ayon_event["summary"]["entityId"] ay_entity = ayon_entity_hub.get_or_query_entity_by_id( ay_id, ["folder", "task"]) @@ -126,8 +120,6 @@ def update_sg_entity_from_ayon_event( f"{ayon_event['summary']['entityId']}" ) - logging.debug(f"Processing entity {ay_entity}") - sg_id = ay_entity.attribs.get("shotgridId") sg_entity_type = ay_entity.attribs.get("shotgridType") @@ -218,7 +210,6 @@ def remove_sg_entity_from_ayon_event(ayon_event, sg_session, ayon_entity_hub): sg_session (shotgun_api3.Shotgun): The Shotgrid API session. ayon_entity_hub (ayon_api.entity_hub.EntityHub): The AYON EntityHub. """ - logging.debug(f"Processing event {ayon_event}") ay_id = ayon_event["payload"]["entityData"]["id"] ay_entity_path = ayon_event["payload"]["entityData"]["path"] sg_id = ayon_event["payload"]["entityData"]["attrib"].get("shotgridId") @@ -354,8 +345,6 @@ def _create_sg_entity( custom_attribs_map )) - logging.debug(f"Creating Shotgrid entity {sg_type} with data: {data}") - try: sg_entity = sg_session.create(sg_type, data) return sg_entity diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index 7e2b1883..f2fc3840 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -85,7 +85,6 @@ def create_ay_entity_from_sg_event( custom_attribs_map=custom_attribs_map, extra_fields=extra_fields, ) - logging.debug(f"ShotGrid Entity as AYON dict: {sg_ay_dict}") if not sg_ay_dict: logging.warning( "Entity {sg_event['entity_type']} <{sg_event['entity_id']}> " @@ -101,7 +100,6 @@ def create_ay_entity_from_sg_event( ) if ay_entity: - logging.debug(f"ShotGrid Entity exists in AYON.") # Ensure Ayon Entity has the correct ShotGrid ID ayon_entity_sg_id = str( ay_entity.attribs.get_attribute(SHOTGRID_ID_ATTRIB).value) @@ -128,14 +126,11 @@ def create_ay_entity_from_sg_event( # with optional way. if sg_ay_dict["data"].get(sg_parent_field) is None: # Parent is the project - logging.debug(f"ShotGrid Parent is the Project: {sg_project}") ay_parent_entity = ayon_entity_hub.project_entity elif ( sg_ay_dict["attribs"][SHOTGRID_TYPE_ATTRIB] == "Asset" and sg_ay_dict["data"].get("sg_asset_type") ): - logging.debug("ShotGrid Parent is an Asset category.") - ay_parent_entity = get_asset_category( ayon_entity_hub, ayon_entity_hub.project_entity, @@ -151,7 +146,6 @@ def create_ay_entity_from_sg_event( project_code_field, ) - logging.debug(f"ShotGrid Parent entity: {sg_parent_entity_dict}") ay_parent_entity = ayon_entity_hub.get_or_query_entity_by_id( sg_parent_entity_dict["data"].get(CUST_FIELD_CODE_ID), [ @@ -188,7 +182,6 @@ def create_ay_entity_from_sg_event( attribs=sg_ay_dict["attribs"] ) - logging.debug(f"Created new AYON entity: {ay_entity}") ay_entity.attribs.set( SHOTGRID_ID_ATTRIB, sg_ay_dict["attribs"].get(SHOTGRID_ID_ATTRIB, "") @@ -251,9 +244,6 @@ def update_ayon_entity_from_sg_event( # if the entity does not have an Ayon ID, try to create it # and no need to update if not sg_ay_dict["data"].get(CUST_FIELD_CODE_ID): - logging.warning("ShotGrid Missing AYON id.") - - logging.debug(f"Creating AYON Entity: {sg_ay_dict}") try: create_ay_entity_from_sg_event( sg_event, @@ -281,7 +271,6 @@ def update_ayon_entity_from_sg_event( logging.error("Unable to update a non existing entity.") raise ValueError("Unable to update a non existing entity.") - logging.debug(f"Updating Ayon Entity: {ay_entity.name}") # Ensure Ayon Entity has the correct ShotGrid ID ayon_entity_sg_id = str( ay_entity.attribs.get_attribute(SHOTGRID_ID_ATTRIB).value) @@ -292,7 +281,6 @@ def update_ayon_entity_from_sg_event( logging.error("Mismatching ShotGrid IDs, aborting...") raise ValueError("Mismatching ShotGrid IDs, aborting...") - logging.debug(f"Updating Ayon entity with '{sg_ay_dict}'") ay_entity.name = sg_ay_dict["name"] ay_entity.label = sg_ay_dict["label"] @@ -337,7 +325,6 @@ def remove_ayon_entity_from_sg_event( retired_only=True ) - logging.debug(f"ShotGrid Entity as Ay dict: {sg_ay_dict}") if not sg_ay_dict: logging.warning( f"Entity {sg_event['entity_type']} <{sg_event['entity_id']}> " diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 8290d50b..9f37ff77 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -38,8 +38,6 @@ def _sg_to_ay_dict( custom_attribs_map (dict): Dictionary that maps names of attributes in AYON to ShotGrid equivalents. """ - logging.debug(f"Transforming sg_entity '{sg_entity}' to ayon dict.") - ay_entity_type = "folder" task_type = None folder_type = None @@ -105,8 +103,6 @@ def _sg_to_ay_dict( elif folder_type: sg_ay_dict["folder_type"] = folder_type - logging.debug(f"Transformed sg_entity as ayon dict: {sg_ay_dict}") - return sg_ay_dict @@ -232,7 +228,6 @@ def create_ay_fields_in_sg_project( for attr_name, attr_dict in get_attributes_for_type("folder").items() } for attribute, attribute_values in SG_PROJECT_ATTRS.items(): - logging.debug(f"Creating ShotGrid field for {attribute}") sg_field_name = attribute_values["name"] sg_field_code = attribute_values["sg_field"] sg_field_type = attribute_values.get("type") @@ -339,9 +334,6 @@ def create_asset_category(entity_hub, parent_entity, sg_ay_dict): parent_entity: AYON parent entity. sg_ay_dict (dict): The ShotGrid entity ready for Ayon consumption. """ - logging.debug( - "It's an AssetCategory, creating it." - ) asset_category = sg_ay_dict["data"]["sg_asset_type"] # asset category entity name cat_ent_name = slugify_string(asset_category).lower() @@ -363,7 +355,7 @@ def create_asset_category(entity_hub, parent_entity, sg_ay_dict): asset_category_entity = entity_hub.add_new_folder(**asset_category_entity) - logging.debug(f"Created AssetCategory: {asset_category_entity}") + logging.info(f"Created AssetCategory: {asset_category_entity}") return asset_category_entity @@ -380,9 +372,6 @@ def get_asset_category(entity_hub, parent_entity, sg_ay_dict): parent_entity: Ayon parent entity. sg_ay_dict (dict): The ShotGrid entity ready for Ayon consumption. """ - logging.debug( - "It's an AssetCategory, checking if it exists already." - ) entity_hub.query_entities_from_server() asset_categories = [ entity @@ -390,8 +379,6 @@ def get_asset_category(entity_hub, parent_entity, sg_ay_dict): if entity.entity_type.lower() == "folder" and entity.folder_type == "AssetCategory" # noqa ] - logging.debug(f"Found existing 'AssetCategory'(s)\n{asset_categories}") - # just in case the asset type doesn't exist yet if not sg_ay_dict["data"].get("sg_asset_type"): sg_ay_dict["data"]["sg_asset_type"] = sg_ay_dict["name"] @@ -404,11 +391,8 @@ def get_asset_category(entity_hub, parent_entity, sg_ay_dict): asset_category.name == asset_category_name and asset_category.parent.id == parent_entity.id ): - logging.debug(f"AssetCategory already exists: {asset_category}") return asset_category - logging.debug(f"Unable to find AssetCategory. {asset_category_name}") - try: return create_asset_category(entity_hub, parent_entity, sg_ay_dict) except Exception as e: @@ -447,9 +431,6 @@ def get_or_create_sg_field( sg_session, sg_entity_type, field_code) if not attribute_exists: - logging.debug( - f"ShotGrid field {sg_entity_type} > {field_code} does not exist." - ) try: attribute_exists = sg_session.schema_field_create( @@ -458,9 +439,6 @@ def get_or_create_sg_field( field_name, properties=field_properties, ) - logging.debug( - f"Created ShotGrid field {sg_entity_type} > {field_code}" - ) return attribute_exists except Exception as e: logging.error( @@ -565,8 +543,8 @@ def get_sg_entities( ), } - sg_ay_dicts_parents: Dict[str, list] = ( - collections.defaultdict(list) + sg_ay_dicts_parents: Dict[str, set] = ( + collections.defaultdict(set) ) for enabled_entity in project_enabled_entities: @@ -577,15 +555,13 @@ def get_sg_entities( # Potential fix when shotgrid api returns the same entity more than # once, we store the entities in a dictionary to avoid duplicates - sg_entities = { - entity["id"]: entity - for entity in sg_session.find( - entity_name, - filters=[["project", "is", sg_project]], - fields=query_fields, - ) - } - for sg_entity in sg_entities.values(): + sg_entities = sg_session.find( + entity_name, + filters=[["project", "is", sg_project]], + fields=query_fields, + ) + + for sg_entity in sg_entities: parent_id = sg_project["id"] if ( @@ -603,26 +579,24 @@ def get_sg_entities( # asset category entity name cat_ent_name = slugify_string(asset_category).lower() - asset_category_entity = { - "label": asset_category, - "name": cat_ent_name, - "attribs": { - SHOTGRID_ID_ATTRIB: slugify_string( - asset_category).lower(), - SHOTGRID_TYPE_ATTRIB: "AssetCategory", - }, - "data": { - CUST_FIELD_CODE_ID: None, - CUST_FIELD_CODE_SYNC: None, - }, - "type": "folder", - "folder_type": "AssetCategory", - } - - if not sg_ay_dicts.get(cat_ent_name): + if cat_ent_name not in sg_ay_dicts: + asset_category_entity = { + "label": asset_category, + "name": cat_ent_name, + "attribs": { + SHOTGRID_ID_ATTRIB: slugify_string( + asset_category).lower(), + SHOTGRID_TYPE_ATTRIB: "AssetCategory", + }, + "data": { + CUST_FIELD_CODE_ID: None, + CUST_FIELD_CODE_SYNC: None, + }, + "type": "folder", + "folder_type": "AssetCategory", + } sg_ay_dicts[cat_ent_name] = asset_category_entity - sg_ay_dicts_parents[sg_project["id"]].append( - asset_category_entity) + sg_ay_dicts_parents[sg_project["id"]].add(cat_ent_name) parent_id = cat_ent_name @@ -631,13 +605,10 @@ def get_sg_entities( project_code_field, custom_attribs_map, ) - logging.debug( - f"ShotGrid entity {sg_entity} as AYON dict: {sg_ay_dict}" - f" Parent ID: {parent_id}" - ) - sg_ay_dicts[sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB]] = sg_ay_dict - sg_ay_dicts_parents[parent_id].append(sg_ay_dict) + sg_id = sg_ay_dict["attribs"][SHOTGRID_ID_ATTRIB] + sg_ay_dicts[sg_id] = sg_ay_dict + sg_ay_dicts_parents[parent_id].add(sg_id) return sg_ay_dicts, sg_ay_dicts_parents @@ -891,7 +862,6 @@ def get_sg_project_enabled_entities( else: project_entities.append((sg_entity_type, "project")) - logging.debug(f"Project {sg_project} enabled entities: {project_entities}") return project_entities @@ -920,14 +890,12 @@ def get_sg_statuses( status_field = "sg_status_list" entity_status = sg_session.schema_field_read(sg_entity_type, status_field) sg_statuses = entity_status["sg_status_list"]["properties"]["display_values"]["value"] - logging.debug(f"ShotGrid Statuses supported by {sg_entity_type}: {sg_statuses}") return sg_statuses sg_statuses = { status["code"]: status["name"] for status in sg_session.find("Status", [], fields=["name", "code"]) } - logging.debug(f"ShotGrid Statuses: {sg_statuses}") return sg_statuses @@ -948,7 +916,6 @@ def get_sg_tags( tags["name"].lower(): tags["id"] for tags in sg_session.find("Tag", [], fields=["name", "id"]) } - logging.debug(f"ShotGrid tags: {sg_tags}") return sg_tags @@ -988,7 +955,6 @@ def get_sg_pipeline_steps( sg_steps.append((step["code"], step["short_name"].lower())) sg_steps = list(set(sg_steps)) - logging.debug(f"ShotGrid Pipeline Steps: {sg_steps}") return sg_steps @@ -1050,13 +1016,12 @@ def update_ay_entity_custom_attributes( logging.warning("Tags update is not supported yet.") ay_entity.tags = [tag["name"] for tag in attrib_value] elif ay_attrib == "status": - logging.warning("Status update is not supported yet.") # TODO: Implement status update try: # INFO: it was causing error so trying to set status directly ay_entity.status = attrib_value except ValueError as e: # `ValueError: Status ip is not available on project.` - logging.warning(f"Error updating status: {e}") + logging.warning(f"Status sync not implemented: {e}") else: ay_entity.attribs.set(ay_attrib, attrib_value) diff --git a/services/transmitter/transmitter/transmitter.py b/services/transmitter/transmitter/transmitter.py index ac5b614c..aa9da4a7 100644 --- a/services/transmitter/transmitter/transmitter.py +++ b/services/transmitter/transmitter/transmitter.py @@ -104,12 +104,6 @@ def start_processing(self): "entity.folder.tags_changed", ] - logging.debug( - f"Querying AYON every {self.sg_polling_frequency} seconds for events to " - "transmit to Shotgrid, and only on Project's that have the attribute " - "'Shotgrid Push enabled..." - ) - while True: projects_we_care = [ project["name"] From 9ef6410057d3854ef149d69c4d8f15f888a9294f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 6 May 2024 22:28:43 +0200 Subject: [PATCH 20/22] clearing code --- services/processor/processor/processor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/processor/processor/processor.py b/services/processor/processor/processor.py index c51d061d..73242446 100644 --- a/services/processor/processor/processor.py +++ b/services/processor/processor/processor.py @@ -96,8 +96,6 @@ def __init__(self): self.handlers_map = self._get_handlers() if not self.handlers_map: logging.error("No handlers found for the processor, aborting.") - else: - pass def _get_handlers(self): """ Import the handlers found in the `handlers` directory. From d3ab8209c31f5ede5adbf3561f8d89a74e161853 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 6 May 2024 22:30:48 +0200 Subject: [PATCH 21/22] comment on wrong line position --- services/shotgrid_common/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/shotgrid_common/utils.py b/services/shotgrid_common/utils.py index 9f37ff77..e665acff 100644 --- a/services/shotgrid_common/utils.py +++ b/services/shotgrid_common/utils.py @@ -550,11 +550,11 @@ def get_sg_entities( for enabled_entity in project_enabled_entities: entity_name, parent_field = enabled_entity + # Potential fix when shotgrid api returns the same entity more than + # once, we store the entities in a dictionary to avoid duplicates if entity_name in entities_to_ignore: continue - # Potential fix when shotgrid api returns the same entity more than - # once, we store the entities in a dictionary to avoid duplicates sg_entities = sg_session.find( entity_name, filters=[["project", "is", sg_project]], From a4514d7c4d895a5cc8ab1a875d8c0d280d6eee57 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 May 2024 11:21:29 +0200 Subject: [PATCH 22/22] Update custom attributes mapping in AyonShotgridHub and remove default assignment in update_from_shotgrid.py. Add support for custom attribute types. --- .../shotgrid_common/ayon_shotgrid_hub/__init__.py | 11 +++++++---- .../ayon_shotgrid_hub/update_from_shotgrid.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/__init__.py b/services/shotgrid_common/ayon_shotgrid_hub/__init__.py index 94993e77..b93ecc9c 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/__init__.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/__init__.py @@ -67,6 +67,12 @@ class AyonShotgridHub: custom_attribs_types (dict): A dictionary mapping AYON attribute types to Shotgrid field types. """ + + custom_attribs_map = { + "status": "status_list", + "tags": "tags" + } + def __init__(self, project_name, project_code, @@ -100,10 +106,7 @@ def __init__(self, else: self.sg_project_code_field = "code" - self.custom_attribs_map = { - "status": "status_list", - "tags": "tags" - } + # add custom attributes from settings if custom_attribs_map: self.custom_attribs_map.update(custom_attribs_map) diff --git a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py index f2fc3840..09e18a43 100644 --- a/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py +++ b/services/shotgrid_common/ayon_shotgrid_hub/update_from_shotgrid.py @@ -215,7 +215,7 @@ def update_ayon_entity_from_sg_event( ayon_entity_hub, sg_enabled_entities, project_code_field, - custom_attribs_map=None, + custom_attribs_map, ): """Try to update an entity in Ayon.