Merge branch 'develop' of bitbucket.org:pypeclub/pype into develop

This commit is contained in:
Jakub Jezek 2019-08-06 12:09:51 +02:00
commit b8f3aa0561
10 changed files with 154 additions and 40 deletions

View file

@ -4,7 +4,7 @@ import time
from pype.ftrack import AppAction
from avalon import lib
from pypeapp import Logger
from pype import lib as pypelib
from pype.lib import get_all_avalon_projects
log = Logger().get_logger(__name__)
@ -15,10 +15,7 @@ def registerApp(app, session):
try:
variant = app['name'].split("_")[1]
except Exception:
log.warning((
'"{0}" - App "name" and "variant" is not separated by "_"'
' (variant is not set)'
).format(app['name']))
pass
abspath = lib.which_app(app['name'])
if abspath is None:
@ -47,18 +44,28 @@ def registerApp(app, session):
icon, description, preactions
).register()
if not variant:
log.info('- Variant is not set')
def register(session):
projects = pypelib.get_all_avalon_projects()
# WARNING getting projects only helps to check connection to mongo
# - without will `discover` of ftrack apps actions take ages
result = get_all_avalon_projects()
apps = []
appNames = []
# Get all application from all projects
for project in projects:
for app in project['config']['apps']:
if app['name'] not in appNames:
appNames.append(app['name'])
apps.append(app)
launchers_path = os.path.join(os.environ["PYPE_CONFIG"], "launchers")
for file in os.listdir(launchers_path):
filename, ext = os.path.splitext(file)
if ext.lower() != ".toml":
continue
loaded_data = toml.load(os.path.join(launchers_path, file))
app_data = {
"name": filename,
"label": loaded_data.get("label", filename)
}
apps.append(app_data)
apps = sorted(apps, key=lambda x: x['name'])
app_counter = 0
@ -68,5 +75,8 @@ def register(session):
if app_counter%5 == 0:
time.sleep(0.1)
app_counter += 1
except Exception as e:
log.exception("'{0}' - not proper App ({1})".format(app['name'], e))
except Exception as exc:
log.exception(
"\"{}\" - not a proper App ({})".format(app['name'], str(exc)),
exc_info=True
)

View file

@ -116,13 +116,13 @@ def import_to_avalon(
# not override existing templates!
templates = av_project['config'].get('template', None)
if templates is not None:
for key, value in config['template'].items():
for key, value in proj_config['template'].items():
if (
key in templates and
templates[key] is not None and
templates[key] != value
):
config['template'][key] = templates[key]
proj_config['template'][key] = templates[key]
projectId = av_project['_id']
@ -142,7 +142,7 @@ def import_to_avalon(
{'_id': ObjectId(projectId)},
{'$set': {
'name': project_name,
'config': config,
'config': proj_config,
'data': data
}}
)

View file

@ -221,10 +221,15 @@ class AppAction(BaseHandler):
anatomy = anatomy.format(data)
work_template = anatomy["work"]["folder"]
except Exception as e:
self.log.exception(
"{0} Error in anatomy.format: {1}".format(__name__, e)
except Exception as exc:
msg = "{} Error in anatomy.format: {}".format(
__name__, str(exc)
)
self.log.error(msg, exc_info=True)
return {
'success': False,
'message': msg
}
workdir = os.path.normpath(work_template)
os.environ["AVALON_WORKDIR"] = workdir

View file

@ -75,7 +75,7 @@ class BaseHandler(object):
self.type, label)
)
except Exception as e:
self.log.exception('{} "{}" - Registration failed ({})'.format(
self.log.error('{} "{}" - Registration failed ({})'.format(
self.type, label, str(e))
)
return wrapper_register
@ -84,25 +84,26 @@ class BaseHandler(object):
def launch_log(self, func):
@functools.wraps(func)
def wrapper_launch(*args, **kwargs):
label = self.__class__.__name__
if hasattr(self, 'label'):
if self.variant is None:
label = self.label
else:
if hasattr(self, 'variant'):
label = '{} {}'.format(self.label, self.variant)
else:
label = self.label
else:
label = self.__class__.__name__
self.log.info(('{} "{}": Launched').format(self.type, label))
try:
self.log.info(('{} "{}": Launched').format(self.type, label))
result = func(*args, **kwargs)
self.log.info(('{} "{}": Finished').format(self.type, label))
return result
except Exception as e:
msg = '{} "{}": Failed ({})'.format(self.type, label, str(e))
self.log.exception(msg)
return func(*args, **kwargs)
except Exception as exc:
msg = '{} "{}": Failed ({})'.format(self.type, label, str(exc))
self.log.error(msg, exc_info=True)
return {
'success': False,
'message': msg
}
finally:
self.log.info(('{} "{}": Finished').format(self.type, label))
return wrapper_launch
@property
@ -230,7 +231,7 @@ class BaseHandler(object):
# Get entity type and make sure it is lower cased. Most places except
# the component tab in the Sidebar will use lower case notation.
entity_type = entity.get('entityType').replace('_', '').lower()
if session is None:
session = self.session

View file

@ -45,13 +45,21 @@ def get_hierarchy(asset_name=None):
if not asset_name:
asset_name = io.Session.get("AVALON_ASSET", os.environ["AVALON_ASSET"])
asset = io.find_one({
asset_entity = io.find_one({
"type": 'asset',
"name": asset_name
})
not_set = "PARENTS_NOT_SET"
entity_parents = entity.get("data", {}).get("parents", not_set)
# If entity already have parents then just return joined
if entity_parents != not_set:
return "/".join(entity_parents)
# Else query parents through visualParents and store result to entity
hierarchy_items = []
entity = asset
entity = asset_entity
while True:
parent_id = entity.get("data", {}).get("visualParent")
if not parent_id:
@ -59,6 +67,14 @@ def get_hierarchy(asset_name=None):
entity = io.find_one({"_id": parent_id})
hierarchy_items.append(entity["name"])
# Add parents to entity data for next query
entity_data = asset_entity.get("data", {})
entity_data["parents"] = hierarchy_items
io.update_many(
{"_id": asset_entity["_id"]},
{"$set": {"data": entity_data}}
)
return "/".join(hierarchy_items)

View file

@ -4,7 +4,17 @@ from avalon.tools import workfiles
from avalon import api as avalon
from pyblish import api as pyblish
from .workio import (
open,
save,
current_file,
has_unsaved_changes,
file_extensions,
work_root
)
from .. import api
from .menu import (
install as menu_install,
_update_menu_task_label
@ -17,6 +27,17 @@ import hiero
log = Logger().get_logger(__name__, "nukestudio")
__all__ = [
# Workfiles API
"open",
"save",
"current_file",
"has_unsaved_changes",
"file_extensions",
"work_root",
]
AVALON_CONFIG = os.getenv("AVALON_CONFIG", "pype")
PARENT_DIR = os.path.dirname(__file__)

61
pype/nukestudio/workio.py Normal file
View file

@ -0,0 +1,61 @@
"""Host API required Work Files tool"""
import os
import hiero
def file_extensions():
return [".hrox"]
def has_unsaved_changes():
return hiero.core.projects()[-1]
def save(filepath):
project = hiero.core.projects()[-1]
if project:
project.saveAs(filepath)
else:
project = hiero.core.newProject()
project.saveAs(filepath)
def open(filepath):
try:
hiero.core.openProject(filepath)
return True
except Exception as e:
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
prompt = "Cannot open the selected file: `{}`".format(e)
hiero.core.log.error(prompt)
dialog = QMessageBox.critical(
hiero.ui.mainWindow(), "Error", unicode(prompt))
def current_file():
import os
import hiero
current_file = hiero.core.projects()[-1].path()
normalised = os.path.normpath(current_file)
# Unsaved current file
if normalised is '':
return "NOT SAVED"
return normalised
def work_root():
from avalon import api
return os.path.normpath(api.Session["AVALON_WORKDIR"]).replace("\\", "/")

View file

@ -66,7 +66,7 @@ class ValidateAttributes(pyblish.api.ContextPlugin):
)
# Get invalid attributes.
nodes = [pm.PyNode(x) for x in instance]
nodes = pm.ls()
for node in nodes:
name = node.name(stripNamespace=True)
if name not in attributes.keys():

View file

@ -7,7 +7,7 @@ class RemoveOutputNode(pyblish.api.ContextPlugin):
"""
label = 'Output Node Remove'
order = pyblish.api.IntegratorOrder
order = pyblish.api.IntegratorOrder + 0.4
families = ["workfile"]
hosts = ['nuke']

View file

@ -11,7 +11,7 @@ class RepairCollectionAction(pyblish.api.Action):
icon = "wrench"
def process(self, context, plugin):
self.log.info(context[0][1])
self.log.info(context[0][0])
files_remove = [os.path.join(context[0].data["outputDir"], f)
for r in context[0].data.get("representations", [])
for f in r.get("files", [])
@ -20,7 +20,7 @@ class RepairCollectionAction(pyblish.api.Action):
for f in files_remove:
os.remove(f)
self.log.debug("removing file: {}".format(f))
context[0][1]["render"].setValue(True)
context[0][0]["render"].setValue(True)
self.log.info("Rendering toggled ON")