mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge branch 'develop' into feature/PYPE-570-maya-renderlayer-creator
This commit is contained in:
commit
438da15f6f
12 changed files with 473 additions and 152 deletions
|
|
@ -9,7 +9,7 @@ from pypeapp import config
|
|||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__version__ = "2.3.0"
|
||||
__version__ = "2.5.0"
|
||||
|
||||
PACKAGE_DIR = os.path.dirname(__file__)
|
||||
PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins")
|
||||
|
|
|
|||
313
pype/ftrack/actions/action_store_thumbnails_to_avalon.py
Normal file
313
pype/ftrack/actions/action_store_thumbnails_to_avalon.py
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
import os
|
||||
import requests
|
||||
import errno
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from pype.ftrack import BaseAction
|
||||
from pype.ftrack.lib import (
|
||||
get_project_from_entity,
|
||||
get_avalon_entities_for_assetversion
|
||||
)
|
||||
from pypeapp import Anatomy
|
||||
from pype.ftrack.lib.io_nonsingleton import DbConnector
|
||||
|
||||
|
||||
class StoreThumbnailsToAvalon(BaseAction):
|
||||
# Action identifier
|
||||
identifier = "store.thubmnail.to.avalon"
|
||||
# Action label
|
||||
label = "Pype Admin"
|
||||
# Action variant
|
||||
variant = "- Store Thumbnails to avalon"
|
||||
# Action description
|
||||
description = 'Test action'
|
||||
# roles that are allowed to register this action
|
||||
role_list = ["Pypeclub", "Administrator", "Project Manager"]
|
||||
|
||||
icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format(
|
||||
os.environ.get('PYPE_STATICS_SERVER', '')
|
||||
)
|
||||
|
||||
thumbnail_key = "AVALON_THUMBNAIL_ROOT"
|
||||
db_con = DbConnector()
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
for entity in entities:
|
||||
if entity.entity_type.lower() == "assetversion":
|
||||
return True
|
||||
return False
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
# DEBUG LINE
|
||||
# root_path = r"C:\Users\jakub.trllo\Desktop\Tests\ftrack_thumbnails"
|
||||
|
||||
thumbnail_roots = os.environ.get(self.thumbnail_key)
|
||||
if not thumbnail_roots:
|
||||
return {
|
||||
"success": False,
|
||||
"message": "`{}` environment is not set".format(
|
||||
self.thumbnail_key
|
||||
)
|
||||
}
|
||||
|
||||
existing_thumbnail_root = None
|
||||
for path in thumbnail_roots.split(os.pathsep):
|
||||
if os.path.exists(path):
|
||||
existing_thumbnail_root = path
|
||||
break
|
||||
|
||||
if existing_thumbnail_root is None:
|
||||
return {
|
||||
"success": False,
|
||||
"message": (
|
||||
"Can't access paths, set in `{}` ({})"
|
||||
).format(self.thumbnail_key, thumbnail_roots)
|
||||
}
|
||||
|
||||
project = get_project_from_entity(entities[0])
|
||||
project_name = project["full_name"]
|
||||
anatomy = Anatomy(project_name)
|
||||
|
||||
if "publish" not in anatomy.templates:
|
||||
msg = "Anatomy does not have set publish key!"
|
||||
|
||||
self.log.warning(msg)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"message": msg
|
||||
}
|
||||
|
||||
if "thumbnail" not in anatomy.templates["publish"]:
|
||||
msg = (
|
||||
"There is not set \"thumbnail\""
|
||||
" template in Antomy for project \"{}\""
|
||||
).format(project_name)
|
||||
|
||||
self.log.warning(msg)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"message": msg
|
||||
}
|
||||
|
||||
example_template_data = {
|
||||
"_id": "ID",
|
||||
"thumbnail_root": "THUBMNAIL_ROOT",
|
||||
"thumbnail_type": "THUMBNAIL_TYPE",
|
||||
"ext": ".EXT",
|
||||
"project": {
|
||||
"name": "PROJECT_NAME",
|
||||
"code": "PROJECT_CODE"
|
||||
},
|
||||
"asset": "ASSET_NAME",
|
||||
"subset": "SUBSET_NAME",
|
||||
"version": "VERSION_NAME",
|
||||
"hierarchy": "HIERARCHY"
|
||||
}
|
||||
tmp_filled = anatomy.format_all(example_template_data)
|
||||
thumbnail_result = tmp_filled["publish"]["thumbnail"]
|
||||
if not thumbnail_result.solved:
|
||||
missing_keys = thumbnail_result.missing_keys
|
||||
invalid_types = thumbnail_result.invalid_types
|
||||
submsg = ""
|
||||
if missing_keys:
|
||||
submsg += "Missing keys: {}".format(", ".join(
|
||||
["\"{}\"".format(key) for key in missing_keys]
|
||||
))
|
||||
|
||||
if invalid_types:
|
||||
items = []
|
||||
for key, value in invalid_types.items():
|
||||
items.append("{}{}".format(str(key), str(value)))
|
||||
submsg += "Invalid types: {}".format(", ".join(items))
|
||||
|
||||
msg = (
|
||||
"Thumbnail Anatomy template expects more keys than action"
|
||||
" can offer. {}"
|
||||
).format(submsg)
|
||||
|
||||
self.log.warning(msg)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"message": msg
|
||||
}
|
||||
|
||||
thumbnail_template = anatomy.templates["publish"]["thumbnail"]
|
||||
|
||||
self.db_con.install()
|
||||
|
||||
for entity in entities:
|
||||
# Skip if entity is not AssetVersion (never should happend, but..)
|
||||
if entity.entity_type.lower() != "assetversion":
|
||||
continue
|
||||
|
||||
# Skip if AssetVersion don't have thumbnail
|
||||
thumbnail_ent = entity["thumbnail"]
|
||||
if thumbnail_ent is None:
|
||||
self.log.debug((
|
||||
"Skipping. AssetVersion don't "
|
||||
"have set thumbnail. {}"
|
||||
).format(entity["id"]))
|
||||
continue
|
||||
|
||||
avalon_ents_result = get_avalon_entities_for_assetversion(
|
||||
entity, self.db_con
|
||||
)
|
||||
version_full_path = (
|
||||
"Asset: \"{project_name}/{asset_path}\""
|
||||
" | Subset: \"{subset_name}\""
|
||||
" | Version: \"{version_name}\""
|
||||
).format(**avalon_ents_result)
|
||||
|
||||
version = avalon_ents_result["version"]
|
||||
if not version:
|
||||
self.log.warning((
|
||||
"AssetVersion does not have version in avalon. {}"
|
||||
).format(version_full_path))
|
||||
continue
|
||||
|
||||
thumbnail_id = version["data"].get("thumbnail_id")
|
||||
if thumbnail_id:
|
||||
self.log.info((
|
||||
"AssetVersion skipped, already has thubmanil set. {}"
|
||||
).format(version_full_path))
|
||||
continue
|
||||
|
||||
# Get thumbnail extension
|
||||
file_ext = thumbnail_ent["file_type"]
|
||||
if not file_ext.startswith("."):
|
||||
file_ext = ".{}".format(file_ext)
|
||||
|
||||
avalon_project = avalon_ents_result["project"]
|
||||
avalon_asset = avalon_ents_result["asset"]
|
||||
hierarchy = ""
|
||||
parents = avalon_asset["data"].get("parents") or []
|
||||
if parents:
|
||||
hierarchy = "/".join(parents)
|
||||
|
||||
# Prepare anatomy template fill data
|
||||
# 1. Create new id for thumbnail entity
|
||||
thumbnail_id = ObjectId()
|
||||
|
||||
template_data = {
|
||||
"_id": str(thumbnail_id),
|
||||
"thumbnail_root": existing_thumbnail_root,
|
||||
"thumbnail_type": "thumbnail",
|
||||
"ext": file_ext,
|
||||
"project": {
|
||||
"name": avalon_project["name"],
|
||||
"code": avalon_project["data"].get("code")
|
||||
},
|
||||
"asset": avalon_ents_result["asset_name"],
|
||||
"subset": avalon_ents_result["subset_name"],
|
||||
"version": avalon_ents_result["version_name"],
|
||||
"hierarchy": hierarchy
|
||||
}
|
||||
|
||||
anatomy_filled = anatomy.format(template_data)
|
||||
thumbnail_path = anatomy_filled["publish"]["thumbnail"]
|
||||
thumbnail_path = thumbnail_path.replace("..", ".")
|
||||
thumbnail_path = os.path.normpath(thumbnail_path)
|
||||
|
||||
downloaded = False
|
||||
for loc in (thumbnail_ent.get("component_locations") or []):
|
||||
res_id = loc.get("resource_identifier")
|
||||
if not res_id:
|
||||
continue
|
||||
|
||||
thubmnail_url = self.get_thumbnail_url(res_id)
|
||||
if self.download_file(thubmnail_url, thumbnail_path):
|
||||
downloaded = True
|
||||
break
|
||||
|
||||
if not downloaded:
|
||||
self.log.warning(
|
||||
"Could not download thumbnail for {}".format(
|
||||
version_full_path
|
||||
)
|
||||
)
|
||||
continue
|
||||
|
||||
# Clean template data from keys that are dynamic
|
||||
template_data.pop("_id")
|
||||
template_data.pop("thumbnail_root")
|
||||
|
||||
thumbnail_entity = {
|
||||
"_id": thumbnail_id,
|
||||
"type": "thumbnail",
|
||||
"schema": "pype:thumbnail-1.0",
|
||||
"data": {
|
||||
"template": thumbnail_template,
|
||||
"template_data": template_data
|
||||
}
|
||||
}
|
||||
|
||||
# Create thumbnail entity
|
||||
self.db_con.insert_one(thumbnail_entity)
|
||||
self.log.debug(
|
||||
"Creating entity in database {}".format(str(thumbnail_entity))
|
||||
)
|
||||
|
||||
# Set thumbnail id for version
|
||||
self.db_con.update_one(
|
||||
{"_id": version["_id"]},
|
||||
{"$set": {"data.thumbnail_id": thumbnail_id}}
|
||||
)
|
||||
|
||||
self.db_con.update_one(
|
||||
{"_id": avalon_asset["_id"]},
|
||||
{"$set": {"data.thumbnail_id": thumbnail_id}}
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def get_thumbnail_url(self, resource_identifier, size=None):
|
||||
# TODO use ftrack_api method rather (find way how to use it)
|
||||
url_string = (
|
||||
u'{url}/component/thumbnail?id={id}&username={username}'
|
||||
u'&apiKey={apiKey}'
|
||||
)
|
||||
url = url_string.format(
|
||||
url=self.session.server_url,
|
||||
id=resource_identifier,
|
||||
username=self.session.api_user,
|
||||
apiKey=self.session.api_key
|
||||
)
|
||||
if size:
|
||||
url += u'&size={0}'.format(size)
|
||||
|
||||
return url
|
||||
|
||||
def download_file(self, source_url, dst_file_path):
|
||||
dir_path = os.path.dirname(dst_file_path)
|
||||
try:
|
||||
os.makedirs(dir_path)
|
||||
except OSError as exc:
|
||||
if exc.errno != errno.EEXIST:
|
||||
self.log.warning(
|
||||
"Could not create folder: \"{}\"".format(dir_path)
|
||||
)
|
||||
return False
|
||||
|
||||
self.log.debug(
|
||||
"Downloading file \"{}\" -> \"{}\"".format(
|
||||
source_url, dst_file_path
|
||||
)
|
||||
)
|
||||
file_open = open(dst_file_path, "wb")
|
||||
try:
|
||||
file_open.write(requests.get(source_url).content)
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
"Download of image `{}` failed.".format(source_url)
|
||||
)
|
||||
return False
|
||||
finally:
|
||||
file_open.close()
|
||||
return True
|
||||
|
||||
|
||||
def register(session, plugins_presets={}):
|
||||
StoreThumbnailsToAvalon(session, plugins_presets).register()
|
||||
|
|
@ -1643,7 +1643,7 @@ class SyncToAvalonEvent(BaseEvent):
|
|||
new_name, "task", schema_patterns=self.regex_schemas
|
||||
)
|
||||
if not passed_regex:
|
||||
self.regex_failed.append(ent_infos["entityId"])
|
||||
self.regex_failed.append(ent_info["entityId"])
|
||||
continue
|
||||
|
||||
if new_name not in self.task_changes_by_avalon_id[mongo_id]:
|
||||
|
|
|
|||
|
|
@ -4,3 +4,8 @@ from .ftrack_app_handler import *
|
|||
from .ftrack_event_handler import *
|
||||
from .ftrack_action_handler import *
|
||||
from .ftrack_base_handler import *
|
||||
|
||||
from .lib import (
|
||||
get_project_from_entity,
|
||||
get_avalon_entities_for_assetversion
|
||||
)
|
||||
|
|
|
|||
135
pype/ftrack/lib/lib.py
Normal file
135
pype/ftrack/lib/lib.py
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
from bson.objectid import ObjectId
|
||||
|
||||
from .avalon_sync import CustAttrIdKey
|
||||
import avalon.io
|
||||
|
||||
|
||||
def get_project_from_entity(entity):
|
||||
# TODO add more entities
|
||||
ent_type_lowered = entity.entity_type.lower()
|
||||
if ent_type_lowered == "project":
|
||||
return entity
|
||||
|
||||
elif ent_type_lowered == "assetversion":
|
||||
return entity["asset"]["parent"]["project"]
|
||||
|
||||
elif "project" in entity:
|
||||
return entity["project"]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_avalon_entities_for_assetversion(asset_version, db_con=None):
|
||||
output = {
|
||||
"success": True,
|
||||
"message": None,
|
||||
"project": None,
|
||||
"project_name": None,
|
||||
"asset": None,
|
||||
"asset_name": None,
|
||||
"asset_path": None,
|
||||
"subset": None,
|
||||
"subset_name": None,
|
||||
"version": None,
|
||||
"version_name": None,
|
||||
"representations": None
|
||||
}
|
||||
|
||||
if db_con is None:
|
||||
db_con = avalon.io
|
||||
db_con.install()
|
||||
|
||||
ft_asset = asset_version["asset"]
|
||||
subset_name = ft_asset["name"]
|
||||
version = asset_version["version"]
|
||||
parent = ft_asset["parent"]
|
||||
ent_path = "/".join(
|
||||
[ent["name"] for ent in parent["link"]]
|
||||
)
|
||||
project = get_project_from_entity(asset_version)
|
||||
project_name = project["full_name"]
|
||||
|
||||
output["project_name"] = project_name
|
||||
output["asset_name"] = parent["name"]
|
||||
output["asset_path"] = ent_path
|
||||
output["subset_name"] = subset_name
|
||||
output["version_name"] = version
|
||||
|
||||
db_con.Session["AVALON_PROJECT"] = project_name
|
||||
|
||||
avalon_project = db_con.find_one({"type": "project"})
|
||||
output["project"] = avalon_project
|
||||
|
||||
if not avalon_project:
|
||||
output["success"] = False
|
||||
output["message"] = "Project not synchronized to avalon `{}`".format(
|
||||
project_name
|
||||
)
|
||||
return output
|
||||
|
||||
asset_ent = None
|
||||
asset_mongo_id = parent["custom_attributes"].get(CustAttrIdKey)
|
||||
if asset_mongo_id:
|
||||
try:
|
||||
asset_mongo_id = ObjectId(asset_mongo_id)
|
||||
asset_ent = db_con.find_one({
|
||||
"type": "asset",
|
||||
"_id": asset_mongo_id
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not asset_ent:
|
||||
asset_ent = db_con.find_one({
|
||||
"type": "asset",
|
||||
"data.ftrackId": parent["id"]
|
||||
})
|
||||
|
||||
output["asset"] = asset_ent
|
||||
|
||||
if not asset_ent:
|
||||
output["success"] = False
|
||||
output["message"] = "Not synchronized entity to avalon `{}`".format(
|
||||
ent_path
|
||||
)
|
||||
return output
|
||||
|
||||
asset_mongo_id = asset_ent["_id"]
|
||||
|
||||
subset_ent = db_con.find_one({
|
||||
"type": "subset",
|
||||
"parent": asset_mongo_id,
|
||||
"name": subset_name
|
||||
})
|
||||
|
||||
output["subset"] = subset_ent
|
||||
|
||||
if not subset_ent:
|
||||
output["success"] = False
|
||||
output["message"] = (
|
||||
"Subset `{}` does not exist under Asset `{}`"
|
||||
).format(subset_name, ent_path)
|
||||
return output
|
||||
|
||||
version_ent = db_con.find_one({
|
||||
"type": "version",
|
||||
"name": version,
|
||||
"parent": subset_ent["_id"]
|
||||
})
|
||||
|
||||
output["version"] = version_ent
|
||||
|
||||
if not version_ent:
|
||||
output["success"] = False
|
||||
output["message"] = (
|
||||
"Version `{}` does not exist under Subset `{}` | Asset `{}`"
|
||||
).format(version, subset_name, ent_path)
|
||||
return output
|
||||
|
||||
repre_ents = list(db_con.find({
|
||||
"type": "representation",
|
||||
"parent": version_ent["_id"]
|
||||
}))
|
||||
|
||||
output["representations"] = repre_ents
|
||||
return output
|
||||
67
pype/lib.py
67
pype/lib.py
|
|
@ -361,23 +361,7 @@ def _get_host_name():
|
|||
|
||||
|
||||
def get_asset(asset_name=None):
|
||||
entity_data_keys_from_project_when_miss = [
|
||||
"frameStart", "frameEnd", "handleStart", "handleEnd", "fps",
|
||||
"resolutionWidth", "resolutionHeight"
|
||||
]
|
||||
|
||||
entity_keys_from_project_when_miss = []
|
||||
|
||||
alternatives = {
|
||||
"handleStart": "handles",
|
||||
"handleEnd": "handles"
|
||||
}
|
||||
|
||||
defaults = {
|
||||
"handleStart": 0,
|
||||
"handleEnd": 0
|
||||
}
|
||||
|
||||
""" Returning asset document from database """
|
||||
if not asset_name:
|
||||
asset_name = avalon.api.Session["AVALON_ASSET"]
|
||||
|
||||
|
|
@ -385,57 +369,10 @@ def get_asset(asset_name=None):
|
|||
"name": asset_name,
|
||||
"type": "asset"
|
||||
})
|
||||
|
||||
if not asset_document:
|
||||
raise TypeError("Entity \"{}\" was not found in DB".format(asset_name))
|
||||
|
||||
project_document = io.find_one({"type": "project"})
|
||||
|
||||
for key in entity_data_keys_from_project_when_miss:
|
||||
if asset_document["data"].get(key):
|
||||
continue
|
||||
|
||||
value = project_document["data"].get(key)
|
||||
if value is not None or key not in alternatives:
|
||||
asset_document["data"][key] = value
|
||||
continue
|
||||
|
||||
alt_key = alternatives[key]
|
||||
value = asset_document["data"].get(alt_key)
|
||||
if value is not None:
|
||||
asset_document["data"][key] = value
|
||||
continue
|
||||
|
||||
value = project_document["data"].get(alt_key)
|
||||
if value:
|
||||
asset_document["data"][key] = value
|
||||
continue
|
||||
|
||||
if key in defaults:
|
||||
asset_document["data"][key] = defaults[key]
|
||||
|
||||
for key in entity_keys_from_project_when_miss:
|
||||
if asset_document.get(key):
|
||||
continue
|
||||
|
||||
value = project_document.get(key)
|
||||
if value is not None or key not in alternatives:
|
||||
asset_document[key] = value
|
||||
continue
|
||||
|
||||
alt_key = alternatives[key]
|
||||
value = asset_document.get(alt_key)
|
||||
if value:
|
||||
asset_document[key] = value
|
||||
continue
|
||||
|
||||
value = project_document.get(alt_key)
|
||||
if value:
|
||||
asset_document[key] = value
|
||||
continue
|
||||
|
||||
if key in defaults:
|
||||
asset_document[key] = defaults[key]
|
||||
|
||||
return asset_document
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ def format_anatomy(data):
|
|||
"root": api.Session["AVALON_PROJECTS"],
|
||||
"subset": data["avalon"]["subset"],
|
||||
"asset": data["avalon"]["asset"],
|
||||
"task": api.Session["AVALON_TASK"].lower(),
|
||||
"task": api.Session["AVALON_TASK"],
|
||||
"family": data["avalon"]["family"],
|
||||
"project": {"name": project_document["name"],
|
||||
"code": project_document["data"].get("code", '')},
|
||||
|
|
@ -519,11 +519,6 @@ class WorkfileSettings(object):
|
|||
self.data = kwargs
|
||||
|
||||
def get_nodes(self, nodes=None, nodes_filter=None):
|
||||
# filter out only dictionaries for node creation
|
||||
#
|
||||
# print("\n\n")
|
||||
# pprint(self._nodes)
|
||||
#
|
||||
|
||||
if not isinstance(nodes, list) and not isinstance(nodes_filter, list):
|
||||
return [n for n in nuke.allNodes()]
|
||||
|
|
@ -791,6 +786,8 @@ class WorkfileSettings(object):
|
|||
return
|
||||
data = self._asset_entity["data"]
|
||||
|
||||
log.debug("__ asset data: `{}`".format(data))
|
||||
|
||||
missing_cols = []
|
||||
check_cols = ["fps", "frameStart", "frameEnd",
|
||||
"handleStart", "handleEnd"]
|
||||
|
|
@ -1070,7 +1067,7 @@ class BuildWorkfile(WorkfileSettings):
|
|||
"project": {"name": self._project["name"],
|
||||
"code": self._project["data"].get("code", '')},
|
||||
"asset": self._asset or os.environ["AVALON_ASSET"],
|
||||
"task": kwargs.get("task") or api.Session["AVALON_TASK"].lower(),
|
||||
"task": kwargs.get("task") or api.Session["AVALON_TASK"],
|
||||
"hierarchy": kwargs.get("hierarchy") or pype.get_hierarchy(),
|
||||
"version": kwargs.get("version", {}).get("name", 1),
|
||||
"user": getpass.getuser(),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from avalon.nuke.pipeline import Creator
|
|||
from avalon.nuke import lib as anlib
|
||||
import nuke
|
||||
|
||||
|
||||
class CreateBackdrop(Creator):
|
||||
"""Add Publishable Backdrop"""
|
||||
|
||||
|
|
@ -35,8 +36,8 @@ class CreateBackdrop(Creator):
|
|||
|
||||
return instance
|
||||
else:
|
||||
msg = "Please select nodes you "
|
||||
"wish to add to a container"
|
||||
msg = str("Please select nodes you "
|
||||
"wish to add to a container")
|
||||
self.log.error(msg)
|
||||
nuke.message(msg)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -240,77 +240,6 @@ class LoadBackdropNodes(api.Loader):
|
|||
|
||||
return update_container(GN, data_imprint)
|
||||
|
||||
def connect_active_viewer(self, group_node):
|
||||
"""
|
||||
Finds Active viewer and
|
||||
place the node under it, also adds
|
||||
name of group into Input Process of the viewer
|
||||
|
||||
Arguments:
|
||||
group_node (nuke node): nuke group node object
|
||||
|
||||
"""
|
||||
group_node_name = group_node["name"].value()
|
||||
|
||||
viewer = [n for n in nuke.allNodes() if "Viewer1" in n["name"].value()]
|
||||
if len(viewer) > 0:
|
||||
viewer = viewer[0]
|
||||
else:
|
||||
if not (len(nodes) < 2):
|
||||
msg = "Please create Viewer node before you "
|
||||
"run this action again"
|
||||
self.log.error(msg)
|
||||
nuke.message(msg)
|
||||
return None
|
||||
|
||||
# get coordinates of Viewer1
|
||||
xpos = viewer["xpos"].value()
|
||||
ypos = viewer["ypos"].value()
|
||||
|
||||
ypos += 150
|
||||
|
||||
viewer["ypos"].setValue(ypos)
|
||||
|
||||
# set coordinates to group node
|
||||
group_node["xpos"].setValue(xpos)
|
||||
group_node["ypos"].setValue(ypos + 50)
|
||||
|
||||
# add group node name to Viewer Input Process
|
||||
viewer["input_process_node"].setValue(group_node_name)
|
||||
|
||||
# put backdrop under
|
||||
pnlib.create_backdrop(label="Input Process", layer=2,
|
||||
nodes=[viewer, group_node], color="0x7c7faaff")
|
||||
|
||||
return True
|
||||
|
||||
def get_item(self, data, trackIndex, subTrackIndex):
|
||||
return {key: val for key, val in data.items()
|
||||
if subTrackIndex == val["subTrackIndex"]
|
||||
if trackIndex == val["trackIndex"]}
|
||||
|
||||
def byteify(self, input):
|
||||
"""
|
||||
Converts unicode strings to strings
|
||||
It goes trought all dictionary
|
||||
|
||||
Arguments:
|
||||
input (dict/str): input
|
||||
|
||||
Returns:
|
||||
dict: with fixed values and keys
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(input, dict):
|
||||
return {self.byteify(key): self.byteify(value)
|
||||
for key, value in input.iteritems()}
|
||||
elif isinstance(input, list):
|
||||
return [self.byteify(element) for element in input]
|
||||
elif isinstance(input, unicode):
|
||||
return input.encode('utf-8')
|
||||
else:
|
||||
return input
|
||||
|
||||
def switch(self, container, representation):
|
||||
self.update(container, representation)
|
||||
|
|
|
|||
|
|
@ -176,8 +176,8 @@ class LoadGizmoInputProcess(api.Loader):
|
|||
if len(viewer) > 0:
|
||||
viewer = viewer[0]
|
||||
else:
|
||||
msg = "Please create Viewer node before you "
|
||||
"run this action again"
|
||||
msg = str("Please create Viewer node before you "
|
||||
"run this action again")
|
||||
self.log.error(msg)
|
||||
nuke.message(msg)
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -276,8 +276,8 @@ class LoadLutsInputProcess(api.Loader):
|
|||
if len(viewer) > 0:
|
||||
viewer = viewer[0]
|
||||
else:
|
||||
msg = "Please create Viewer node before you "
|
||||
"run this action again"
|
||||
msg = str("Please create Viewer node before you "
|
||||
"run this action again")
|
||||
self.log.error(msg)
|
||||
nuke.message(msg)
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -58,7 +58,11 @@ class CollectBackdrops(pyblish.api.InstancePlugin):
|
|||
last_frame = int(nuke.root()["last_frame"].getValue())
|
||||
|
||||
# get version
|
||||
version = pype.get_version_from_path(nuke.root().name())
|
||||
version = instance.context.data.get('version')
|
||||
|
||||
if not version:
|
||||
raise RuntimeError("Script name has no version in the name.")
|
||||
|
||||
instance.data['version'] = version
|
||||
|
||||
# Add version data to instance
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue