diff --git a/pype/modules/ftrack/events/event_thumbnail_updates.py b/pype/modules/ftrack/events/event_thumbnail_updates.py index 94783629f0..9d816a79e5 100644 --- a/pype/modules/ftrack/events/event_thumbnail_updates.py +++ b/pype/modules/ftrack/events/event_thumbnail_updates.py @@ -1,7 +1,16 @@ +import collections from pype.modules.ftrack import BaseEvent class ThumbnailEvents(BaseEvent): + settings_key = "thumbnail_updates" + + # TODO remove `join_query_keys` as it should be in `BaseHandler` + @staticmethod + def join_query_keys(keys): + """Helper to join keys to query.""" + return ",".join(["\"{}\"".format(key) for key in keys]) + def launch(self, session, event): """Updates thumbnails of entities from new AssetVersion.""" filtered_entities = self.filter_entities(event) @@ -35,10 +44,91 @@ class ThumbnailEvents(BaseEvent): project_name, self.__class__.__name__ )) return + + self.log.debug("Processing {} on project \"{}\".".format( + self.__class__.__name__, project_name + )) + + parent_levels = event_settings["levels"] + if parent_levels < 1: + self.log.debug( + "Project \"{}\" has parent levels set to {}. Skipping".format( + project_name, parent_levels + ) + ) + return + + asset_version_ids = set() + for entity in entities_info: + asset_version_ids.add(entity["entityId"]) + + # Do not use attribute `asset_version_entities` will be filtered + # to when `asset_versions_by_id` is filled + asset_version_entities = session.query(( + "select task_id, thumbnail_id from AssetVersion where id in ({})" + ).format(self.join_query_keys(asset_version_ids))).all() + + asset_versions_by_id = {} + for asset_version_entity in asset_version_entities: + if not asset_version_entity["thumbnail_id"]: + continue + entity_id = asset_version_entity["id"] + asset_versions_by_id[entity_id] = asset_version_entity + + if not asset_versions_by_id: + self.log.debug("None of asset versions has set thumbnail id.") + return + + entity_ids_by_asset_version_id = collections.defaultdict(list) + hierarchy_ids = set() + for entity_info in entities_info: + entity_id = entity_info["entityId"] + if entity_id not in asset_versions_by_id: continue - continue + parent_ids = [] + counter = None + for parent_info in entity_info["parents"]: + if counter is not None: + if counter >= parent_levels: + break + parent_ids.append(parent_info["entityId"]) + counter += 1 + elif parent_info["entityType"] == "asset": + counter = 0 + + for parent_id in parent_ids: + hierarchy_ids.add(parent_id) + entity_ids_by_asset_version_id[entity_id].append(parent_id) + + for asset_version_entity in asset_versions_by_id.values(): + task_id = asset_version_entity["task_id"] + if task_id: + hierarchy_ids.add(task_id) + asset_version_id = asset_version_entity["id"] + entity_ids_by_asset_version_id[asset_version_id].append( + task_id + ) + + entities = session.query(( + "select thumbnail_id, link from TypedContext where id in ({})" + ).format(self.join_query_keys(hierarchy_ids))).all() + entities_by_id = { + entity["id"]: entity + for entity in entities + } + + for version_id, version_entity in asset_versions_by_id.items(): + for entity_id in entity_ids_by_asset_version_id[version_id]: + entity = entities_by_id.get(entity_id) + if not entity: + continue + + entity["thumbnail_id"] = version_entity["thumbnail_id"] + self.log.info("Updating thumbnail for entity [ {} ]".format( + self.get_entity_path(entity) + )) try: session.commit()