From d4dccba24884520fb44b6406d2e47c8f9a7fab8d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 16 May 2019 17:32:43 +0200 Subject: [PATCH 1/4] fix(nuke): logging cleaning --- pype/nuke/__init__.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pype/nuke/__init__.py b/pype/nuke/__init__.py index 376e8f95b8..a2b1aeda6e 100644 --- a/pype/nuke/__init__.py +++ b/pype/nuke/__init__.py @@ -25,8 +25,6 @@ from pypeapp import Logger log = Logger().get_logger(__name__, "nuke") -# log = api.Logger.getLogger(__name__, "nuke") - AVALON_CONFIG = os.getenv("AVALON_CONFIG", "pype") PARENT_DIR = os.path.dirname(__file__) @@ -38,9 +36,8 @@ LOAD_PATH = os.path.join(PLUGINS_DIR, "nuke", "load") CREATE_PATH = os.path.join(PLUGINS_DIR, "nuke", "create") INVENTORY_PATH = os.path.join(PLUGINS_DIR, "nuke", "inventory") -self = sys.modules[__name__] -self.nLogger = None +# registering pyblish gui regarding settings in presets if os.getenv("PYBLISH_GUI", None): pyblish.register_gui(os.getenv("PYBLISH_GUI", None)) @@ -66,6 +63,7 @@ class NukeHandler(logging.Handler): "fatal", "error" ]: + msg = self.format(record) nuke.message(msg) @@ -77,9 +75,6 @@ if nuke_handler.get_name() \ logging.getLogger().addHandler(nuke_handler) logging.getLogger().setLevel(logging.INFO) -if not self.nLogger: - self.nLogger = Logger - def reload_config(): """Attempt to reload pipeline at run-time. @@ -157,7 +152,7 @@ def uninstall(): def on_pyblish_instance_toggled(instance, old_value, new_value): """Toggle node passthrough states on instance toggles.""" - self.log.info("instance toggle: {}, old_value: {}, new_value:{} ".format( + log.info("instance toggle: {}, old_value: {}, new_value:{} ".format( instance, old_value, new_value)) from avalon.nuke import ( From 16182d41eba4cd5859f7a6d645635a9473759346 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 16 May 2019 17:34:33 +0200 Subject: [PATCH 2/4] feat(nuke): Load nkscript as precomp with version --- pype/plugins/nuke/load/load_script_precomp.py | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 pype/plugins/nuke/load/load_script_precomp.py diff --git a/pype/plugins/nuke/load/load_script_precomp.py b/pype/plugins/nuke/load/load_script_precomp.py new file mode 100644 index 0000000000..6fd76edd03 --- /dev/null +++ b/pype/plugins/nuke/load/load_script_precomp.py @@ -0,0 +1,170 @@ +from avalon import api, style, io +from pype.nuke.lib import get_avalon_knob_data +import nuke +import os +from pype.api import Logger +log = Logger().get_logger(__name__, "nuke") + + + +class LinkAsGroup(api.Loader): + """Copy the published file to be pasted at the desired location""" + + representations = ["nk"] + families = ["*"] + + label = "Load Precomp" + order = 10 + icon = "file" + color = style.colors.dark + + def load(self, context, name, namespace, data): + + from avalon.nuke import containerise + # for k, v in context.items(): + # log.info("key: `{}`, value: {}\n".format(k, v)) + version = context['version'] + version_data = version.get("data", {}) + + vname = version.get("name", None) + first = version_data.get("startFrame", None) + last = version_data.get("endFrame", None) + + # Fallback to asset name when namespace is None + if namespace is None: + namespace = context['asset']['name'] + + file = self.fname.replace("\\", "/") + self.log.info("file: {}\n".format(self.fname)) + + precomp_name = context["representation"]["context"]["subset"] + + # Set global in point to start frame (if in version.data) + start = context["version"]["data"].get("startFrame", None) + + # add additional metadata from the version to imprint to Avalon knob + add_keys = ["startFrame", "endFrame", "handles", + "source", "author", "fps"] + + data_imprint = { + "start_frame": start, + "fstart": first, + "fend": last, + "version": vname + } + for k in add_keys: + data_imprint.update({k: context["version"]['data'][k]}) + data_imprint.update({"objectName": precomp_name}) + + # group context is set to precomp, so back up one level. + nuke.endGroup() + + # P = nuke.nodes.LiveGroup("file {}".format(file)) + P = nuke.createNode( + "Precomp", + "file {}".format(file)) + + # Set colorspace defined in version data + colorspace = context["version"]["data"].get("colorspace", None) + self.log.info("colorspace: {}\n".format(colorspace)) + + + # ['version', 'file', 'reading', 'output', 'useOutput'] + + P["name"].setValue("{}_{}".format(name, namespace)) + P["useOutput"].setValue(True) + + with P: + # iterate trough all nodes in group node and find pype writes + writes = [n.name() for n in nuke.allNodes() + if n.Class() == "Write" + if get_avalon_knob_data(n)] + + # create panel for selecting output + panel_choices = " ".join(writes) + panel_label = "Select write node for output" + p = nuke.Panel("Select Write Node") + p.addEnumerationPulldown( + panel_label, panel_choices) + p.show() + P["output"].setValue(p.value(panel_label)) + + P["tile_color"].setValue(0xff0ff0ff) + + return containerise( + node=P, + name=name, + namespace=namespace, + context=context, + loader=self.__class__.__name__, + data=data_imprint) + + def switch(self, container, representation): + self.update(container, representation) + + def update(self, container, representation): + """Update the Loader's path + + Nuke automatically tries to reset some variables when changing + the loader's path to a new file. These automatic changes are to its + inputs: + + """ + + from avalon.nuke import ( + update_container + ) + + node = nuke.toNode(container['objectName']) + + root = api.get_representation_path(representation).replace("\\","/") + + # Get start frame from version data + version = io.find_one({ + "type": "version", + "_id": representation["parent"] + }) + + # get all versions in list + versions = io.find({ + "type": "version", + "parent": version["parent"] + }).distinct('name') + + max_version = max(versions) + + updated_dict = {} + updated_dict.update({ + "representation": str(representation["_id"]), + "endFrame": version["data"].get("endFrame"), + "version": version.get("name"), + "colorspace": version["data"].get("colorspace"), + "source": version["data"].get("source"), + "handles": version["data"].get("handles"), + "fps": version["data"].get("fps"), + "author": version["data"].get("author"), + "outputDir": version["data"].get("outputDir"), + }) + + # Update the imprinted representation + update_container( + node, + updated_dict + ) + + node["file"].setValue(root) + + # change color of node + if version.get("name") not in [max_version]: + node["tile_color"].setValue(int("0xd84f20ff", 16)) + else: + node["tile_color"].setValue(int("0xff0ff0ff", 16)) + + log.info("udated to version: {}".format(version.get("name"))) + + + def remove(self, container): + from avalon.nuke import viewer_update_and_undo_stop + node = nuke.toNode(container['objectName']) + with viewer_update_and_undo_stop(): + nuke.delete(node) From 4f4a45c54b201cd69ec056622eeeee351a94043e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 17 May 2019 11:21:43 +0200 Subject: [PATCH 3/4] fix(premiere): removing message_window from pype.api and adding link to the message into premiere --- pype/api.py | 5 ----- pype/premiere/__init__.py | 6 ++++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pype/api.py b/pype/api.py index fcdcbce82b..0acb80e383 100644 --- a/pype/api.py +++ b/pype/api.py @@ -46,8 +46,6 @@ from .lib import ( get_data_hierarchical_attr ) -from .widgets.message_window import message - __all__ = [ # plugin classes "Extractor", @@ -89,7 +87,4 @@ __all__ = [ "Colorspace", "Dataflow", - # QtWidgets - "message" - ] diff --git a/pype/premiere/__init__.py b/pype/premiere/__init__.py index 74ce106de2..cc5abe115e 100644 --- a/pype/premiere/__init__.py +++ b/pype/premiere/__init__.py @@ -7,6 +7,8 @@ from pyblish import api as pyblish from pypeapp import Logger from .. import api +from ..widgets.message_window import message + import requests log = Logger().get_logger(__name__, "premiere") @@ -42,7 +44,7 @@ def request_aport(url_path, data={}): return req except Exception as e: - api.message(title="Premiere Aport Server", + message(title="Premiere Aport Server", message="Before you can run Premiere, start Aport Server. \n Error: {}".format( e), level="critical") @@ -99,7 +101,7 @@ def install(): # synchronize extensions extensions_sync() - api.message(title="pyblish_paths", message=str(reg_paths), level="info") + message(title="pyblish_paths", message=str(reg_paths), level="info") def uninstall(): From 8c2db60b26074f66578b8f91eec0651bfa2a7992 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 17 May 2019 16:21:47 +0200 Subject: [PATCH 4/4] (hotfix)/ added stagingDir to standalone publisher --- .../widgets/widget_component_item.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pype/standalonepublish/widgets/widget_component_item.py b/pype/standalonepublish/widgets/widget_component_item.py index 43aa54a955..a58a292ec5 100644 --- a/pype/standalonepublish/widgets/widget_component_item.py +++ b/pype/standalonepublish/widgets/widget_component_item.py @@ -284,11 +284,19 @@ class ComponentItem(QtWidgets.QFrame): self.preview.change_checked(hover) def collect_data(self): + in_files = self.in_data['files'] + staging_dir = os.path.dirname(in_files[0]) + + files = [os.path.basename(file) for file in in_files] + if len(files) == 1: + files = files[0] + data = { 'ext': self.in_data['ext'], 'label': self.name.text(), - 'representation': self.input_repre.text(), - 'files': self.in_data['files'], + 'name': self.input_repre.text(), + 'stagingDir': staging_dir, + 'files': files, 'thumbnail': self.is_thumbnail(), 'preview': self.is_preview() }