Merged in feautre/PYPE-139_tray_crash_on_sync (pull request #50)

Feautre/PYPE-139 tray crash on sync

Approved-by: Milan Kolar <milan@orbi.tools>
This commit is contained in:
Jakub Trllo 2019-01-17 16:16:21 +00:00 committed by Milan Kolar
commit bb5eceff95
11 changed files with 254 additions and 168 deletions

View file

@ -1,8 +1,9 @@
import os
import toml
import time
from ftrack_action_handler import AppAction
from avalon import io, lib
from avalon import lib
from app.api import Logger
from pype import lib as pypelib
log = Logger.getLogger(__name__)
@ -28,8 +29,11 @@ def registerApp(app, session):
apptoml = toml.load(abspath)
''' REQUIRED '''
executable = apptoml['executable']
label = apptoml.get('ftrack_label', app['label'])
''' OPTIONAL '''
label = apptoml.get('ftrack_label', app.get('label', name))
icon = apptoml.get('ftrack_icon', None)
description = apptoml.get('description', None)
@ -40,17 +44,7 @@ def registerApp(app, session):
def register(session):
# set avalon environ - they just must exist
os.environ['AVALON_PROJECT'] = ''
os.environ['AVALON_ASSET'] = ''
os.environ['AVALON_SILO'] = ''
# Get all projects from Avalon DB
try:
io.install()
projects = sorted(io.projects(), key=lambda x: x['name'])
io.uninstall()
except Exception as e:
log.error(e)
projects = pypelib.get_all_avalon_projects()
apps = []
appNames = []
@ -65,5 +59,6 @@ def register(session):
for app in apps:
try:
registerApp(app, session)
time.sleep(0.05)
except Exception as e:
log.warning("'{0}' - not proper App ({1})".format(app['name'], e))

View file

@ -6,7 +6,6 @@ import json
import importlib
import ftrack_api
from avalon import io
from ftrack_action_handler import BaseAction
from pype.ftrack import ftrack_utils
@ -134,17 +133,9 @@ class SyncToAvalon(BaseAction):
# ----- PROJECT ------
# store Ftrack project- self.importable[0] must be project entity!!
ft_project = self.importable[0]
# set AVALON_ env
os.environ["AVALON_PROJECT"] = ft_project["full_name"]
os.environ["AVALON_ASSET"] = ft_project["full_name"]
os.environ["AVALON_SILO"] = ""
avalon_project = ftrack_utils.get_avalon_proj(ft_project)
avalon_project = ftrack_utils.get_avalon_project(ft_project)
custom_attributes = ftrack_utils.get_avalon_attr(session)
io.install()
# Import all entities to Avalon DB
for entity in self.importable:
result = ftrack_utils.import_to_avalon(
@ -156,7 +147,6 @@ class SyncToAvalon(BaseAction):
)
if 'errors' in result and len(result['errors']) > 0:
print('error')
items = []
for error in result['errors']:
for key, message in error.items():
@ -171,11 +161,12 @@ class SyncToAvalon(BaseAction):
self.log.error(
'{}: {}'.format(key, message)
)
io.uninstall()
title = 'Hey You! Few Errors were raised! (*look below*)'
job['status'] = 'failed'
session.commit()
self.show_interface(event, items)
self.show_interface(event, items, title)
return {
'success': False,
'message': "Sync to avalon FAILED"
@ -211,8 +202,6 @@ class SyncToAvalon(BaseAction):
' - Please check Log for more information'
)
io.uninstall()
if len(message) > 0:
message = "Unable to sync: {}".format(message)
return {

View file

@ -6,6 +6,8 @@ import sys
import json
import base64
ignore_me = True
# sys.path.append(os.path.dirname(os.path.dirname(__file__)))
# from ftrack_kredenc.lucidity.vendor import yaml
# from ftrack_kredenc import lucidity

View file

@ -4,13 +4,17 @@ import os
import sys
import platform
import ftrack_api
from avalon import io, lib
from avalon import lib
import acre
from pype.ftrack import ftrack_utils
from pype.ftrack import ftrack_utils
from pype import api as pype
ignore_me = True
class AppAction(object):
'''Custom Action base class
@ -123,33 +127,20 @@ class AppAction(object):
entity = session.get(entity_type, entity_id)
# TODO Should return False if not TASK ?!!!
if entity.entity_type != 'Task':
return False
# TODO Should return False if more than one entity is selected ?!!!
if len(entities) > 1:
if (
len(entities) > 1 or
entity.entity_type.lower() != 'task'
):
return False
ft_project = entity
if (entity.entity_type != 'Project'):
ft_project = entity['project']
ft_project = entity['project']
silo = ""
if 'ancestors' in entity:
for ancestor in entity['ancestors']:
silo = ancestor['name']
break
os.environ['AVALON_PROJECT'] = ft_project['full_name']
os.environ['AVALON_ASSET'] = entity['name']
os.environ['AVALON_SILO'] = silo
io.install()
avalon_project = io.find_one({
"type": "project",
"name": ft_project['full_name']
database = ftrack_utils.get_avalon_database()
project_name = ft_project['full_name']
avalon_project = database[project_name].find_one({
"type": "project"
})
io.uninstall()
if avalon_project is None:
return False
@ -250,24 +241,37 @@ class AppAction(object):
entity, id = entities[0]
entity = session.get(entity, id)
project_name = entity['project']['full_name']
database = ftrack_utils.get_avalon_database()
# Get current environments
env_list = [
'AVALON_PROJECT',
'AVALON_SILO',
'AVALON_ASSET',
'AVALON_TASK',
'AVALON_APP',
'AVALON_APP_NAME'
]
env_origin = {}
for env in env_list:
env_origin[env] = os.environ.get(env, None)
# set environments for Avalon
os.environ["AVALON_PROJECT"] = entity['project']['full_name']
os.environ["AVALON_PROJECT"] = project_name
os.environ["AVALON_SILO"] = entity['ancestors'][0]['name']
os.environ["AVALON_ASSET"] = entity['parent']['name']
os.environ["AVALON_TASK"] = entity['name']
os.environ["AVALON_APP"] = self.identifier.split("_")[0]
os.environ["AVALON_APP_NAME"] = self.identifier
os.environ["FTRACK_TASKID"] = id
anatomy = pype.Anatomy
io.install()
hierarchy = io.find_one({
hierarchy = database[project_name].find_one({
"type": 'asset',
"name": entity['parent']['name']
})['data']['parents']
io.uninstall()
if hierarchy:
hierarchy = os.path.join(*hierarchy)
@ -406,6 +410,10 @@ class AppAction(object):
msg = "Status '{}' in config wasn't found on Ftrack".format(status_name)
self.log.warning(msg)
# Set origin avalon environments
for key, value in env_origin.items():
os.environ[key] = value
return {
'success': True,
'message': "Launching {0}".format(self.label)
@ -751,7 +759,7 @@ class BaseAction(object):
return result
def show_interface(self, event, items):
def show_interface(self, event, items, title=''):
"""
Shows interface to user who triggered event
- 'items' must be list containing Ftrack interface items
@ -766,7 +774,8 @@ class BaseAction(object):
topic='ftrack.action.trigger-user-interface',
data=dict(
type='widget',
items=items
items=items,
title=title
),
target=target
),

View file

@ -1,16 +1,11 @@
import os
import sys
import argparse
import logging
import os
import ftrack_api
import json
import re
from pype import lib
from pype.ftrack.actions.ftrack_action_handler import BaseAction
from bson.objectid import ObjectId
from avalon import io, inventory
from pype.ftrack import ftrack_utils
from pype.ftrack.actions.ftrack_action_handler import BaseAction
class Sync_To_Avalon(BaseAction):
@ -149,17 +144,9 @@ class Sync_To_Avalon(BaseAction):
# ----- PROJECT ------
# store Ftrack project- self.importable[0] must be project entity!!
ft_project = self.importable[0]
# set AVALON_ env
os.environ["AVALON_PROJECT"] = ft_project["full_name"]
os.environ["AVALON_ASSET"] = ft_project["full_name"]
os.environ["AVALON_SILO"] = ""
avalon_project = ftrack_utils.get_avalon_proj(ft_project)
avalon_project = ftrack_utils.get_avalon_project(ft_project)
custom_attributes = ftrack_utils.get_avalon_attr(session)
io.install()
# Import all entities to Avalon DB
for entity in self.importable:
result = ftrack_utils.import_to_avalon(
@ -171,7 +158,6 @@ class Sync_To_Avalon(BaseAction):
)
if 'errors' in result and len(result['errors']) > 0:
print('error')
items = []
for error in result['errors']:
for key, message in error.items():
@ -186,11 +172,12 @@ class Sync_To_Avalon(BaseAction):
self.log.error(
'{}: {}'.format(key, message)
)
io.uninstall()
title = 'Hey You! Few Errors were raised! (*look below*)'
job['status'] = 'failed'
session.commit()
self.show_interface(event, items)
self.show_interface(event, items, title)
return {
'success': False,
'message': "Sync to avalon FAILED"
@ -226,8 +213,6 @@ class Sync_To_Avalon(BaseAction):
' - Please check Log for more information'
)
io.uninstall()
if len(message) > 0:
message = "Unable to sync: {}".format(message)
return {

View file

@ -1,8 +1,7 @@
import os
import ftrack_api
from ftrack_event_handler import BaseEvent
from avalon import io
from pype.ftrack import ftrack_utils
from ftrack_event_handler import BaseEvent
class Sync_to_Avalon(BaseEvent):
@ -45,14 +44,12 @@ class Sync_to_Avalon(BaseEvent):
self.show_message(event, message, False)
return
os.environ["AVALON_PROJECT"] = ft_project['full_name']
os.environ["AVALON_ASSET"] = ft_project["full_name"]
os.environ["AVALON_SILO"] = ""
# get avalon project if possible
import_entities = []
avalon_project = ftrack_utils.get_avalon_proj(ft_project)
custom_attributes = ftrack_utils.get_avalon_attr(session)
avalon_project = ftrack_utils.get_avalon_project(ft_project)
if avalon_project is None:
import_entities.append(ft_project)
@ -79,11 +76,6 @@ class Sync_to_Avalon(BaseEvent):
if len(import_entities) < 1:
return
avalon_project = ftrack_utils.get_avalon_proj(ft_project)
custom_attributes = ftrack_utils.get_avalon_attr(session)
io.install()
try:
for entity in import_entities:
result = ftrack_utils.import_to_avalon(
@ -94,7 +86,6 @@ class Sync_to_Avalon(BaseEvent):
custom_attributes=custom_attributes
)
if 'errors' in result and len(result['errors']) > 0:
print('error')
items = []
for error in result['errors']:
for key, message in error.items():
@ -109,10 +100,9 @@ class Sync_to_Avalon(BaseEvent):
self.log.error(
'{}: {}'.format(key, message)
)
io.uninstall()
session.commit()
self.show_interface(event, items)
title = 'Hey You! You raised few Errors! (*look below*)'
self.show_interface(event, items, title)
return
if avalon_project is None:
@ -131,11 +121,10 @@ class Sync_to_Avalon(BaseEvent):
'name': 'error',
'value': ftrack_message
}]
self.show_interface(event, items)
title = 'Hey You! Unknown Error has been raised! (*look below*)'
self.show_interface(event, items, title)
self.log.error(message)
io.uninstall()
return
def _launch(self, event):

View file

@ -140,7 +140,7 @@ class BaseEvent(object):
on_error='ignore'
)
def show_interface(self, event, items):
def show_interface(self, event, items, title=''):
"""
Shows interface to user who triggered event
- 'items' must be list containing Ftrack interface items
@ -153,7 +153,8 @@ class BaseEvent(object):
topic='ftrack.action.trigger-user-interface',
data=dict(
type='widget',
items=items
items=items,
title=title
),
target=target
),

View file

@ -1,4 +1,3 @@
import sys
import os
import json
import threading
@ -6,6 +5,7 @@ import time
import ftrack_api
from app import style
from app.vendor.Qt import QtCore, QtGui, QtWidgets
from pype.ftrack import credentials, login_dialog as login_dialog
from pype.vendor.pynput import mouse, keyboard
@ -21,7 +21,6 @@ log = pype.Logger.getLogger(__name__, "ftrack")
class FtrackRunner:
def __init__(self, main_parent=None, parent=None):
self.parent = parent
@ -86,7 +85,9 @@ class FtrackRunner:
# Actions part
def start_action_server(self):
if self.thread_action_server is None:
self.thread_action_server = threading.Thread(target=self.set_action_server)
self.thread_action_server = threading.Thread(
target=self.set_action_server
)
self.thread_action_server.daemon = True
self.thread_action_server.start()
@ -95,7 +96,14 @@ class FtrackRunner:
self.set_menu_visibility()
def set_action_server(self):
self.action_server.run_server()
try:
self.action_server.run_server()
except Exception:
msg = 'Ftrack Action server crashed! Please try to start again.'
log.error(msg)
# TODO show message to user
self.bool_action_server = False
self.set_menu_visibility()
def reset_action_server(self):
self.stop_action_server()
@ -123,11 +131,19 @@ class FtrackRunner:
# Actions - server
self.smActionS = self.menu.addMenu("Action server")
self.aRunActionS = QtWidgets.QAction("Run action server", self.smActionS)
self.aRunActionS = QtWidgets.QAction(
"Run action server", self.smActionS
)
self.aResetActionS = QtWidgets.QAction(
"Reset action server", self.smActionS
)
self.aStopActionS = QtWidgets.QAction(
"Stop action server", self.smActionS
)
self.aRunActionS.triggered.connect(self.start_action_server)
self.aResetActionS = QtWidgets.QAction("Reset action server", self.smActionS)
self.aResetActionS.triggered.connect(self.reset_action_server)
self.aStopActionS = QtWidgets.QAction("Stop action server", self.smActionS)
self.aStopActionS.triggered.connect(self.stop_action_server)
self.smActionS.addAction(self.aRunActionS)
@ -168,12 +184,19 @@ class FtrackRunner:
self.start_timer_thread()
def start_timer_thread(self):
if self.thread_timer is None:
self.thread_timer = FtrackEventsThread(self)
self.bool_timer_event = True
self.thread_timer.signal_timer_started.connect(self.timer_started)
self.thread_timer.signal_timer_stopped.connect(self.timer_stopped)
self.thread_timer.start()
try:
if self.thread_timer is None:
self.thread_timer = FtrackEventsThread(self)
self.bool_timer_event = True
self.thread_timer.signal_timer_started.connect(
self.timer_started
)
self.thread_timer.signal_timer_stopped.connect(
self.timer_stopped
)
self.thread_timer.start()
except Exception:
pass
def stop_timer_thread(self):
try:
@ -188,9 +211,15 @@ class FtrackRunner:
def start_countdown_thread(self):
if self.thread_timer_coundown is None:
self.thread_timer_coundown = CountdownThread(self)
self.thread_timer_coundown.signal_show_question.connect(self.show_widget_timer)
self.thread_timer_coundown.signal_send_time.connect(self.change_count_widget)
self.thread_timer_coundown.signal_stop_timer.connect(self.timer_stop)
self.thread_timer_coundown.signal_show_question.connect(
self.show_widget_timer
)
self.thread_timer_coundown.signal_send_time.connect(
self.change_count_widget
)
self.thread_timer_coundown.signal_stop_timer.connect(
self.timer_stop
)
self.thread_timer_coundown.start()
def stop_countdown_thread(self):
@ -255,7 +284,9 @@ class FtrackEventsThread(QtCore.QThread):
def run(self):
self.timer_session = ftrack_api.Session(auto_connect_event_hub=True)
self.timer_session.event_hub.subscribe(
'topic=ftrack.update and source.user.username={}'.format(self.username),
'topic=ftrack.update and source.user.username={}'.format(
self.username
),
self.event_handler)
user_query = 'User where username is "{}"'.format(self.username)
@ -273,7 +304,7 @@ class FtrackEventsThread(QtCore.QThread):
try:
if event['data']['entities'][0]['objectTypeId'] != 'timer':
return
except:
except Exception:
return
new = event['data']['entities'][0]['changes']['start']['new']
@ -301,12 +332,6 @@ class FtrackEventsThread(QtCore.QThread):
def ftrack_restart_timer(self):
try:
last_task = None
if "FTRACK_LAST_TASK_ID" in os.environ:
task_id = os.environ["FTRACK_LAST_TASK_ID"]
query = 'Task where id is {}'.format(task_id)
last_task = self.timer_session.query(query).one()
if (self.last_task is not None) and (self.user is not None):
self.user.start_timer(self.last_task)
self.timer_session.commit()
@ -386,7 +411,11 @@ class CountdownThread(QtCore.QThread):
json_dict = json.load(data_file)
data = json_dict['timer']
except Exception as e:
msg = 'Loading "Ftrack Config file" Failed. Please check log for more information. Times are set to default.'
msg = (
'Loading "Ftrack Config file" Failed.'
' Please check log for more information.'
' Times are set to default.'
)
log.warning("{} - {}".format(msg, str(e)))
data = self.validate_timer_values(data)
@ -485,15 +514,17 @@ class StopTimer(QtWidgets.QWidget):
def _main(self):
self.main = QtWidgets.QVBoxLayout()
self.main.setObjectName("main")
self.main.setObjectName('main')
self.form = QtWidgets.QFormLayout()
self.form.setContentsMargins(10, 15, 10, 5)
self.form.setObjectName("form")
self.form.setObjectName('form')
msg_info = "You didn't work for a long time."
msg_question = "Would you like to stop Ftrack timer?"
msg_stopped = "Your Ftrack timer was stopped. Do you want to start again?"
msg_info = 'You didn\'t work for a long time.'
msg_question = 'Would you like to stop Ftrack timer?'
msg_stopped = (
'Your Ftrack timer was stopped. Do you want to start again?'
)
self.lbl_info = QtWidgets.QLabel(msg_info)
self.lbl_info.setFont(self.font)

View file

@ -1,7 +1,8 @@
import os
import re
from pype import lib
from avalon import io, inventory
from pype.lib import get_avalon_database
from avalon import schema
from bson.objectid import ObjectId
from pype.ftrack.ftrack_utils import ftrack_utils
from avalon.vendor import jsonschema
@ -19,6 +20,8 @@ def get_ca_mongoid():
def import_to_avalon(
session, entity, ft_project, av_project, custom_attributes
):
database = get_avalon_database()
project_name = ft_project['full_name']
output = {}
errors = []
@ -46,9 +49,9 @@ def import_to_avalon(
# Project ////////////////////////////////////////////////////////////////
if entity_type in ['Project']:
type = 'project'
name = entity['full_name']
config = ftrack_utils.get_config(entity)
template = lib.get_avalon_project_template_schema()
schema.validate(config)
av_project_code = None
if av_project is not None and 'code' in av_project['data']:
@ -56,23 +59,46 @@ def import_to_avalon(
ft_project_code = ft_project['name']
if av_project is None:
inventory.save(name, config, template)
av_project = io.find_one({'type': type, 'name': name})
project_schema = lib.get_avalon_project_template_schema()
item = {
'schema': project_schema,
'type': type,
'name': project_name,
'data': dict(),
'config': config,
'parent': None,
}
schema.validate(item)
elif av_project['name'] != name or av_project_code != ft_project_code:
database[project_name].insert_one(item)
av_project = database[project_name].find_one(
{'type': type}
)
elif (
av_project['name'] != project_name or
(
av_project_code is not None and
av_project_code != ft_project_code
)
):
msg = (
'You can\'t change {0} "{1}" to "{2}"'
', avalon wouldn\'t work properly!'
'\n{0} was changed back!'
)
if av_project['name'] != name:
if av_project['name'] != project_name:
entity['full_name'] = av_project['name']
errors.append(
{'Changed name error': msg.format(
'Project name', av_project['name'], name
'Project name', av_project['name'], project_name
)}
)
if av_project_code != ft_project_code:
if (
av_project_code is not None and
av_project_code != ft_project_code
):
entity['name'] = av_project_code
errors.append(
{'Changed name error': msg.format(
@ -91,10 +117,10 @@ def import_to_avalon(
entity, session, custom_attributes
)
io.update_many(
database[project_name].update_many(
{'_id': ObjectId(projectId)},
{'$set': {
'name': name,
'name': project_name,
'config': config,
'data': data,
}})
@ -137,9 +163,6 @@ def import_to_avalon(
name = entity['name']
os.environ['AVALON_SILO'] = silo
os.environ['AVALON_ASSET'] = name
avalon_asset = None
# existence of this custom attr is already checked
if ca_mongoid not in entity['custom_attributes']:
@ -153,14 +176,27 @@ def import_to_avalon(
mongo_id = entity['custom_attributes'][ca_mongoid]
if mongo_id is not '':
avalon_asset = io.find_one({'_id': ObjectId(mongo_id)})
avalon_asset = database[project_name].find_one(
{'_id': ObjectId(mongo_id)}
)
if avalon_asset is None:
avalon_asset = io.find_one({'type': 'asset', 'name': name})
avalon_asset = database[project_name].find_one(
{'type': 'asset', 'name': name}
)
if avalon_asset is None:
mongo_id = inventory.create_asset(
name, silo, data, ObjectId(projectId)
)
asset_schema = lib.get_avalon_asset_template_schema()
item = {
'schema': asset_schema,
'name': name,
'silo': silo,
'parent': ObjectId(projectId),
'type': 'asset',
'data': data
}
schema.validate(item)
mongo_id = database[project_name].insert_one(item).inserted_id
# Raise error if it seems to be different ent. with same name
elif (
avalon_asset['data']['parents'] != data['parents'] or
@ -172,6 +208,10 @@ def import_to_avalon(
errors.append({'Entity name duplication': msg})
output['errors'] = errors
return output
# Store new ID (in case that asset was removed from DB)
else:
mongo_id = avalon_asset['_id']
else:
if avalon_asset['name'] != entity['name']:
if silo is None or changeability_check_childs(entity) is False:
@ -205,7 +245,9 @@ def import_to_avalon(
else:
asset_parent_id = avalon_asset['data']['visualParent']
asset_parent = io.find_one({'_id': ObjectId(asset_parent_id)})
asset_parent = database[project_name].find_one(
{'_id': ObjectId(asset_parent_id)}
)
ft_parent_id = asset_parent['data']['ftrackId']
try:
entity['parent_id'] = ft_parent_id
@ -231,7 +273,7 @@ def import_to_avalon(
output['errors'] = errors
return output
io.update_many(
database[project_name].update_many(
{'_id': ObjectId(mongo_id)},
{'$set': {
'name': name,
@ -280,8 +322,18 @@ def changeability_check_childs(entity):
def get_data(entity, session, custom_attributes):
database = get_avalon_database()
entity_type = entity.entity_type
if entity_type.lower() == 'project':
ft_project = entity
elif entity_type.lower() != 'project':
ft_project = entity['project']
av_project = get_avalon_project(ft_project)
project_name = ft_project['full_name']
data = {}
data['ftrackId'] = entity['id']
data['entityType'] = entity_type
@ -335,10 +387,16 @@ def get_data(entity, session, custom_attributes):
parentId = None
for parent in parents:
parentId = io.find_one({'type': 'asset', 'name': parName})['_id']
parentId = database[project_name].find_one(
{'type': 'asset', 'name': parName}
)['_id']
if parent['parent'].entity_type != 'project' and parentId is None:
parent.importToAvalon(session, parent)
parentId = io.find_one({'type': 'asset', 'name': parName})['_id']
import_to_avalon(
session, parent, ft_project, av_project, custom_attributes
)
parentId = database[project_name].find_one(
{'type': 'asset', 'name': parName}
)['_id']
hierarchy = os.path.sep.join(folderStruct)
@ -350,27 +408,25 @@ def get_data(entity, session, custom_attributes):
return data
def get_avalon_proj(ft_project):
io.install()
def get_avalon_project(ft_project):
database = get_avalon_database()
project_name = ft_project['full_name']
ca_mongoid = get_ca_mongoid()
if ca_mongoid not in ft_project['custom_attributes']:
return None
# try to find by Id
project_id = ft_project['custom_attributes'][ca_mongoid]
try:
avalon_project = io.find_one({
"_id": ObjectId(project_id)
avalon_project = database[project_name].find_one({
'_id': ObjectId(project_id)
})
except Exception:
avalon_project = None
if avalon_project is None:
avalon_project = io.find_one({
"type": "project",
"name": ft_project["full_name"]
avalon_project = database[project_name].find_one({
'type': 'project'
})
io.uninstall()
return avalon_project

View file

@ -45,7 +45,7 @@ def avalon_check_name(entity, inSchema=None):
if entity.entity_type in ['Project']:
# data['type'] = 'project'
name = entity['full_name']
# schema = get_avalon_project_template_schema()['schema']
# schema = get_avalon_project_template_schema()
# elif entity.entity_type in ['AssetBuild','Library']:
# data['silo'] = 'Assets'
# else:

View file

@ -337,14 +337,17 @@ def get_asset_data(asset=None):
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"}
schema = "avalon-core:inventory-1.0"
return schema
def get_avalon_project_template():
from app.api import Templates
@ -364,3 +367,29 @@ def get_avalon_project_template():
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}"
return proj_template
def get_avalon_asset_template_schema():
schema = "avalon-core:asset-2.0"
return schema
def get_avalon_database():
if io._database is None:
project = os.environ.get('AVALON_PROJECT', '')
asset = os.environ.get('AVALON_ASSET', '')
silo = os.environ.get('AVALON_SILO', '')
os.environ['AVALON_PROJECT'] = project
os.environ['AVALON_ASSET'] = asset
os.environ['AVALON_SILO'] = silo
io.install()
return io._database
def get_all_avalon_projects():
db = get_avalon_database()
project_names = db.collection_names()
projects = []
for name in project_names:
projects.append(db[name].find_one({'type': 'project'}))
return projects