diff --git a/pype/modules/ftrack/events/action_sync_to_avalon.py b/pype/modules/ftrack/events/action_sync_to_avalon.py index 4e119228c34..01db8154134 100644 --- a/pype/modules/ftrack/events/action_sync_to_avalon.py +++ b/pype/modules/ftrack/events/action_sync_to_avalon.py @@ -15,7 +15,7 @@ class SyncToAvalonServer(BaseAction): - Data(dictionary): - VisualParent(ObjectId) - Avalon Id of parent asset - Parents(array of string) - All parent names except project - - Tasks(array of string) - Tasks on asset + - Tasks(dictionary of dictionaries) - Tasks on asset - FtrackId(string) - entityType(string) - entity's type on Ftrack * All Custom attributes in group 'Avalon' diff --git a/pype/modules/ftrack/events/event_sync_to_avalon.py b/pype/modules/ftrack/events/event_sync_to_avalon.py index d0c9ea2e966..b96741626c1 100644 --- a/pype/modules/ftrack/events/event_sync_to_avalon.py +++ b/pype/modules/ftrack/events/event_sync_to_avalon.py @@ -472,6 +472,16 @@ def filter_updated(self, updates): return filtered_updates def get_ent_path(self, ftrack_id): + """ + Looks for entity in FTrack with 'ftrack_id'. If found returns + concatenated paths from its 'link' elemenent's names. Describes + location of entity in tree. + Args: + ftrack_id (string): entityId of FTrack entity + + Returns: + (string) - example : "/test_project/assets/my_asset" + """ entity = self.ftrack_ents_by_id.get(ftrack_id) if not entity: entity = self.process_session.query( @@ -491,7 +501,7 @@ def launch(self, session, event): self.process_session.commit() except Exception: self.set_process_session(session) - + self.log.debug("start launch") # Reset object values for each launch self.reset_variables() self._cur_event = event @@ -502,7 +512,7 @@ def launch(self, session, event): "move": {}, "add": {} } - + self.log.debug("event_data:: {}".format(event["data"])) entities_info = event["data"]["entities"] found_actions = set() for ent_info in entities_info: @@ -741,8 +751,9 @@ def process_removed(self): avalon_ent["data"]["tasks"] ) - if removed_name in self.task_changes_by_avalon_id[mongo_id]: - self.task_changes_by_avalon_id[mongo_id].remove( + if removed_name in self.task_changes_by_avalon_id[mongo_id].\ + keys(): + self.task_changes_by_avalon_id[mongo_id].pop( removed_name ) @@ -1068,11 +1079,13 @@ def create_entity_in_avalon(self, ftrack_ent, parent_avalon): ) # Tasks - tasks = [] + tasks = {} for child in ftrack_ent["children"]: if child.entity_type.lower() != "task": continue - tasks.append(child["name"]) + self.log.debug("child:: {}".format(child)) + task_type = self._get_task_type(child['entityId']) + tasks[child["name"]] = {"type": task_type} # Visual Parent vis_par = None @@ -1423,8 +1436,8 @@ def process_renamed(self): avalon_ent["data"]["tasks"] ) - if old_name in self.task_changes_by_avalon_id[mongo_id]: - self.task_changes_by_avalon_id[mongo_id].remove(old_name) + if old_name in self.task_changes_by_avalon_id[mongo_id].keys(): + self.task_changes_by_avalon_id[mongo_id].pop(old_name) else: parent_ftrack_ent = self.ftrack_ents_by_id.get(parent_id) if not parent_ftrack_ent: @@ -1442,17 +1455,21 @@ def process_renamed(self): continue child_names.append(child["name"]) - tasks = [task for task in ( - self.task_changes_by_avalon_id[mongo_id] - )] - for task in tasks: - if task not in child_names: - self.task_changes_by_avalon_id[mongo_id].remove( - task + tasks = copy.deepcopy( + self.task_changes_by_avalon_id[mongo_id].keys() + ) + + for task_name in tasks: + if task_name not in child_names: + self.task_changes_by_avalon_id[mongo_id].pop( + task_name ) - if new_name not in self.task_changes_by_avalon_id[mongo_id]: - self.task_changes_by_avalon_id[mongo_id].append(new_name) + task_type = self._get_task_type(ent_info['entityId']) + if new_name not in self.task_changes_by_avalon_id[mongo_id].keys(): + self.task_changes_by_avalon_id[mongo_id][new_name] = { + "type": task_type + } # not_found are not processed since all not found are # not found because they are not synchronizable @@ -1688,8 +1705,12 @@ def process_added(self): self.regex_failed.append(ent_info["entityId"]) continue - if new_name not in self.task_changes_by_avalon_id[mongo_id]: - self.task_changes_by_avalon_id[mongo_id].append(new_name) + task_type = self._get_task_type(ent_info['entityId']) + if new_name not in \ + self.task_changes_by_avalon_id[mongo_id].keys(): + self.task_changes_by_avalon_id[mongo_id][new_name] = { + "type": task_type + } def _mongo_id_configuration( self, @@ -2293,7 +2314,9 @@ def update_entities(self): mongo_changes_bulk = [] for mongo_id, changes in self.updates.items(): filter = {"_id": mongo_id} - change_data = avalon_sync.from_dict_to_set(changes) + avalon_ent = self.avalon_ents_by_id[mongo_id] + is_project = avalon_ent["type"] == "project" + change_data = avalon_sync.from_dict_to_set(changes, is_project) mongo_changes_bulk.append(UpdateOne(filter, change_data)) if not mongo_changes_bulk: @@ -2477,6 +2500,25 @@ def report(self): ) return True + def _get_task_type(self, entityId): + """ + Returns task type ('Props', 'Art') from Task 'entityId' + Args: + entityId (string): entityId of Task + + Returns: + (string) - None if Task not found + """ + task_type = None + entity = self.process_session.query( + self.entities_query_by_id.format( + self.cur_project["id"], entityId + ) + ).first() + if entity: + task_type = entity["type"]["name"] + return task_type + def register(session, plugins_presets): '''Register plugin. Called when used as an plugin.'''