mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-26 05:42:15 +01:00
Merge branch 'develop' of bitbucket.org:pypeclub/pype into develop
This commit is contained in:
commit
b8f3aa0561
10 changed files with 154 additions and 40 deletions
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
20
pype/lib.py
20
pype/lib.py
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
61
pype/nukestudio/workio.py
Normal 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("\\", "/")
|
||||
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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']
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue