mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
integrate hierarchy ftrack temporary python 2 fix
This commit is contained in:
parent
e331518ddb
commit
019562e5ac
2 changed files with 341 additions and 41 deletions
|
|
@ -1,13 +1,12 @@
|
||||||
import sys
|
import sys
|
||||||
import six
|
import six
|
||||||
import collections
|
|
||||||
import pyblish.api
|
import pyblish.api
|
||||||
from avalon import io
|
from avalon import io
|
||||||
|
|
||||||
from pype.modules.ftrack.lib.avalon_sync import (
|
try:
|
||||||
CUST_ATTR_AUTO_SYNC,
|
from pype.modules.ftrack.lib.avalon_sync import CUST_ATTR_AUTO_SYNC
|
||||||
get_pype_attr
|
except Exception:
|
||||||
)
|
CUST_ATTR_AUTO_SYNC = "avalon_auto_sync"
|
||||||
|
|
||||||
|
|
||||||
class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
||||||
|
|
@ -37,6 +36,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
||||||
order = pyblish.api.IntegratorOrder - 0.04
|
order = pyblish.api.IntegratorOrder - 0.04
|
||||||
label = 'Integrate Hierarchy To Ftrack'
|
label = 'Integrate Hierarchy To Ftrack'
|
||||||
families = ["shot"]
|
families = ["shot"]
|
||||||
|
hosts = ["hiero"]
|
||||||
optional = False
|
optional = False
|
||||||
|
|
||||||
def process(self, context):
|
def process(self, context):
|
||||||
|
|
@ -74,15 +74,6 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
||||||
self.auto_sync_on(project)
|
self.auto_sync_on(project)
|
||||||
|
|
||||||
def import_to_ftrack(self, input_data, parent=None):
|
def import_to_ftrack(self, input_data, parent=None):
|
||||||
# Prequery hiearchical custom attributes
|
|
||||||
hier_custom_attributes = get_pype_attr(self.session)[1]
|
|
||||||
hier_attr_by_key = {
|
|
||||||
attr["key"]: attr
|
|
||||||
for attr in hier_custom_attributes
|
|
||||||
}
|
|
||||||
# Get ftrack api module (as they are different per python version)
|
|
||||||
ftrack_api = self.context.data["ftrackPythonModule"]
|
|
||||||
|
|
||||||
for entity_name in input_data:
|
for entity_name in input_data:
|
||||||
entity_data = input_data[entity_name]
|
entity_data = input_data[entity_name]
|
||||||
entity_type = entity_data['entity_type']
|
entity_type = entity_data['entity_type']
|
||||||
|
|
@ -125,34 +116,12 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
||||||
i for i in self.context if i.data['asset'] in entity['name']
|
i for i in self.context if i.data['asset'] in entity['name']
|
||||||
]
|
]
|
||||||
for key in custom_attributes:
|
for key in custom_attributes:
|
||||||
hier_attr = hier_attr_by_key.get(key)
|
assert (key in entity['custom_attributes']), (
|
||||||
# Use simple method if key is not hierarchical
|
'Missing custom attribute key: `{0}` in attrs: '
|
||||||
if not hier_attr:
|
'`{1}`'.format(key, entity['custom_attributes'].keys())
|
||||||
assert (key in entity['custom_attributes']), (
|
)
|
||||||
'Missing custom attribute key: `{0}` in attrs: '
|
|
||||||
'`{1}`'.format(key, entity['custom_attributes'].keys())
|
|
||||||
)
|
|
||||||
|
|
||||||
entity['custom_attributes'][key] = custom_attributes[key]
|
entity['custom_attributes'][key] = custom_attributes[key]
|
||||||
|
|
||||||
else:
|
|
||||||
# Use ftrack operations method to set hiearchical
|
|
||||||
# attribute value.
|
|
||||||
# - this is because there may be non hiearchical custom
|
|
||||||
# attributes with different properties
|
|
||||||
entity_key = collections.OrderedDict({
|
|
||||||
"configuration_id": hier_attr["id"],
|
|
||||||
"entity_id": entity["id"]
|
|
||||||
})
|
|
||||||
self.session.recorded_operations.push(
|
|
||||||
ftrack_api.operation.UpdateEntityOperation(
|
|
||||||
"ContextCustomAttributeValue",
|
|
||||||
entity_key,
|
|
||||||
"value",
|
|
||||||
ftrack_api.symbol.NOT_SET,
|
|
||||||
custom_attributes[key]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
instance.data['ftrackEntity'] = entity
|
instance.data['ftrackEntity'] = entity
|
||||||
|
|
|
||||||
331
pype/plugins/ftrack/publish/integrate_hierarchy_ftrack_SP.py
Normal file
331
pype/plugins/ftrack/publish/integrate_hierarchy_ftrack_SP.py
Normal file
|
|
@ -0,0 +1,331 @@
|
||||||
|
import sys
|
||||||
|
import six
|
||||||
|
import collections
|
||||||
|
import pyblish.api
|
||||||
|
from avalon import io
|
||||||
|
|
||||||
|
from pype.modules.ftrack.lib.avalon_sync import (
|
||||||
|
CUST_ATTR_AUTO_SYNC,
|
||||||
|
get_pype_attr
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
||||||
|
"""
|
||||||
|
Create entities in ftrack based on collected data from premiere
|
||||||
|
Example of entry data:
|
||||||
|
{
|
||||||
|
"ProjectXS": {
|
||||||
|
"entity_type": "Project",
|
||||||
|
"custom_attributes": {
|
||||||
|
"fps": 24,...
|
||||||
|
},
|
||||||
|
"tasks": [
|
||||||
|
"Compositing",
|
||||||
|
"Lighting",... *task must exist as task type in project schema*
|
||||||
|
],
|
||||||
|
"childs": {
|
||||||
|
"sq01": {
|
||||||
|
"entity_type": "Sequence",
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
order = pyblish.api.IntegratorOrder - 0.04
|
||||||
|
label = 'Integrate Hierarchy To Ftrack'
|
||||||
|
families = ["shot"]
|
||||||
|
hosts = ["standalonepublisher"]
|
||||||
|
optional = False
|
||||||
|
|
||||||
|
def process(self, context):
|
||||||
|
self.context = context
|
||||||
|
if "hierarchyContext" not in self.context.data:
|
||||||
|
return
|
||||||
|
|
||||||
|
hierarchy_context = self.context.data["hierarchyContext"]
|
||||||
|
|
||||||
|
self.session = self.context.data["ftrackSession"]
|
||||||
|
project_name = self.context.data["projectEntity"]["name"]
|
||||||
|
query = 'Project where full_name is "{}"'.format(project_name)
|
||||||
|
project = self.session.query(query).one()
|
||||||
|
auto_sync_state = project[
|
||||||
|
"custom_attributes"][CUST_ATTR_AUTO_SYNC]
|
||||||
|
|
||||||
|
if not io.Session:
|
||||||
|
io.install()
|
||||||
|
|
||||||
|
self.ft_project = None
|
||||||
|
|
||||||
|
input_data = hierarchy_context
|
||||||
|
|
||||||
|
# disable termporarily ftrack project's autosyncing
|
||||||
|
if auto_sync_state:
|
||||||
|
self.auto_sync_off(project)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# import ftrack hierarchy
|
||||||
|
self.import_to_ftrack(input_data)
|
||||||
|
except Exception:
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
if auto_sync_state:
|
||||||
|
self.auto_sync_on(project)
|
||||||
|
|
||||||
|
def import_to_ftrack(self, input_data, parent=None):
|
||||||
|
# Prequery hiearchical custom attributes
|
||||||
|
hier_custom_attributes = get_pype_attr(self.session)[1]
|
||||||
|
hier_attr_by_key = {
|
||||||
|
attr["key"]: attr
|
||||||
|
for attr in hier_custom_attributes
|
||||||
|
}
|
||||||
|
# Get ftrack api module (as they are different per python version)
|
||||||
|
ftrack_api = self.context.data["ftrackPythonModule"]
|
||||||
|
|
||||||
|
for entity_name in input_data:
|
||||||
|
entity_data = input_data[entity_name]
|
||||||
|
entity_type = entity_data['entity_type']
|
||||||
|
self.log.debug(entity_data)
|
||||||
|
self.log.debug(entity_type)
|
||||||
|
|
||||||
|
if entity_type.lower() == 'project':
|
||||||
|
query = 'Project where full_name is "{}"'.format(entity_name)
|
||||||
|
entity = self.session.query(query).one()
|
||||||
|
self.ft_project = entity
|
||||||
|
self.task_types = self.get_all_task_types(entity)
|
||||||
|
|
||||||
|
elif self.ft_project is None or parent is None:
|
||||||
|
raise AssertionError(
|
||||||
|
"Collected items are not in right order!"
|
||||||
|
)
|
||||||
|
|
||||||
|
# try to find if entity already exists
|
||||||
|
else:
|
||||||
|
query = (
|
||||||
|
'TypedContext where name is "{0}" and '
|
||||||
|
'project_id is "{1}"'
|
||||||
|
).format(entity_name, self.ft_project["id"])
|
||||||
|
try:
|
||||||
|
entity = self.session.query(query).one()
|
||||||
|
except Exception:
|
||||||
|
entity = None
|
||||||
|
|
||||||
|
# Create entity if not exists
|
||||||
|
if entity is None:
|
||||||
|
entity = self.create_entity(
|
||||||
|
name=entity_name,
|
||||||
|
type=entity_type,
|
||||||
|
parent=parent
|
||||||
|
)
|
||||||
|
# self.log.info('entity: {}'.format(dict(entity)))
|
||||||
|
# CUSTOM ATTRIBUTES
|
||||||
|
custom_attributes = entity_data.get('custom_attributes', [])
|
||||||
|
instances = [
|
||||||
|
i for i in self.context if i.data['asset'] in entity['name']
|
||||||
|
]
|
||||||
|
for key in custom_attributes:
|
||||||
|
hier_attr = hier_attr_by_key.get(key)
|
||||||
|
# Use simple method if key is not hierarchical
|
||||||
|
if not hier_attr:
|
||||||
|
assert (key in entity['custom_attributes']), (
|
||||||
|
'Missing custom attribute key: `{0}` in attrs: '
|
||||||
|
'`{1}`'.format(key, entity['custom_attributes'].keys())
|
||||||
|
)
|
||||||
|
|
||||||
|
entity['custom_attributes'][key] = custom_attributes[key]
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Use ftrack operations method to set hiearchical
|
||||||
|
# attribute value.
|
||||||
|
# - this is because there may be non hiearchical custom
|
||||||
|
# attributes with different properties
|
||||||
|
entity_key = collections.OrderedDict({
|
||||||
|
"configuration_id": hier_attr["id"],
|
||||||
|
"entity_id": entity["id"]
|
||||||
|
})
|
||||||
|
self.session.recorded_operations.push(
|
||||||
|
ftrack_api.operation.UpdateEntityOperation(
|
||||||
|
"ContextCustomAttributeValue",
|
||||||
|
entity_key,
|
||||||
|
"value",
|
||||||
|
ftrack_api.symbol.NOT_SET,
|
||||||
|
custom_attributes[key]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for instance in instances:
|
||||||
|
instance.data['ftrackEntity'] = entity
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
# TASKS
|
||||||
|
tasks = entity_data.get('tasks', [])
|
||||||
|
existing_tasks = []
|
||||||
|
tasks_to_create = []
|
||||||
|
for child in entity['children']:
|
||||||
|
if child.entity_type.lower() == 'task':
|
||||||
|
existing_tasks.append(child['name'].lower())
|
||||||
|
# existing_tasks.append(child['type']['name'])
|
||||||
|
|
||||||
|
for task_name in tasks:
|
||||||
|
task_type = tasks[task_name]["type"]
|
||||||
|
if task_name.lower() in existing_tasks:
|
||||||
|
print("Task {} already exists".format(task_name))
|
||||||
|
continue
|
||||||
|
tasks_to_create.append((task_name, task_type))
|
||||||
|
|
||||||
|
for task_name, task_type in tasks_to_create:
|
||||||
|
self.create_task(
|
||||||
|
name=task_name,
|
||||||
|
task_type=task_type,
|
||||||
|
parent=entity
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
# Incoming links.
|
||||||
|
self.create_links(entity_data, entity)
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
# Create notes.
|
||||||
|
user = self.session.query(
|
||||||
|
"User where username is \"{}\"".format(self.session.api_user)
|
||||||
|
).first()
|
||||||
|
if user:
|
||||||
|
for comment in entity_data.get("comments", []):
|
||||||
|
entity.create_note(comment, user)
|
||||||
|
else:
|
||||||
|
self.log.warning(
|
||||||
|
"Was not able to query current User {}".format(
|
||||||
|
self.session.api_user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
# Import children.
|
||||||
|
if 'childs' in entity_data:
|
||||||
|
self.import_to_ftrack(
|
||||||
|
entity_data['childs'], entity)
|
||||||
|
|
||||||
|
def create_links(self, entity_data, entity):
|
||||||
|
# Clear existing links.
|
||||||
|
for link in entity.get("incoming_links", []):
|
||||||
|
self.session.delete(link)
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
# Create new links.
|
||||||
|
for input in entity_data.get("inputs", []):
|
||||||
|
input_id = io.find_one({"_id": input})["data"]["ftrackId"]
|
||||||
|
assetbuild = self.session.get("AssetBuild", input_id)
|
||||||
|
self.log.debug(
|
||||||
|
"Creating link from {0} to {1}".format(
|
||||||
|
assetbuild["name"], entity["name"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.session.create(
|
||||||
|
"TypedContextLink", {"from": assetbuild, "to": entity}
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_all_task_types(self, project):
|
||||||
|
tasks = {}
|
||||||
|
proj_template = project['project_schema']
|
||||||
|
temp_task_types = proj_template['_task_type_schema']['types']
|
||||||
|
|
||||||
|
for type in temp_task_types:
|
||||||
|
if type['name'] not in tasks:
|
||||||
|
tasks[type['name']] = type
|
||||||
|
|
||||||
|
return tasks
|
||||||
|
|
||||||
|
def create_task(self, name, task_type, parent):
|
||||||
|
task = self.session.create('Task', {
|
||||||
|
'name': name,
|
||||||
|
'parent': parent
|
||||||
|
})
|
||||||
|
# TODO not secured!!! - check if task_type exists
|
||||||
|
self.log.info(task_type)
|
||||||
|
self.log.info(self.task_types)
|
||||||
|
task['type'] = self.task_types[task_type]
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
return task
|
||||||
|
|
||||||
|
def create_entity(self, name, type, parent):
|
||||||
|
entity = self.session.create(type, {
|
||||||
|
'name': name,
|
||||||
|
'parent': parent
|
||||||
|
})
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
return entity
|
||||||
|
|
||||||
|
def auto_sync_off(self, project):
|
||||||
|
project["custom_attributes"][CUST_ATTR_AUTO_SYNC] = False
|
||||||
|
|
||||||
|
self.log.info("Ftrack autosync swithed off")
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
|
|
||||||
|
def auto_sync_on(self, project):
|
||||||
|
|
||||||
|
project["custom_attributes"][CUST_ATTR_AUTO_SYNC] = True
|
||||||
|
|
||||||
|
self.log.info("Ftrack autosync swithed on")
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.session.commit()
|
||||||
|
except Exception:
|
||||||
|
tp, value, tb = sys.exc_info()
|
||||||
|
self.session.rollback()
|
||||||
|
self.session._configure_locations()
|
||||||
|
six.reraise(tp, value, tb)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue