Creating backup

This commit is contained in:
Jakub Trllo 2018-11-26 14:26:44 +01:00
parent b8d803c2e7
commit 8c093ce2ad
8 changed files with 229 additions and 203 deletions

View file

@ -7,10 +7,11 @@ import os
import ftrack_api
import json
import re
from pype import lib
from ftrack_action_handler import BaseAction
from avalon import io, inventory, lib
from avalon import io, inventory
from avalon.vendor import toml
from pype.ftrack import ftrack_utils
class SyncToAvalon(BaseAction):
'''Edit meta data action.'''
@ -27,6 +28,7 @@ class SyncToAvalon(BaseAction):
def discover(self, session, entities, event):
''' Validation '''
discover = False
for entity in entities:
if entity.entity_type.lower() not in ['task', 'assetversion']:
@ -55,7 +57,7 @@ class SyncToAvalon(BaseAction):
print("action <" + self.__class__.__name__ + "> is running")
#TODO AVALON_PROJECTS, AVALON_ASSET, AVALON_SILO should be set up otherwise console log shows avalon debug
self.setAvalonAttributes(session)
self.setAvalonAttributes()
self.importable = []
# get from top entity in hierarchy all parent entities
@ -107,9 +109,10 @@ class SyncToAvalon(BaseAction):
'success': True,
'message': "Synchronization was successfull"
}
def setAvalonAttributes(self, session):
def setAvalonAttributes(self):
self.custom_attributes = []
all_avalon_attr = session.query('CustomAttributeGroup where name is "avalon"').one()
all_avalon_attr = self.session.query('CustomAttributeGroup where name is "avalon"').one()
for cust_attr in all_avalon_attr['custom_attribute_configurations']:
if 'avalon_' not in cust_attr['key']:
self.custom_attributes.append(cust_attr)
@ -132,28 +135,6 @@ class SyncToAvalon(BaseAction):
print("Name of {} was changed to {}".format(input_name, name))
return name
def getConfig(self, entity):
apps = []
for app in entity['custom_attributes']['applications']:
try:
label = toml.load(lib.which_app(app))['label']
apps.append({'name':app, 'label':label})
except Exception as e:
print('Error with application {0} - {1}'.format(app, e))
config = {
'schema': 'avalon-core:config-1.0',
'tasks': [{'name': ''}],
'apps': apps,
# TODO redo work!!!
'template': {
'workfile': '{asset[name]}_{task[name]}_{version:0>3}<_{comment}>',
'work': '{root}/{project}/{hierarchy}/{asset}/work/{task}',
'publish':'{root}/{project}/{hierarchy}/{asset}/publish/{family}/{subset}/v{version}/{projectcode}_{asset}_{subset}_v{version}.{representation}'}
}
return config
def importToAvalon(self, session, entity):
eLinks = []
@ -170,9 +151,6 @@ class SyncToAvalon(BaseAction):
os.environ["AVALON_PROJECT"] = entityProj["full_name"]
os.environ["AVALON_ASSET"] = entityProj['full_name']
# Set project template
template = {"schema": "avalon-core:inventory-1.0"}
# --- Begin: PUSH TO Avalon ---
io.install()
## ----- PROJECT ------
@ -185,25 +163,28 @@ class SyncToAvalon(BaseAction):
data['entityType'] = entity_type
for cust_attr in self.custom_attributes:
key = cust_attr['key']
if cust_attr['entity_type'].lower() in ['asset']:
data[cust_attr['key']] = entity['custom_attributes'][cust_attr['key']]
data[key] = entity['custom_attributes'][key]
elif cust_attr['entity_type'].lower() in ['show'] and entity_type.lower() == 'project':
data[cust_attr['key']] = entity['custom_attributes'][cust_attr['key']]
data[key] = entity['custom_attributes'][key]
elif cust_attr['entity_type'].lower() in ['task'] and entity_type.lower() != 'project':
# Put space between capitals (e.g. 'AssetBuild' -> 'Asset Build')
entity_type = re.sub(r"(\w)([A-Z])", r"\1 \2", entity_type)
entity_type_full = re.sub(r"(\w)([A-Z])", r"\1 \2", entity_type)
# Get object id of entity type
ent_obj_type_id = session.query('ObjectType where name is "{}"'.format(entity_type)).one()['id']
ent_obj_type_id = session.query('ObjectType where name is "{}"'.format(entity_type_full)).one()['id']
if cust_attr['object_type_id'] == ent_obj_type_id:
data[cust_attr['key']] = entity['custom_attributes'][cust_attr['key']]
data[key] = entity['custom_attributes'][key]
if entity.entity_type.lower() in ['project']:
if entity_type.lower() in ['project']:
# Set project Config
config = self.getConfig(entity)
config = ftrack_utils.get_config(entity)
# Set project template
template = lib.get_avalon_project_template_schema()
if avalon_project is None:
inventory.save(entityProj['full_name'], config, template)
@ -233,7 +214,7 @@ class SyncToAvalon(BaseAction):
## ----- ASSETS ------
# Presets:
# TODO how to check if entity is Asset Library or AssetBuild?
if entity.entity_type in ['AssetBuild', 'Library']:
if entity_type in ['AssetBuild', 'Library']:
silo = 'Assets'
else:
silo = 'Film'

View file

@ -1,18 +1,20 @@
import os
import sys
import re
import ftrack_api
from ftrack_event_handler import BaseEvent
from avalon import io, inventory, lib
from pype import lib
from avalon import io, inventory
from avalon.vendor import toml
import re
from bson.objectid import ObjectId
from pype.ftrack import ftrack_utils
class Sync_to_Avalon(BaseEvent):
def launch(self, session, entities, event):
self.ca_mongoid = 'avalon_mongo_id'
self.proj = None
for entity in entities:
try:
base_proj = entity['link'][0]
@ -37,12 +39,9 @@ class Sync_to_Avalon(BaseEvent):
io.uninstall()
self.importEntities = []
exceptions = ['assetversion', 'job', 'user']
for entity in entities:
if entity.entity_type.lower() in exceptions:
continue
elif entity.entity_type.lower() in ['task']:
if entity.entity_type.lower() in ['task']:
entity = entity['parent']
try:
mongo_id = entity['custom_attributes'][self.ca_mongoid]
@ -72,46 +71,48 @@ class Sync_to_Avalon(BaseEvent):
def importToAvalon(self, entity):
data = {}
entity_type = entity.entity_type
type = 'asset'
name = entity['name']
silo = 'Film'
if entity.entity_type == 'Project':
if entity_type in ['Project']:
type = 'project'
name = entity['full_name']
data['code'] = entity['name']
elif entity.entity_type in ['AssetBuild', 'Library']:
elif entity_type in ['AssetBuild', 'Library']:
silo = 'Assets'
os.environ["AVALON_ASSET"] = name
os.environ["AVALON_SILO"] = silo
entity_type = entity.entity_type
data['ftrackId'] = entity['id']
data['entityType'] = entity_type
for cust_attr in self.custom_attributes:
key = cust_attr['key']
if cust_attr['entity_type'].lower() in ['asset']:
data[cust_attr['key']] = entity['custom_attributes'][cust_attr['key']]
data[key] = entity['custom_attributes'][key]
elif cust_attr['entity_type'].lower() in ['show'] and entity_type.lower() == 'project':
data[cust_attr['key']] = entity['custom_attributes'][cust_attr['key']]
data[key] = entity['custom_attributes'][key]
elif cust_attr['entity_type'].lower() in ['task'] and entity_type.lower() != 'project':
# Put space between capitals (e.g. 'AssetBuild' -> 'Asset Build')
entity_type = re.sub(r"(\w)([A-Z])", r"\1 \2", entity_type)
entity_type_full = re.sub(r"(\w)([A-Z])", r"\1 \2", entity_type)
# Get object id of entity type
ent_obj_type_id = self.session.query('ObjectType where name is "{}"'.format(entity_type)).one()['id']
ent_obj_type_id = self.session.query('ObjectType where name is "{}"'.format(entity_type_full)).one()['id']
if cust_attr['object_type_id'] == ent_obj_type_id:
data[cust_attr['key']] = entity['custom_attributes'][cust_attr['key']]
data[key] = entity['custom_attributes'][key]
mongo_id = entity['custom_attributes'][self.ca_mongoid]
if entity_type in ['project']:
config = self.getConfig()
template = {"schema": "avalon-core:inventory-1.0"}
if entity_type.lower() in ['project']:
config = ftrack_utils.get_config(entity)
template = lib.get_avalon_project_template_schema()
if self.avalon_project is None:
mongo_id = inventory.save(self.proj['full_name'], config, template)
@ -131,6 +132,10 @@ class Sync_to_Avalon(BaseEvent):
}})
return
if self.avalon_project is None:
self.importToAvalon(self.proj)
eLinks = []
for e in entity['link']:
tmp = self.session.get(e['type'], e['id'])
@ -161,13 +166,12 @@ class Sync_to_Avalon(BaseEvent):
data['visualParent'] = parentId
data['hierarchy'] = hierarchy
if self.avalon_project is None:
self.importToAvalon(self.proj)
avalon_asset = io.find_one({'_id': ObjectId(mongo_id)})
if avalon_asset is None:
avalon_asset = io.find_one({'type': type, 'name': name})
if avalon_asset is None:
if avalon_asset is None:
mongo_id = inventory.create_asset(name, silo, data, self.projectId)
elif avalon_asset['name'] != name:
mongo_id = inventory.create_asset(name, silo, data, self.projectId)
io.update_many(
@ -176,7 +180,7 @@ class Sync_to_Avalon(BaseEvent):
'name':name,
'silo':silo,
'data':data,
'Parent': self.projectId}})
'parent': self.projectId}})
def checkName(self, input_name):
@ -187,27 +191,6 @@ class Sync_to_Avalon(BaseEvent):
print("Name of {} was changed to {}".format(input_name, name))
return name
def getConfig(self, entity):
apps = []
for app in entity['custom_attributes']['applications']:
try:
label = toml.load(lib.which_app(app))['label']
apps.append({'name':app, 'label':label})
except Exception as e:
print('Error with application {0} - {1}'.format(app, e))
config = {
'schema': 'avalon-core:config-1.0',
'tasks': [{'name': ''}],
'apps': apps,
# TODO redo work!!!
'template': {
'workfile': '{asset[name]}_{task[name]}_{version:0>3}<_{comment}>',
'work': '{root}/{project}/{hierarchy}/{asset}/work/{task}',
'publish':'{root}/{project}/{hierarchy}/{asset}/publish/{family}/{subset}/v{version}/{projectcode}_{asset}_{subset}_v{version}.{representation}'}
}
return config
def setAvalonAttributes(self):
self.custom_attributes = []
all_avalon_attr = self.session.query('CustomAttributeGroup where name is "avalon"').one()
@ -215,6 +198,22 @@ class Sync_to_Avalon(BaseEvent):
if 'avalon_' not in cust_attr['key']:
self.custom_attributes.append(cust_attr)
def _translate_event(self, session, event):
exceptions = ['assetversion', 'job', 'user', 'reviewsessionobject', 'timer', 'socialfeed', 'timelog']
_selection = event['data'].get('entities',[])
_entities = list()
for entity in _selection:
if entity['entityType'] in exceptions:
continue
_entities.append(
(
session.get(self._get_entity_type(entity), entity.get('entityId'))
)
)
return [_entities, event]
def register(session, **kw):
'''Register plugin. Called when used as an plugin.'''

View file

@ -59,7 +59,6 @@ class BaseEvent(object):
_entities.append(
(
session.get(self._get_entity_type(entity), entity.get('entityId'))
# self._get_entity_type(entity), entity.get('entityId')
)
)

View file

@ -1,26 +1,26 @@
# import ftrack_api as local session
import os
import sys
import ftrack_api
#
session = ftrack_api.Session()
# ----------------------------------
from ftrack_event_handler import BaseEvent
def test_event(event):
'''just a testing event'''
class Test_Event(BaseEvent):
# start of event procedure ----------------------------------
for entity in event['data'].get('entities', []):
if entity['entityType'] == 'task' and entity['action'] == 'update':
def launch(self, session, entities, event):
'''just a testing event'''
exceptions = ['assetversion', 'job', 'user', 'reviewsessionobject', 'timer', 'socialfeed', 'timelog']
selection = event['data'].get('entities',[])
for entity in selection:
if entity['entityType'] in exceptions:
print(100*"*")
print(entity)
print("\n\nevent script: {}".format(__file__))
# for k in task.keys():
# print k, task[k]
# print '\n'
# print task['assignments']
def register(session, **kw):
'''Register plugin. Called when used as an plugin.'''
for e in entity.keys():
print('{0}: {1}'.format(e, entity[e]))
if not isinstance(session, ftrack_api.session.Session):
return
# end of event procedure ----------------------------------
event = Test_Event(session)
event.register()

View file

@ -2,13 +2,36 @@
import ftrack_api
import os
import traceback
from pprint import *
from pype import lib
def get_apps(entity):
""" Get apps from project
Requirements:
'Entity' MUST be object of ftrack entity with entity_type 'Project'
Checking if app from ftrack is available in Templates/bin/{app_name}.toml
def checkLogin():
# check Environments FTRACK_API_USER, FTRACK_API_KEY
pass
Returns:
Array with dictionaries with app Name and Label
"""
apps = []
for app in entity['custom_attributes']['applications']:
try:
label = toml.load(lib.which_app(app))['label']
apps.append({'name':app, 'label':label})
except Exception as e:
print('Error with application {0} - {1}'.format(app, e))
return apps
def get_config(self, entity):
config = {}
config['schema'] = lib.get_avalon_project_config_schema()
config['tasks'] = [{'name': ''}]
config['apps'] = get_apps(entity)
config['template'] = lib.get_avalon_project_template()
return config
def checkRegex():
# _handle_result -> would be solution?

View file

@ -335,3 +335,29 @@ def get_asset_data(asset=None):
data = document.get("data", {})
return data
def get_avalon_project_config_schema():
schema = 'avalon-core:config-1.0'
return schema
def get_avalon_project_template_schema():
schema = {"schema": "avalon-core:inventory-1.0"}
return schema
def get_avalon_project_template():
from app.api import Templates
"""Get avalon template
Returns:
dictionary with templates
"""
template = Templates(type=["anatomy"])
proj_template = {}
# proj_template['workfile'] = '{asset[name]}_{task[name]}_{version:0>3}<_{comment}>'
# proj_template['work'] = '{root}/{project}/{hierarchy}/{asset}/work/{task}'
# proj_template['publish'] = '{root}/{project}/{hierarchy}/{asset}/publish/{family}/{subset}/v{version}/{projectcode}_{asset}_{subset}_v{version}.{representation}'
proj_template['workfile'] = template.anatomy.avalon.workfile
proj_template['work'] = template.anatomy.avalon.work
proj_template['publish'] = template.anatomy.avalon.publish
return proj_template

View file

@ -1,98 +0,0 @@
from .lib import *
def load_capture_preset(path):
import capture_gui
import capture
path = path
preset = capture_gui.lib.load_json(path)
print preset
options = dict()
# CODEC
id = 'Codec'
for key in preset[id]:
options[str(key)] = preset[id][key]
# GENERIC
id = 'Generic'
for key in preset[id]:
if key.startswith('isolate'):
pass
# options['isolate'] = preset[id][key]
else:
options[str(key)] = preset[id][key]
# RESOLUTION
id = 'Resolution'
options['height'] = preset[id]['height']
options['width'] = preset[id]['width']
# DISPLAY OPTIONS
id = 'Display Options'
disp_options = {}
for key in preset['Display Options']:
if key.startswith('background'):
disp_options[key] = preset['Display Options'][key]
else:
disp_options['displayGradient'] = True
options['display_options'] = disp_options
# VIEWPORT OPTIONS
temp_options = {}
id = 'Renderer'
for key in preset[id]:
temp_options[str(key)] = preset[id][key]
temp_options2 = {}
id = 'Viewport Options'
light_options = {0: "default",
1: 'all',
2: 'selected',
3: 'flat',
4: 'nolights'}
for key in preset[id]:
if key == 'high_quality':
temp_options2['multiSampleEnable'] = True
temp_options2['multiSampleCount'] = 4
temp_options2['textureMaxResolution'] = 512
temp_options2['enableTextureMaxRes'] = True
if key == 'alphaCut':
temp_options2['transparencyAlgorithm'] = 5
temp_options2['transparencyQuality'] = 1
if key == 'headsUpDisplay':
temp_options['headsUpDisplay'] = True
if key == 'displayLights':
temp_options[str(key)] = light_options[preset[id][key]]
else:
temp_options[str(key)] = preset[id][key]
for key in ['override_viewport_options', 'high_quality', 'alphaCut']:
temp_options.pop(key, None)
options['viewport_options'] = temp_options
options['viewport2_options'] = temp_options2
# use active sound track
scene = capture.parse_active_scene()
options['sound'] = scene['sound']
cam_options = dict()
cam_options['overscan'] = 1.0
cam_options['displayFieldChart'] = False
cam_options['displayFilmGate'] = False
cam_options['displayFilmOrigin'] = False
cam_options['displayFilmPivot'] = False
cam_options['displayGateMask'] = False
cam_options['displayResolution'] = False
cam_options['displaySafeAction'] = False
cam_options['displaySafeTitle'] = False
# options['display_options'] = temp_options
return options

View file

@ -105,3 +105,99 @@ def filter_instances(context, plugin):
instances = pyblish.api.instances_by_plugin(allInstances, plugin)
return instances
def load_capture_preset(path):
import capture_gui
import capture
path = path
preset = capture_gui.lib.load_json(path)
print preset
options = dict()
# CODEC
id = 'Codec'
for key in preset[id]:
options[str(key)] = preset[id][key]
# GENERIC
id = 'Generic'
for key in preset[id]:
if key.startswith('isolate'):
pass
# options['isolate'] = preset[id][key]
else:
options[str(key)] = preset[id][key]
# RESOLUTION
id = 'Resolution'
options['height'] = preset[id]['height']
options['width'] = preset[id]['width']
# DISPLAY OPTIONS
id = 'Display Options'
disp_options = {}
for key in preset['Display Options']:
if key.startswith('background'):
disp_options[key] = preset['Display Options'][key]
else:
disp_options['displayGradient'] = True
options['display_options'] = disp_options
# VIEWPORT OPTIONS
temp_options = {}
id = 'Renderer'
for key in preset[id]:
temp_options[str(key)] = preset[id][key]
temp_options2 = {}
id = 'Viewport Options'
light_options = {0: "default",
1: 'all',
2: 'selected',
3: 'flat',
4: 'nolights'}
for key in preset[id]:
if key == 'high_quality':
temp_options2['multiSampleEnable'] = True
temp_options2['multiSampleCount'] = 4
temp_options2['textureMaxResolution'] = 512
temp_options2['enableTextureMaxRes'] = True
if key == 'alphaCut':
temp_options2['transparencyAlgorithm'] = 5
temp_options2['transparencyQuality'] = 1
if key == 'headsUpDisplay':
temp_options['headsUpDisplay'] = True
if key == 'displayLights':
temp_options[str(key)] = light_options[preset[id][key]]
else:
temp_options[str(key)] = preset[id][key]
for key in ['override_viewport_options', 'high_quality', 'alphaCut']:
temp_options.pop(key, None)
options['viewport_options'] = temp_options
options['viewport2_options'] = temp_options2
# use active sound track
scene = capture.parse_active_scene()
options['sound'] = scene['sound']
cam_options = dict()
cam_options['overscan'] = 1.0
cam_options['displayFieldChart'] = False
cam_options['displayFilmGate'] = False
cam_options['displayFilmOrigin'] = False
cam_options['displayFilmPivot'] = False
cam_options['displayGateMask'] = False
cam_options['displayResolution'] = False
cam_options['displaySafeAction'] = False
cam_options['displaySafeTitle'] = False
# options['display_options'] = temp_options
return options