Skip to content

Commit

Permalink
Merge pull request #147 from ynput/enhancement/125-ay-6234_sync-statuses
Browse files Browse the repository at this point in the history
Sync: Folder and Task statuses
  • Loading branch information
iLLiCiTiT authored Oct 16, 2024
2 parents ce148c6 + e4b0540 commit b013fc4
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 9 deletions.
2 changes: 1 addition & 1 deletion service_tools/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ colorama==0.4.6
ftrack-python-api==2.3.3
future==0.18.2
idna==3.4
ayon-python-api==1.0.0rc3
ayon-python-api==1.0.10
pydantic==1.10.2
pyparsing==2.4.7
python-dateutil==2.8.2
Expand Down
2 changes: 1 addition & 1 deletion services/leecher/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["Ynput s.r.o. <[email protected]>"]

[tool.poetry.dependencies]
python = ">=3.9,<3.10"
ayon-python-api = "1.0.0"
ayon-python-api = "1.0.10"
ftrack-python-api = "2.3.3"

[tool.poetry.dev-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class SyncProcess:
interest_base_types = ["show", "task"]
ignore_ent_types = ["Milestone"]
ignore_change_keys = [
"statusid",
"thumbid",
"priorityid",
]
Expand Down Expand Up @@ -118,6 +117,7 @@ def __init__(self, event_handler, session, event, log):
self._ft_std_cust_attrs = None
self._ft_object_type_name_by_id = None
self._ft_task_type_name_by_id = None
self._ft_status_names_by_id = None

self._created_entity_by_ftrack_id = {}
self._hierarchy_changed_by_ftrack_id = {}
Expand Down Expand Up @@ -409,6 +409,16 @@ def ft_task_type_name_by_id(self):
}
return self._ft_task_type_name_by_id

@property
def ft_status_names_by_id(self):
if self._ft_status_names_by_id is None:
statuses = self.session.query("select id, name from Status").all()
self._ft_status_names_by_id = {
statuse["id"]: statuse["name"]
for statuse in statuses
}
return self._ft_status_names_by_id

@property
def has_valid_entity_types(self):
return self._has_valid_entity_types
Expand Down Expand Up @@ -1256,6 +1266,27 @@ def _update_project_task_types(self):

project_entity.task_types = new_task_types

def _update_project_statuses(self):
# TODO implement statuses sync to AYON project
return
project_entity = self.entity_hub.project_entity
src_statuses = {
statuse.name.lower(): statuse
for statuse in project_entity.statuses
}
new_statuses = []
project_schema = self.ft_project["project_schema"]
for task_type in project_schema["task_type_schema"]["types"]:
status_name = task_type["name"]
ayon_status = src_statuses.get(status_name.lower())
if ayon_status is None:
new_statuses.append({
"name": status_name,
"color": task_type["color"]
})

project_entity.statuses = new_statuses

def _propagate_task_type_changes(self, task_type_changes):
if not task_type_changes:
return
Expand Down Expand Up @@ -1289,6 +1320,44 @@ def _propagate_task_type_changes(self, task_type_changes):
self.log.debug(
f"Changed task type {prev_task_type} -> {new_type_name}")

def _propagate_status_changes(self, status_changes):
if not status_changes:
return

project_entity = self.entity_hub.project_entity
ayon_statuses_by_name = {
status.name.lower(): status
for status in project_entity.statuses
}
ft_status_names_by_id = self.ft_status_names_by_id
to_change = []
project_need_update = False
for ftrack_id, (entity, info) in status_changes.items():
new_status_id = info["changes"]["statusid"]["new"]
new_status_name = ft_status_names_by_id[new_status_id]
if entity.status.lower() == new_status_name.lower():
continue

ayon_status = ayon_statuses_by_name.get(new_status_name.lower())
if (
ayon_status is None
or entity.entity_type not in ayon_status.scope
):
# TODO implement statuses sync to AYON project
continue
project_need_update = True

to_change.append((entity, new_status_name))

if project_need_update:
self._update_project_statuses()

for entity, new_status_name in to_change:
prev_status_name = entity.status
entity.status = new_status_name
self.log.debug(
f"Changed status {prev_status_name} -> {new_status_name}")

def _propagate_attrib_changes(self):
std_cust_attr = self.ft_std_cust_attrs
hier_cust_attr = self.ft_hier_cust_attrs
Expand All @@ -1298,6 +1367,7 @@ def _propagate_attrib_changes(self):
# set all attributes from ftrack
created_ftrack_ids = set(self._created_entity_by_ftrack_id.keys())
task_type_changes = {}
status_changes = {}
for ftrack_id, info in self.entities_by_action["update"].items():
if ftrack_id in created_ftrack_ids:
continue
Expand Down Expand Up @@ -1327,8 +1397,14 @@ def _propagate_attrib_changes(self):

for key, change_info in info["changes"].items():
value = change_info["new"]
if key == "typeid" and entity.entity_type == "task":
task_type_changes[ftrack_id] = (entity, info)
if key == "typeid":
if entity.entity_type == "task":
task_type_changes[ftrack_id] = (entity, info)
continue

if key == "statusid":
status_changes[ftrack_id] = (entity, info)
continue

default_attr_key = DEFAULT_ATTRS_MAPPING.get(key)

Expand Down Expand Up @@ -1365,6 +1441,7 @@ def _propagate_attrib_changes(self):
entity.attribs[dst_key] = value

self._propagate_task_type_changes(task_type_changes)
self._propagate_status_changes(status_changes)

def _create_ft_attr_operation(
self, conf_id, entity_id, is_new, new_value, old_value=None
Expand Down
48 changes: 45 additions & 3 deletions services/processor/processor/lib/sync_from_ftrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
import collections
import time
import logging
from typing import Any, Dict

import arrow
from ayon_api import (
get_project,
create_project,
slugify_string,
)
from ayon_api.entity_hub import EntityHub
from ayon_api.entity_hub import EntityHub, BaseEntity
import ftrack_api
from ftrack_common import (
CUST_ATTR_KEY_SERVER_ID,
Expand Down Expand Up @@ -211,7 +212,9 @@ def sync_to_server(self):
self._report_items.extend([
{
"type": "label",
"value": "## Project does not exist in AYON"
"value": (
f"## Project '{project_name}' does not exist in AYON"
)
},
{
"type": "label",
Expand Down Expand Up @@ -310,7 +313,7 @@ def sync_to_server(self):
self.log.info("Querying project hierarchy from ftrack")
ft_entities = ft_session.query((
"select id, name, parent_id, type_id, object_type_id, status_id"
", start_date, end_date, description" #, bid, status_id"
", start_date, end_date, description, status_id"
" from TypedContext where project_id is \"{}\""
).format(ft_project["id"])).all()
t_ft_entities_4 = time.perf_counter()
Expand Down Expand Up @@ -686,9 +689,44 @@ def _add_children_to_queue(ft_entity_id):
for child in entity.children:
deactivate_queue.append(child)

def _set_entity_status(
self,
ft_entity: ftrack_api.entity.base.Entity,
entity: BaseEntity,
ftrack_statuses: Dict[str, str],
ayon_statuses: Dict[str, Any],
):
# QUESTION should we log all invalid/missing statuses?
# QUESTION should we update AYON project statuses if status
# is not available?
if entity.entity_type not in ("folder", "task"):
return

ft_status_name = ftrack_statuses.get(ft_entity.get("status_id"))
if ft_status_name is None:
return

ayon_status = ayon_statuses.get(ft_status_name.lower())
if ayon_status is None:
return

scope = ayon_status.scope
if entity.entity_type in scope:
entity.set_status(ayon_status["name"])

def update_attributes_from_ftrack(
self, cust_attr_value_by_entity_id, ft_entities_by_id
):
ftrack_statuses = {
status["id"]: status["name"]
for status in self._ft_session.query(
"select id, name from Status"
).all()
}
ayon_statuses = {
status["name"].lower(): status
for status in self._entity_hub.project_entity["statuses"]
}
hierarchy_queue = collections.deque()
hierarchy_queue.append(self._entity_hub.project_entity)
while hierarchy_queue:
Expand All @@ -710,6 +748,10 @@ def update_attributes_from_ftrack(
entity.attribs[FTRACK_ID_ATTRIB] = ftrack_id
entity.attribs[FTRACK_PATH_ATTRIB] = path

self._set_entity_status(
ft_entity, entity, ftrack_statuses, ayon_statuses
)

for attr_name, value in (
("startDate", ft_entity["start_date"]),
("endDate", ft_entity["end_date"]),
Expand Down
2 changes: 1 addition & 1 deletion services/processor/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["Ynput s.r.o. <[email protected]>"]

[tool.poetry.dependencies]
python = ">=3.9,<3.10"
ayon-python-api = "1.0.0"
ayon-python-api = "1.0.10"
ftrack-python-api = "2.3.3"

[tool.poetry.dev-dependencies]
Expand Down

0 comments on commit b013fc4

Please sign in to comment.