Merge branch 'develop' into feature/PYPE-654-nks-cut-reference-videos

This commit is contained in:
Jakub Jezek 2020-05-15 12:05:11 +02:00
commit 0c5b7b7ab9
No known key found for this signature in database
GPG key ID: C4B96E101D2A47F3
18 changed files with 112 additions and 177 deletions

View file

@ -3,7 +3,7 @@ import os
from pyblish import api as pyblish
from avalon import api as avalon
from .lib import filter_pyblish_plugins
from pypeapp import config, Roots
from pypeapp import config, Anatomy
import logging
@ -100,8 +100,9 @@ def install():
avalon.register_plugin_path(avalon.InventoryAction, path)
if project_name:
root_obj = Roots(project_name)
avalon.register_root(root_obj.roots)
anatomy = Anatomy(project_name)
anatomy.set_root_environments()
avalon.register_root(anatomy.roots)
# apply monkey patched discover to original one
avalon.discover = patched_discover

View file

@ -45,10 +45,9 @@ class AvalonApps:
def show_launcher(self):
# if app_launcher don't exist create it/otherwise only show main window
if self.app_launcher is None:
root = os.path.realpath(os.environ["AVALON_PROJECTS"])
io.install()
APP_PATH = launcher_lib.resource("qml", "main.qml")
self.app_launcher = launcher_widget.Launcher(root, APP_PATH)
self.app_launcher = launcher_widget.Launcher(APP_PATH)
self.app_launcher.window.show()
def show_library_loader(self):

View file

@ -42,36 +42,8 @@ class DeleteOldVersions(BaseAction):
return False
def interface(self, session, entities, event):
# TODO Add roots existence validation
items = []
root = os.environ.get("AVALON_PROJECTS")
if not root:
msg = "Root path to projects is not set."
items.append({
"type": "label",
"value": "<i><b>ERROR:</b> {}</i>".format(msg)
})
self.show_interface(
items=items, title=self.inteface_title, event=event
)
return {
"success": False,
"message": msg
}
if not os.path.exists(root):
msg = "Root path does not exists \"{}\".".format(str(root))
items.append({
"type": "label",
"value": "<i><b>ERROR:</b> {}</i>".format(msg)
})
self.show_interface(
items=items, title=self.inteface_title, event=event
)
return {
"success": False,
"message": msg
}
values = event["data"].get("values")
if values:
versions_count = int(values["last_versions_count"])

View file

@ -340,7 +340,7 @@ class Delivery(BaseAction):
repre_path = self.path_from_represenation(repre, anatomy)
# TODO add backup solution where root of path from component
# is repalced with AVALON_PROJECTS root
# is repalced with root
if not frame:
self.process_single_file(
repre_path, anatomy, anatomy_name, anatomy_data

View file

@ -177,9 +177,16 @@ def format_anatomy(data):
log.debug("__ anatomy.templates: {}".format(anatomy.templates))
try:
padding = int(anatomy.templates['render']['padding'])
# TODO: bck compatibility with old anatomy template
padding = int(
anatomy.templates["render"].get(
"frame_padding",
anatomy.templates["render"].get("padding")
)
)
except KeyError as e:
msg = ("`padding` key is not in `render` "
"or `frame_padding` on is not available in "
"Anatomy template. Please, add it there and restart "
"the pipeline (padding: \"4\"): `{}`").format(e)
@ -973,7 +980,9 @@ class WorkfileSettings(object):
self.set_colorspace()
def set_favorites(self):
projects_root = os.getenv("AVALON_PROJECTS")
anatomy = get_anatomy()
work_template = anatomy.templates["work"]["path"]
projects_root = anatomy.root_value_for_template(work_template)
work_dir = os.getenv("AVALON_WORKDIR")
asset = os.getenv("AVALON_ASSET")
project = os.getenv("AVALON_PROJECT")

View file

@ -6,7 +6,7 @@ import pyblish.api
import avalon.api as avalon
from avalon.vendor.Qt import (QtWidgets, QtGui)
import pype.api as pype
from pypeapp import Logger
from pypeapp import Logger, Anatomy
log = Logger().get_logger(__name__, "nukestudio")
@ -30,12 +30,17 @@ def set_workfiles():
# show workfile gui
workfiles.show(workdir)
def sync_avalon_data_to_workfile():
# import session to get project dir
S = avalon.Session
active_project_root = os.path.normpath(
os.path.join(S['AVALON_PROJECTS'], S['AVALON_PROJECT'])
)
project_name = avalon.Session["AVALON_PROJECT"]
anatomy = Anatomy(project_name)
work_template = anatomy.templates["work"]["path"]
work_root = anatomy.root_value_for_template(work_template)
active_project_root = (
os.path.join(work_root, project_name)
).replace("\\", "/")
# getting project
project = hiero.core.projects()[-1]
@ -350,17 +355,19 @@ def CreateNukeWorkfile(nodes=None,
# create root node and save all metadata
root_node = hiero.core.nuke.RootNode()
root_path = os.environ["AVALON_PROJECTS"]
anatomy = Anatomy(os.environ["AVALON_PROJECT"])
work_template = anatomy.templates["work"]["path"]
root_path = anatomy.root_value_for_template(work_template)
nuke_script.addNode(root_node)
# here to call pype.nuke.lib.BuildWorkfile
script_builder = nklib.BuildWorkfile(
root_node=root_node,
root_path=root_path,
nodes=nuke_script.getNodes(),
**kwargs
)
root_node=root_node,
root_path=root_path,
nodes=nuke_script.getNodes(),
**kwargs
)
class ClipLoader:

View file

@ -39,10 +39,8 @@ class CollectContextDataFromAport(pyblish.api.ContextPlugin):
# get avalon session data and convert \ to /
_S = avalon.session
projects = Path(_S["AVALON_PROJECTS"]).resolve()
asset = _S["AVALON_ASSET"]
workdir = Path(_S["AVALON_WORKDIR"]).resolve()
_S["AVALON_PROJECTS"] = str(projects)
_S["AVALON_WORKDIR"] = str(workdir)
context.data["avalonSession"] = _S

View file

@ -1,64 +0,0 @@
"""
Requires:
environment -> DEADLINE_PATH
Provides:
context -> deadlineUser (str)
"""
import os
import subprocess
import pyblish.api
from pype.plugin import contextplugin_should_run
CREATE_NO_WINDOW = 0x08000000
def deadline_command(cmd):
# Find Deadline
path = os.environ.get("DEADLINE_PATH", None)
assert path is not None, "Variable 'DEADLINE_PATH' must be set"
executable = os.path.join(path, "deadlinecommand")
if os.name == "nt":
executable += ".exe"
assert os.path.exists(
executable), "Deadline executable not found at %s" % executable
assert cmd, "Must have a command"
query = (executable, cmd)
process = subprocess.Popen(query, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
creationflags=CREATE_NO_WINDOW)
out, err = process.communicate()
return out
class CollectDeadlineUser(pyblish.api.ContextPlugin):
"""Retrieve the local active Deadline user"""
order = pyblish.api.CollectorOrder + 0.499
label = "Deadline User"
hosts = ['maya', 'fusion']
families = ["renderlayer", "saver.deadline"]
def process(self, context):
"""Inject the current working file"""
# Workaround bug pyblish-base#250
if not contextplugin_should_run(self, context):
return
user = deadline_command("GetCurrentUserName").strip()
if not user:
self.log.warning("No Deadline user found. "
"Do you have Deadline installed?")
return
self.log.info("Found Deadline user: {}".format(user))
context.data['deadlineUser'] = user

View file

@ -356,8 +356,11 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin):
_anatomy_filled = anatomy.format(anatomy_data)
_template_filled = _anatomy_filled["master"]["path"]
head, tail = _template_filled.split(frame_splitter)
padding = (
anatomy.templates["render"]["padding"]
padding = int(
anatomy.templates["render"].get(
"frame_padding",
anatomy.templates["render"].get("padding")
)
)
dst_col = clique.Collection(

View file

@ -343,10 +343,11 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
index_frame_start = None
if repre.get("frameStart"):
# TODO: bck compatibility `templates["render"]["padding"]`
frame_start_padding = anatomy.templates.get(
"frame_padding",
anatomy.templates["render"].get("padding")
frame_start_padding = int(
anatomy.templates["render"].get(
"frame_padding",
anatomy.templates["render"].get("padding")
)
)
index_frame_start = int(repre.get("frameStart"))
@ -656,7 +657,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
source = context.data["currentFile"]
anatomy = instance.context.data["anatomy"]
success, rootless_path = (
anatomy.roots_obj.find_root_template_from_path(source)
anatomy.find_root_template_from_path(source)
)
if success:
source = rootless_path

View file

@ -195,7 +195,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
output_dir = instance.data["outputDir"]
# Convert output dir to `{root}/rest/of/path/...` with Anatomy
success, rootless_path = (
self.anatomy.roots_obj.find_root_template_from_path(output_dir)
self.anatomy.find_root_template_from_path(output_dir)
)
if not success:
# `rootless_path` is not set to `output_dir` if none of roots match
@ -262,7 +262,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
# self.log.info(json.dumps(payload, indent=4, sort_keys=True))
url = "{}/api/jobs".format(self.DEADLINE_REST_URL)
response = requests.post(url, json=payload)
response = requests.post(url, json=payload, timeout=10)
if not response.ok:
raise Exception(response.text)
@ -379,7 +379,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
staging = os.path.dirname(list(cols[0])[0])
success, rootless_staging_dir = (
self.anatomy.roots_obj.find_root_template_from_path(staging)
self.anatomy.find_root_template_from_path(staging)
)
if success:
staging = rootless_staging_dir
@ -471,7 +471,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
staging = os.path.dirname(list(collection)[0])
success, rootless_staging_dir = (
self.anatomy.roots_obj.find_root_template_from_path(staging)
self.anatomy.find_root_template_from_path(staging)
)
if success:
staging = rootless_staging_dir
@ -506,7 +506,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
staging = os.path.dirname(remainder)
success, rootless_staging_dir = (
self.anatomy.roots_obj.find_root_template_from_path(staging)
self.anatomy.find_root_template_from_path(staging)
)
if success:
staging = rootless_staging_dir
@ -619,7 +619,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
source = context.data["currentFile"]
success, rootless_path = (
self.anatomy.roots_obj.find_root_template_from_path(source)
self.anatomy.find_root_template_from_path(source)
)
if success:
source = rootless_path
@ -684,7 +684,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
staging_dir = repre.get("stagingDir")
if staging_dir:
success, rootless_staging_dir = (
self.anatomy.roots_obj.find_root_template_from_path(
self.anatomy.find_root_template_from_path(
staging_dir
)
)

View file

@ -352,6 +352,8 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin):
"""
if 'verify' not in kwargs:
kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa
# add 10sec timeout before bailing out
kwargs['timeout'] = 10
return requests.post(*args, **kwargs)
def _requests_get(self, *args, **kwargs):
@ -366,4 +368,6 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin):
"""
if 'verify' not in kwargs:
kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa
# add 10sec timeout before bailing out
kwargs['timeout'] = 10
return requests.get(*args, **kwargs)

View file

@ -37,50 +37,71 @@ class ValidateAssRelativePaths(pyblish.api.InstancePlugin):
scene_dir, scene_basename = os.path.split(cmds.file(q=True, loc=True))
scene_name, _ = os.path.splitext(scene_basename)
project_root = "{}{}{}".format(
os.environ.get("AVALON_PROJECTS"),
os.path.sep,
os.environ.get("AVALON_PROJECT")
)
assert self.maya_is_true(relative_texture) is not True, \
("Texture path is set to be absolute")
assert self.maya_is_true(relative_procedural) is not True, \
("Procedural path is set to be absolute")
texture_search_path = texture_search_path.replace("\\", "/")
procedural_search_path = procedural_search_path.replace("\\", "/")
project_root = project_root.replace("\\", "/")
anatomy = instance.context.data["anatomy"]
assert project_root in texture_search_path, \
("Project root is not in texture_search_path")
assert project_root in procedural_search_path, \
("Project root is not in procedural_search_path")
# Use project root variables for multiplatform support, see:
# https://docs.arnoldrenderer.com/display/A5AFMUG/Search+Path
# ':' as path separator is supported by Arnold for all platforms.
keys = anatomy.root_environments().keys()
paths = []
for k in keys:
paths.append("[{}]".format(k))
self.log.info("discovered roots: {}".format(":".join(paths)))
assert ":".join(paths) in texture_search_path, (
"Project roots are not in texture_search_path"
)
assert ":".join(paths) in procedural_search_path, (
"Project roots are not in procedural_search_path"
)
@classmethod
def repair(cls, instance):
texture_search_path = cmds.getAttr(
"defaultArnoldRenderOptions.tspath"
texture_path = cmds.getAttr("defaultArnoldRenderOptions.tspath")
procedural_path = cmds.getAttr("defaultArnoldRenderOptions.pspath")
# Use project root variables for multiplatform support, see:
# https://docs.arnoldrenderer.com/display/A5AFMUG/Search+Path
# ':' as path separator is supported by Arnold for all platforms.
anatomy = instance.context.data["anatomy"]
keys = anatomy.root_environments().keys()
paths = []
for k in keys:
paths.append("[{}]".format(k))
cmds.setAttr(
"defaultArnoldRenderOptions.tspath",
":".join([p for p in paths + [texture_path] if p]),
type="string"
)
procedural_search_path = cmds.getAttr(
"defaultArnoldRenderOptions.pspath"
cmds.setAttr(
"defaultArnoldRenderOptions.absolute_texture_paths",
False
)
project_root = "{}{}{}".format(
os.environ.get("AVALON_PROJECTS"),
os.path.sep,
os.environ.get("AVALON_PROJECT"),
).replace("\\", "/")
cmds.setAttr(
"defaultArnoldRenderOptions.pspath",
":".join([p for p in paths + [procedural_path] if p]),
type="string"
)
cmds.setAttr(
"defaultArnoldRenderOptions.absolute_procedural_paths",
False
)
cmds.setAttr("defaultArnoldRenderOptions.tspath",
project_root + os.pathsep + texture_search_path,
type="string")
cmds.setAttr("defaultArnoldRenderOptions.pspath",
project_root + os.pathsep + procedural_search_path,
type="string")
cmds.setAttr("defaultArnoldRenderOptions.absolute_procedural_paths",
False)
cmds.setAttr("defaultArnoldRenderOptions.absolute_texture_paths",
False)
@staticmethod
def find_absolute_path(relative_path, all_root_paths):
for root_path in all_root_paths:
possible_path = os.path.join(root_path, relative_path)
if os.path.exists(possible_path):
return possible_path
def maya_is_true(self, attr_val):
"""

View file

@ -251,7 +251,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin):
self.expected_files(instance, render_path)
self.log.debug("__ expectedFiles: `{}`".format(
instance.data["expectedFiles"]))
response = requests.post(self.deadline_url, json=payload)
response = requests.post(self.deadline_url, json=payload, timeout=10)
if not response.ok:
raise Exception(response.text)

View file

@ -1,15 +0,0 @@
import pyblish.api
import avalon.api as avalon
import os
class CollectActiveProjectRoot(pyblish.api.ContextPlugin):
"""Inject the active project into context"""
label = "Collect Project Root"
order = pyblish.api.CollectorOrder - 0.1
def process(self, context):
S = avalon.Session
context.data["projectroot"] = os.path.normpath(
os.path.join(S['AVALON_PROJECTS'], S['AVALON_PROJECT'])
)

View file

@ -18,7 +18,7 @@ def main(env):
# Register Host (and it's pyblish plugins)
host_name = env["AVALON_APP"]
# TODO not sure if use "pype." or "avalon." for host import
host_import_str = f"avalon.{host_name}"
host_import_str = f"pype.{host_name}"
try:
host_module = importlib.import_module(host_import_str)

BIN
res/app_icons/harmony.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -9,7 +9,6 @@
"additionalProperties": true,
"required": [
"AVALON_PROJECTS",
"AVALON_PROJECT",
"AVALON_ASSET",
"AVALON_CONFIG"