From 46c831e585ac95c98675fd3edbb3028f43c7e22d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 19 May 2020 13:31:01 +0200 Subject: [PATCH 01/40] feat(resolve): adding resolve host basics --- pype/hooks/resolve/prelaunch.py | 42 +++++++++++++++ pype/resolve/README.markdown | 1 + pype/resolve/__init__.py | 71 +++++++++++++++++++++++++ pype/resolve/lib.py | 89 ++++++++++++++++++++++++++++++++ res/app_icons/resolve.png | Bin 0 -> 252602 bytes 5 files changed, 203 insertions(+) create mode 100644 pype/hooks/resolve/prelaunch.py create mode 100644 pype/resolve/README.markdown create mode 100644 pype/resolve/__init__.py create mode 100644 pype/resolve/lib.py create mode 100644 res/app_icons/resolve.png diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py new file mode 100644 index 0000000000..0020677c4c --- /dev/null +++ b/pype/hooks/resolve/prelaunch.py @@ -0,0 +1,42 @@ +import os +import traceback +from pype.lib import PypeHook +from pypeapp import Logger +from pype.resolve import lib as rlib + + +class ResolvePrelaunch(PypeHook): + """ + This hook will check if current workfile path has Resolve + project inside. IF not, it initialize it and finally it pass + path to the project by environment variable to Premiere launcher + shell script. + """ + + def __init__(self, logger=None): + if not logger: + self.log = Logger().get_logger(self.__class__.__name__) + else: + self.log = logger + + self.signature = "( {} )".format(self.__class__.__name__) + + def execute(self, *args, env: dict = None) -> bool: + + if not env: + env = os.environ + + try: + __import__("pype.resolve") + __import__("pyblish") + + except ImportError as e: + print(traceback.format_exc()) + print("pyblish: Could not load integration: %s " % e) + + else: + # Resolve Setup integration + # importlib.reload(prlib) + rlib.setup(env) + + return True diff --git a/pype/resolve/README.markdown b/pype/resolve/README.markdown new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/pype/resolve/README.markdown @@ -0,0 +1 @@ + diff --git a/pype/resolve/__init__.py b/pype/resolve/__init__.py new file mode 100644 index 0000000000..1e6c7c2274 --- /dev/null +++ b/pype/resolve/__init__.py @@ -0,0 +1,71 @@ +import os +from avalon import api as avalon +from pyblish import api as pyblish +from pypeapp import Logger + + +from .lib import ( + setup, + reload_pipeline, + ls, + LOAD_PATH, + CREATE_PATH, + PUBLISH_PATH +) + +__all__ = [ + "setup", + "reload_pipeline", + "ls" +] + +log = Logger().get_logger(__name__, "resolve") + + +def install(): + """Install resolve-specific functionality of avalon-core. + + This is where you install menus and register families, data + and loaders into resolve. + + It is called automatically when installing via `api.install(resolve)`. + + See the Maya equivalent for inspiration on how to implement this. + + """ + + # Disable all families except for the ones we explicitly want to see + family_states = [ + "imagesequence", + "mov" + ] + avalon.data["familiesStateDefault"] = False + avalon.data["familiesStateToggled"] = family_states + + log.info("pype.resolve installed") + + pyblish.register_host("resolve") + pyblish.register_plugin_path(PUBLISH_PATH) + log.info("Registering Premiera plug-ins..") + + avalon.register_plugin_path(avalon.Loader, LOAD_PATH) + avalon.register_plugin_path(avalon.Creator, CREATE_PATH) + + +def uninstall(): + """Uninstall all tha was installed + + This is where you undo everything that was done in `install()`. + That means, removing menus, deregistering families and data + and everything. It should be as though `install()` was never run, + because odds are calling this function means the user is interested + in re-installing shortly afterwards. If, for example, he has been + modifying the menu or registered families. + + """ + pyblish.deregister_host("resolve") + pyblish.deregister_plugin_path(PUBLISH_PATH) + log.info("Deregistering Premiera plug-ins..") + + avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) + avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) diff --git a/pype/resolve/lib.py b/pype/resolve/lib.py new file mode 100644 index 0000000000..012bcdd80c --- /dev/null +++ b/pype/resolve/lib.py @@ -0,0 +1,89 @@ +import os +import sys +import shutil +import json +from pysync import walktree +import requests + +from avalon import api +from pype.widgets.message_window import message +from pypeapp import Logger + + +log = Logger().get_logger(__name__, "resolve") + +self = sys.modules[__name__] +self._has_been_setup = False +self._registered_gui = None + +AVALON_CONFIG = os.environ["AVALON_CONFIG"] + +PARENT_DIR = os.path.dirname(__file__) +PACKAGE_DIR = os.path.dirname(PARENT_DIR) +PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") + +self.EXTENSIONS_PATH_REMOTE = os.path.join(PARENT_DIR, "extensions") +self.EXTENSIONS_PATH_LOCAL = None +self.EXTENSIONS_CACHE_PATH = None + +self.LOAD_PATH = os.path.join(PLUGINS_DIR, "resolve", "load") +self.CREATE_PATH = os.path.join(PLUGINS_DIR, "resolve", "create") +self.INVENTORY_PATH = os.path.join(PLUGINS_DIR, "resolve", "inventory") + +self.PUBLISH_PATH = os.path.join( + PLUGINS_DIR, "resolve", "publish" +).replace("\\", "/") + +if os.getenv("PUBLISH_PATH", None): + if self.PUBLISH_PATH not in os.environ["PUBLISH_PATH"]: + os.environ["PUBLISH_PATH"] = os.pathsep.join( + os.environ["PUBLISH_PATH"].split(os.pathsep) + + [self.PUBLISH_PATH] + ) +else: + os.environ["PUBLISH_PATH"] = self.PUBLISH_PATH + + +def ls(): + pass + + +def reload_pipeline(): + """Attempt to reload pipeline at run-time. + + CAUTION: This is primarily for development and debugging purposes. + + """ + + import importlib + import pype.resolve + + api.uninstall() + + for module in ("avalon.io", + "avalon.lib", + "avalon.pipeline", + "avalon.api", + "avalon.tools", + + "{}".format(AVALON_CONFIG), + "{}.resolve".format(AVALON_CONFIG), + "{}.resolve.lib".format(AVALON_CONFIG) + ): + log.info("Reloading module: {}...".format(module)) + try: + module = importlib.import_module(module) + importlib.reload(module) + except Exception as e: + log.warning("Cannot reload module: {}".format(e)) + + api.install(pype.resolve) + + +def setup(env=None): + """ Running wrapper + """ + if not env: + env = os.environ + + log.info("Resolve Pype wrapper has been installed") diff --git a/res/app_icons/resolve.png b/res/app_icons/resolve.png new file mode 100644 index 0000000000000000000000000000000000000000..d084288d906e6628c1e78676bd1d581aced26a86 GIT binary patch literal 252602 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 K4aMhTVW61-YdWEnkf6gM?w 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

S{aj3H{MHWV-rPc`LRtXOI(OchP7NkU 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

mGb7C!t8n<#iL;Xm^qncuSd0Gf;#gF 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 Date: Fri, 22 May 2020 18:32:52 +0200 Subject: [PATCH 02/40] feat(resolve): launching with pre imported resolve python console --- pype/hooks/resolve/prelaunch.py | 3 ++ pype/resolve/pre_python_console_script.py | 26 +++++++++++++++++ pype/resolve/python_get_resolve.py | 34 +++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 pype/resolve/pre_python_console_script.py create mode 100644 pype/resolve/python_get_resolve.py diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py index 0020677c4c..ebf101dc1d 100644 --- a/pype/hooks/resolve/prelaunch.py +++ b/pype/hooks/resolve/prelaunch.py @@ -26,6 +26,9 @@ class ResolvePrelaunch(PypeHook): if not env: env = os.environ + env["PRE_PYTHON_SCRIPT"] = os.path.normpath(env["PRE_PYTHON_SCRIPT"]) + self.log.info(env["PRE_PYTHON_SCRIPT"]) + try: __import__("pype.resolve") __import__("pyblish") diff --git a/pype/resolve/pre_python_console_script.py b/pype/resolve/pre_python_console_script.py new file mode 100644 index 0000000000..1c1aceaddd --- /dev/null +++ b/pype/resolve/pre_python_console_script.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +import time +from python_get_resolve import GetResolve + +wait_delay = 2.5 +wait = 0.00 +ready = None +while True: + try: + # Create project and set parameters: + resolve = GetResolve() + PM = resolve.GetProjectManager() + P = PM.GetCurrentProject() + if P.GetName() == "Untitled Project": + ready = None + else: + ready = True + except AttributeError: + pass + + if ready is None: + time.sleep(wait_delay) + print(f"Waiting {wait}s for Resolve to be open inproject") + wait += wait_delay + else: + break diff --git a/pype/resolve/python_get_resolve.py b/pype/resolve/python_get_resolve.py new file mode 100644 index 0000000000..862a5bb758 --- /dev/null +++ b/pype/resolve/python_get_resolve.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" +This file serves to return a DaVinci Resolve object +""" + +import sys + +def GetResolve(): + try: + # The PYTHONPATH needs to be set correctly for this import statement to work. + # An alternative is to import the DaVinciResolveScript by specifying absolute path (see ExceptionHandler logic) + import DaVinciResolveScript as bmd + except ImportError: + if sys.platform.startswith("darwin"): + expectedPath="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules/" + elif sys.platform.startswith("win") or sys.platform.startswith("cygwin"): + import os + expectedPath=os.getenv('PROGRAMDATA') + "\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\Modules\\" + elif sys.platform.startswith("linux"): + expectedPath="/opt/resolve/libs/Fusion/Modules/" + + # check if the default path has it... + print("Unable to find module DaVinciResolveScript from $PYTHONPATH - trying default locations") + try: + import imp + bmd = imp.load_source('DaVinciResolveScript', expectedPath+"DaVinciResolveScript.py") + except ImportError: + # No fallbacks ... report error: + print("Unable to find module DaVinciResolveScript - please ensure that the module DaVinciResolveScript is discoverable by python") + print("For a default DaVinci Resolve installation, the module is expected to be located in: "+expectedPath) + sys.exit() + + return bmd.scriptapp("Resolve") From 1dc624cdc6d3b4caf0bda30657e64d415efb3910 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 25 May 2020 19:54:43 +0200 Subject: [PATCH 03/40] feat(resolve): updating resolve integration --- pype/hooks/resolve/prelaunch.py | 25 ++++++- pype/resolve/__init__.py | 12 ++-- pype/resolve/lib.py | 48 +++++++++---- .../python_get_resolve.py | 0 .../resolve_utility_scripts/resolveapitest.py | 72 +++++++++++++++++++ pype/resolve/resolve_utility_scripts/test.py | 8 +++ .../pre_python_console_script.py | 0 pype/resolve/utility/python_get_resolve.py | 34 +++++++++ 8 files changed, 176 insertions(+), 23 deletions(-) rename pype/resolve/{ => resolve_utility_scripts}/python_get_resolve.py (100%) create mode 100644 pype/resolve/resolve_utility_scripts/resolveapitest.py create mode 100644 pype/resolve/resolve_utility_scripts/test.py rename pype/resolve/{ => utility}/pre_python_console_script.py (100%) create mode 100644 pype/resolve/utility/python_get_resolve.py diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py index ebf101dc1d..e3e1c83077 100644 --- a/pype/hooks/resolve/prelaunch.py +++ b/pype/hooks/resolve/prelaunch.py @@ -26,8 +26,28 @@ class ResolvePrelaunch(PypeHook): if not env: env = os.environ - env["PRE_PYTHON_SCRIPT"] = os.path.normpath(env["PRE_PYTHON_SCRIPT"]) - self.log.info(env["PRE_PYTHON_SCRIPT"]) + # making sure pyton 3.6 is installed at provided path + py36_dir = os.path.normpath(env.get("PYTHON36_RES", "")) + assert os.path.isdir(py36_dir), ( + "Python 3.6 is not installed at the provided folder path. Either " + "make sure the `environments\resolve.json` is having correctly set " + "`PYTHON36_RES` or make sure Python 3.6 is installed in given path." + f"\nPYTHON36_RES: `{py36_dir}`" + ) + env["PYTHON36_RES"] = py36_dir + + # setting utility scripts dir for scripts syncing + us_dir = os.path.normpath(env.get("RESOLVE_UTILITY_SCRIPTS_DIR", "")) + assert os.path.isdir(us_dir), ( + "Resolve utility script dir does not exists. Either make sure " + "the `environments\resolve.json` is having correctly set " + "`RESOLVE_UTILITY_SCRIPTS_DIR` or reinstall DaVinci Resolve. \n" + f"RESOLVE_UTILITY_SCRIPTS_DIR: `{us_dir}`" + ) + + # correctly format path for pre python script + pre_py_sc = os.path.normpath(env.get("PRE_PYTHON_SCRIPT", "")) + env["PRE_PYTHON_SCRIPT"] = pre_py_sc try: __import__("pype.resolve") @@ -39,7 +59,6 @@ class ResolvePrelaunch(PypeHook): else: # Resolve Setup integration - # importlib.reload(prlib) rlib.setup(env) return True diff --git a/pype/resolve/__init__.py b/pype/resolve/__init__.py index 1e6c7c2274..0683cfa92f 100644 --- a/pype/resolve/__init__.py +++ b/pype/resolve/__init__.py @@ -8,8 +8,8 @@ from .lib import ( setup, reload_pipeline, ls, - LOAD_PATH, - CREATE_PATH, + # LOAD_PATH, + # CREATE_PATH, PUBLISH_PATH ) @@ -48,8 +48,8 @@ def install(): pyblish.register_plugin_path(PUBLISH_PATH) log.info("Registering Premiera plug-ins..") - avalon.register_plugin_path(avalon.Loader, LOAD_PATH) - avalon.register_plugin_path(avalon.Creator, CREATE_PATH) + # avalon.register_plugin_path(avalon.Loader, LOAD_PATH) + # avalon.register_plugin_path(avalon.Creator, CREATE_PATH) def uninstall(): @@ -67,5 +67,5 @@ def uninstall(): pyblish.deregister_plugin_path(PUBLISH_PATH) log.info("Deregistering Premiera plug-ins..") - avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) - avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) + # avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) + # avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) diff --git a/pype/resolve/lib.py b/pype/resolve/lib.py index 012bcdd80c..95586b00eb 100644 --- a/pype/resolve/lib.py +++ b/pype/resolve/lib.py @@ -1,34 +1,21 @@ import os import sys import shutil -import json -from pysync import walktree -import requests from avalon import api from pype.widgets.message_window import message from pypeapp import Logger - log = Logger().get_logger(__name__, "resolve") self = sys.modules[__name__] -self._has_been_setup = False -self._registered_gui = None AVALON_CONFIG = os.environ["AVALON_CONFIG"] - PARENT_DIR = os.path.dirname(__file__) PACKAGE_DIR = os.path.dirname(PARENT_DIR) PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") -self.EXTENSIONS_PATH_REMOTE = os.path.join(PARENT_DIR, "extensions") -self.EXTENSIONS_PATH_LOCAL = None -self.EXTENSIONS_CACHE_PATH = None - -self.LOAD_PATH = os.path.join(PLUGINS_DIR, "resolve", "load") -self.CREATE_PATH = os.path.join(PLUGINS_DIR, "resolve", "create") -self.INVENTORY_PATH = os.path.join(PLUGINS_DIR, "resolve", "inventory") +self.UTILITY_SCRIPTS = os.path.join(PARENT_DIR, "resolve_utility_scripts") self.PUBLISH_PATH = os.path.join( PLUGINS_DIR, "resolve", "publish" @@ -48,6 +35,36 @@ def ls(): pass +def sync_utility_scripts(env=None): + """ Synchronizing basic utlility scripts for resolve. + + To be able to run scripts from inside `Resolve/Workspace/Scripts` menu + all scripts has to be accessible from defined folder. + """ + if not env: + env = os.environ + + us_dir = env.get("RESOLVE_UTILITY_SCRIPTS_DIR", "") + scripts = os.listdir(self.UTILITY_SCRIPTS) + + log.info(f"Utility Scripts Dir: `{self.UTILITY_SCRIPTS}`") + log.info(f"Utility Scripts: `{scripts}`") + + # make sure no script file is in folder + if next((s for s in os.listdir(us_dir)), None): + for s in os.listdir(us_dir): + path = os.path.join(us_dir, s) + log.info(f"Removing `{path}`...") + os.remove(path) + + # copy scripts into Resolve's utility scripts dir + for s in scripts: + src = os.path.join(self.UTILITY_SCRIPTS, s) + dst = os.path.join(us_dir, s) + log.info(f"Copying `{src}` to `{dst}`...") + shutil.copy2(src, dst) + + def reload_pipeline(): """Attempt to reload pipeline at run-time. @@ -86,4 +103,7 @@ def setup(env=None): if not env: env = os.environ + # synchronize resolve utility scripts + sync_utility_scripts(env) + log.info("Resolve Pype wrapper has been installed") diff --git a/pype/resolve/python_get_resolve.py b/pype/resolve/resolve_utility_scripts/python_get_resolve.py similarity index 100% rename from pype/resolve/python_get_resolve.py rename to pype/resolve/resolve_utility_scripts/python_get_resolve.py diff --git a/pype/resolve/resolve_utility_scripts/resolveapitest.py b/pype/resolve/resolve_utility_scripts/resolveapitest.py new file mode 100644 index 0000000000..e7cc32a864 --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/resolveapitest.py @@ -0,0 +1,72 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# This script tests Resolve 15 scripting API on MacOS. +# We suspect an issue with import of fusionscript.so. +# To test launch Resolve Studio first and then run this script. +# The script will save a text report. +# igor@hdhead.com + +from datetime import datetime +import os +import sys +import imp + +eol = '\n' +pathLib = 'C:\\Program Files\\Blackmagic Design\\DaVinci Resolve\\fusionscript.dll' + +reportDir = "C:\\Users\\jezsc" + +# Create initial report file. It will overwrite existing! +reportName = 'Resolve_API_Report.txt' +reportPath = os.path.join(reportDir, reportName) +reportfile = open(reportPath, 'w') +reportfile.close() + + +def report(entry): + # Print to console + print entry + + # Write a report entry + reportfile = open(reportPath, 'a') + reportfile.write(entry) + reportfile.write(eol) + reportfile.close() + + +# These are the values we'll discover and save +report('Time: ' + str(datetime.now())) +report('Python Version: ' + sys.version) +report('Interpreter Path: ' + sys.executable) +report('___________________________________' + eol) + +report('If no lines follow we have likely experienced a Fatal Python Error.') + +try: + # Will the API library import? Does it exist? + smodule = imp.load_dynamic('fusionscript', pathLib) + report('Imported fusionscript.so') + + # It looks like the library imported. Can we create a resolve instance now? + try: + resolve = smodule.scriptapp('Resolve') + if 'None' in str(type(resolve)): + report('Resolve instance is created, but Resolve is not found.') + sys.exit() + if 'PyRemoteObject' in str(type(resolve)): + report('Resolve instance is created and Resolve is responsive.') + except Exception, e: + report(str(e)) + + # Let's go nuts and count how many projects are in the Project Manager + try: + projman = resolve.GetProjectManager() + projects = projman.GetProjectsInCurrentFolder() + report('Project Count: ' + str(len(projects))) + report('All is well!') + except Exception, e: + report(str(e)) + +except Exception, e: + report(str(e)) diff --git a/pype/resolve/resolve_utility_scripts/test.py b/pype/resolve/resolve_utility_scripts/test.py new file mode 100644 index 0000000000..7d32aabfe5 --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/test.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3.6 +from python_get_resolve import GetResolve + +resolve = GetResolve() +PM = resolve.GetProjectManager() +P = PM.GetCurrentProject() + +print(P.GetName()) diff --git a/pype/resolve/pre_python_console_script.py b/pype/resolve/utility/pre_python_console_script.py similarity index 100% rename from pype/resolve/pre_python_console_script.py rename to pype/resolve/utility/pre_python_console_script.py diff --git a/pype/resolve/utility/python_get_resolve.py b/pype/resolve/utility/python_get_resolve.py new file mode 100644 index 0000000000..862a5bb758 --- /dev/null +++ b/pype/resolve/utility/python_get_resolve.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" +This file serves to return a DaVinci Resolve object +""" + +import sys + +def GetResolve(): + try: + # The PYTHONPATH needs to be set correctly for this import statement to work. + # An alternative is to import the DaVinciResolveScript by specifying absolute path (see ExceptionHandler logic) + import DaVinciResolveScript as bmd + except ImportError: + if sys.platform.startswith("darwin"): + expectedPath="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules/" + elif sys.platform.startswith("win") or sys.platform.startswith("cygwin"): + import os + expectedPath=os.getenv('PROGRAMDATA') + "\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\Modules\\" + elif sys.platform.startswith("linux"): + expectedPath="/opt/resolve/libs/Fusion/Modules/" + + # check if the default path has it... + print("Unable to find module DaVinciResolveScript from $PYTHONPATH - trying default locations") + try: + import imp + bmd = imp.load_source('DaVinciResolveScript', expectedPath+"DaVinciResolveScript.py") + except ImportError: + # No fallbacks ... report error: + print("Unable to find module DaVinciResolveScript - please ensure that the module DaVinciResolveScript is discoverable by python") + print("For a default DaVinci Resolve installation, the module is expected to be located in: "+expectedPath) + sys.exit() + + return bmd.scriptapp("Resolve") From 341379e546807e1dfa6794402e9dffcea3931088 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 27 May 2020 18:20:52 +0200 Subject: [PATCH 04/40] feat(resolve): wip integration workio, pipeline and basic avalon methods, menu, --- pype/hooks/resolve/prelaunch.py | 13 +- pype/plugins/resolve/publish/collect_host.py | 17 ++ pype/resolve/__init__.py | 106 ++++------ pype/resolve/action.py | 53 +++++ pype/resolve/lib.py | 109 ----------- pype/resolve/menu.py | 133 +++++++++++++ pype/resolve/menu_style.qss | 34 ++++ pype/resolve/pipeline.py | 184 ++++++++++++++++++ pype/resolve/plugin.py | 75 +++++++ pype/resolve/preload_console.py | 29 +++ .../resolve_utility_scripts/Pype_menu.py | 34 ++++ .../resolve_utility_scripts/README.markdown | 1 + .../resolve_utility_scripts/__test_gui.py | 111 +++++++++++ .../resolve_utility_scripts/__test_pyblish.py | 57 ++++++ .../__test_subprocess.py | 36 ++++ .../python_get_resolve.py | 34 ---- .../resolve_utility_scripts/resolveapitest.py | 72 ------- pype/resolve/resolve_utility_scripts/test.py | 8 - .../utility/pre_python_console_script.py | 26 --- pype/resolve/utility/python_get_resolve.py | 34 ---- pype/resolve/utils.py | 114 +++++++++++ pype/resolve/workio.py | 88 +++++++++ 22 files changed, 1014 insertions(+), 354 deletions(-) create mode 100644 pype/plugins/resolve/publish/collect_host.py create mode 100644 pype/resolve/action.py create mode 100644 pype/resolve/menu.py create mode 100644 pype/resolve/menu_style.qss create mode 100644 pype/resolve/pipeline.py create mode 100644 pype/resolve/plugin.py create mode 100644 pype/resolve/preload_console.py create mode 100644 pype/resolve/resolve_utility_scripts/Pype_menu.py create mode 100644 pype/resolve/resolve_utility_scripts/README.markdown create mode 100644 pype/resolve/resolve_utility_scripts/__test_gui.py create mode 100644 pype/resolve/resolve_utility_scripts/__test_pyblish.py create mode 100644 pype/resolve/resolve_utility_scripts/__test_subprocess.py delete mode 100644 pype/resolve/resolve_utility_scripts/python_get_resolve.py delete mode 100644 pype/resolve/resolve_utility_scripts/resolveapitest.py delete mode 100644 pype/resolve/resolve_utility_scripts/test.py delete mode 100644 pype/resolve/utility/pre_python_console_script.py delete mode 100644 pype/resolve/utility/python_get_resolve.py create mode 100644 pype/resolve/utils.py create mode 100644 pype/resolve/workio.py diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py index e3e1c83077..d0b7448a41 100644 --- a/pype/hooks/resolve/prelaunch.py +++ b/pype/hooks/resolve/prelaunch.py @@ -2,7 +2,7 @@ import os import traceback from pype.lib import PypeHook from pypeapp import Logger -from pype.resolve import lib as rlib +from pype.resolve import utils class ResolvePrelaunch(PypeHook): @@ -27,14 +27,15 @@ class ResolvePrelaunch(PypeHook): env = os.environ # making sure pyton 3.6 is installed at provided path - py36_dir = os.path.normpath(env.get("PYTHON36_RES", "")) + py36_dir = os.path.normpath(env.get("PYTHON36_RESOLVE", "")) assert os.path.isdir(py36_dir), ( "Python 3.6 is not installed at the provided folder path. Either " "make sure the `environments\resolve.json` is having correctly set " - "`PYTHON36_RES` or make sure Python 3.6 is installed in given path." - f"\nPYTHON36_RES: `{py36_dir}`" + "`PYTHON36_RESOLVE` or make sure Python 3.6 is installed in given path." + f"\nPYTHON36_RESOLVE: `{py36_dir}`" ) - env["PYTHON36_RES"] = py36_dir + self.log.info(f"Path to Resolve Python folder: `{py36_dir}`...") + env["PYTHON36_RESOLVE"] = py36_dir # setting utility scripts dir for scripts syncing us_dir = os.path.normpath(env.get("RESOLVE_UTILITY_SCRIPTS_DIR", "")) @@ -59,6 +60,6 @@ class ResolvePrelaunch(PypeHook): else: # Resolve Setup integration - rlib.setup(env) + utils.setup(env) return True diff --git a/pype/plugins/resolve/publish/collect_host.py b/pype/plugins/resolve/publish/collect_host.py new file mode 100644 index 0000000000..9119ba1f4f --- /dev/null +++ b/pype/plugins/resolve/publish/collect_host.py @@ -0,0 +1,17 @@ +import pyblish.api +from python_get_resolve import GetResolve + + +class CollectProject(pyblish.api.ContextPlugin): + """Collect Project object""" + + order = pyblish.api.CollectorOrder - 0.1 + label = "Collect Project" + hosts = ["resolve"] + + def process(self, context): + resolve = GetResolve() + PM = resolve.GetProjectManager() + P = PM.GetCurrentProject() + + self.log.info(P.GetName()) diff --git a/pype/resolve/__init__.py b/pype/resolve/__init__.py index 0683cfa92f..966d7aef4c 100644 --- a/pype/resolve/__init__.py +++ b/pype/resolve/__init__.py @@ -1,71 +1,47 @@ -import os -from avalon import api as avalon -from pyblish import api as pyblish -from pypeapp import Logger - - -from .lib import ( - setup, - reload_pipeline, +from .pipeline import ( + install, + uninstall, ls, - # LOAD_PATH, - # CREATE_PATH, - PUBLISH_PATH + containerise, + reload_pipeline, + publish, + launch_workfiles_app ) +from .utils import ( + setup, + get_resolve_module +) + +from .workio import ( + open_file, + save_file, + current_file, + has_unsaved_changes, + file_extensions, + work_root +) + +# from .lib import ( +# +# ) + __all__ = [ - "setup", + "install", + "uninstall", + "ls", + "containerise", "reload_pipeline", - "ls" + "publish", + "launch_workfiles_app", + + "setup", + "get_resolve_module", + + "open_file", + "save_file", + "current_file", + "has_unsaved_changes", + "file_extensions", + "work_root" ] - -log = Logger().get_logger(__name__, "resolve") - - -def install(): - """Install resolve-specific functionality of avalon-core. - - This is where you install menus and register families, data - and loaders into resolve. - - It is called automatically when installing via `api.install(resolve)`. - - See the Maya equivalent for inspiration on how to implement this. - - """ - - # Disable all families except for the ones we explicitly want to see - family_states = [ - "imagesequence", - "mov" - ] - avalon.data["familiesStateDefault"] = False - avalon.data["familiesStateToggled"] = family_states - - log.info("pype.resolve installed") - - pyblish.register_host("resolve") - pyblish.register_plugin_path(PUBLISH_PATH) - log.info("Registering Premiera plug-ins..") - - # avalon.register_plugin_path(avalon.Loader, LOAD_PATH) - # avalon.register_plugin_path(avalon.Creator, CREATE_PATH) - - -def uninstall(): - """Uninstall all tha was installed - - This is where you undo everything that was done in `install()`. - That means, removing menus, deregistering families and data - and everything. It should be as though `install()` was never run, - because odds are calling this function means the user is interested - in re-installing shortly afterwards. If, for example, he has been - modifying the menu or registered families. - - """ - pyblish.deregister_host("resolve") - pyblish.deregister_plugin_path(PUBLISH_PATH) - log.info("Deregistering Premiera plug-ins..") - - # avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) - # avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) diff --git a/pype/resolve/action.py b/pype/resolve/action.py new file mode 100644 index 0000000000..94d0f5eb67 --- /dev/null +++ b/pype/resolve/action.py @@ -0,0 +1,53 @@ +# absolute_import is needed to counter the `module has no cmds error` in Maya +from __future__ import absolute_import + +import pyblish.api + + +from ..action import get_errored_instances_from_context + + +class SelectInvalidAction(pyblish.api.Action): + """Select invalid clips in Resolve timeline when plug-in failed. + + To retrieve the invalid nodes this assumes a static `get_invalid()` + method is available on the plugin. + + """ + label = "Select invalid" + on = "failed" # This action is only available on a failed plug-in + icon = "search" # Icon from Awesome Icon + + def process(self, context, plugin): + + try: + from pype.resolve.utils import get_resolve_module + resolve = get_resolve_module() + except ImportError: + raise ImportError("Current host is not Resolve") + + errored_instances = get_errored_instances_from_context(context) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(errored_instances, plugin) + + # Get the invalid nodes for the plug-ins + self.log.info("Finding invalid clips..") + invalid = list() + for instance in instances: + invalid_nodes = plugin.get_invalid(instance) + if invalid_nodes: + if isinstance(invalid_nodes, (list, tuple)): + invalid.extend(invalid_nodes) + else: + self.log.warning("Plug-in returned to be invalid, " + "but has no selectable nodes.") + + # Ensure unique (process each node only once) + invalid = list(set(invalid)) + + if invalid: + self.log.info("Selecting invalid nodes: %s" % ", ".join(invalid)) + # TODO: select resolve timeline track items in current timeline + else: + self.log.info("No invalid nodes found.") diff --git a/pype/resolve/lib.py b/pype/resolve/lib.py index 95586b00eb..e69de29bb2 100644 --- a/pype/resolve/lib.py +++ b/pype/resolve/lib.py @@ -1,109 +0,0 @@ -import os -import sys -import shutil - -from avalon import api -from pype.widgets.message_window import message -from pypeapp import Logger - -log = Logger().get_logger(__name__, "resolve") - -self = sys.modules[__name__] - -AVALON_CONFIG = os.environ["AVALON_CONFIG"] -PARENT_DIR = os.path.dirname(__file__) -PACKAGE_DIR = os.path.dirname(PARENT_DIR) -PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") - -self.UTILITY_SCRIPTS = os.path.join(PARENT_DIR, "resolve_utility_scripts") - -self.PUBLISH_PATH = os.path.join( - PLUGINS_DIR, "resolve", "publish" -).replace("\\", "/") - -if os.getenv("PUBLISH_PATH", None): - if self.PUBLISH_PATH not in os.environ["PUBLISH_PATH"]: - os.environ["PUBLISH_PATH"] = os.pathsep.join( - os.environ["PUBLISH_PATH"].split(os.pathsep) + - [self.PUBLISH_PATH] - ) -else: - os.environ["PUBLISH_PATH"] = self.PUBLISH_PATH - - -def ls(): - pass - - -def sync_utility_scripts(env=None): - """ Synchronizing basic utlility scripts for resolve. - - To be able to run scripts from inside `Resolve/Workspace/Scripts` menu - all scripts has to be accessible from defined folder. - """ - if not env: - env = os.environ - - us_dir = env.get("RESOLVE_UTILITY_SCRIPTS_DIR", "") - scripts = os.listdir(self.UTILITY_SCRIPTS) - - log.info(f"Utility Scripts Dir: `{self.UTILITY_SCRIPTS}`") - log.info(f"Utility Scripts: `{scripts}`") - - # make sure no script file is in folder - if next((s for s in os.listdir(us_dir)), None): - for s in os.listdir(us_dir): - path = os.path.join(us_dir, s) - log.info(f"Removing `{path}`...") - os.remove(path) - - # copy scripts into Resolve's utility scripts dir - for s in scripts: - src = os.path.join(self.UTILITY_SCRIPTS, s) - dst = os.path.join(us_dir, s) - log.info(f"Copying `{src}` to `{dst}`...") - shutil.copy2(src, dst) - - -def reload_pipeline(): - """Attempt to reload pipeline at run-time. - - CAUTION: This is primarily for development and debugging purposes. - - """ - - import importlib - import pype.resolve - - api.uninstall() - - for module in ("avalon.io", - "avalon.lib", - "avalon.pipeline", - "avalon.api", - "avalon.tools", - - "{}".format(AVALON_CONFIG), - "{}.resolve".format(AVALON_CONFIG), - "{}.resolve.lib".format(AVALON_CONFIG) - ): - log.info("Reloading module: {}...".format(module)) - try: - module = importlib.import_module(module) - importlib.reload(module) - except Exception as e: - log.warning("Cannot reload module: {}".format(e)) - - api.install(pype.resolve) - - -def setup(env=None): - """ Running wrapper - """ - if not env: - env = os.environ - - # synchronize resolve utility scripts - sync_utility_scripts(env) - - log.info("Resolve Pype wrapper has been installed") diff --git a/pype/resolve/menu.py b/pype/resolve/menu.py new file mode 100644 index 0000000000..9f45ec9b70 --- /dev/null +++ b/pype/resolve/menu.py @@ -0,0 +1,133 @@ +import os +import sys + +from Qt import QtWidgets, QtCore + + +def load_stylesheet(): + path = os.path.join(os.path.dirname(__file__), "menu_style.qss") + if not os.path.exists(path): + print("Unable to load stylesheet, file not found in resources") + return "" + + with open(path, "r") as file_stream: + stylesheet = file_stream.read() + return stylesheet + + +class Spacer(QtWidgets.QWidget): + def __init__(self, height, *args, **kwargs): + super(self.__class__, self).__init__(*args, **kwargs) + + self.setFixedHeight(height) + + real_spacer = QtWidgets.QWidget(self) + real_spacer.setObjectName("Spacer") + real_spacer.setFixedHeight(int(height / 3)) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(real_spacer) + + self.setLayout(layout) + + +class PypeMenu(QtWidgets.QWidget): + def __init__(self, *args, **kwargs): + super(self.__class__, self).__init__(*args, **kwargs) + + self.setObjectName("PypeMenu") + + self.setWindowFlags( + QtCore.Qt.Window + | QtCore.Qt.CustomizeWindowHint + | QtCore.Qt.WindowTitleHint + | QtCore.Qt.WindowCloseButtonHint + | QtCore.Qt.WindowStaysOnTopHint + ) + + self.setWindowTitle("Pype") + workfiles_btn = QtWidgets.QPushButton("Workfiles", self) + create_btn = QtWidgets.QPushButton("Create", self) + publish_btn = QtWidgets.QPushButton("Publish", self) + load_btn = QtWidgets.QPushButton("Load", self) + inventory_btn = QtWidgets.QPushButton("Inventory", self) + rename_btn = QtWidgets.QPushButton("Rename", self) + set_colorspace_btn = QtWidgets.QPushButton( + "Set colorspace from presets", self + ) + reset_resolution_btn = QtWidgets.QPushButton( + "Reset Resolution from peresets", self + ) + reload_pipeline_btn = QtWidgets.QPushButton("Reload pipeline", self) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(10, 10, 10, 10) + + layout.addWidget(workfiles_btn) + layout.addWidget(create_btn) + layout.addWidget(publish_btn) + layout.addWidget(load_btn) + layout.addWidget(inventory_btn) + + layout.addWidget(Spacer(20, self)) + + layout.addWidget(rename_btn) + layout.addWidget(set_colorspace_btn) + layout.addWidget(reset_resolution_btn) + + layout.addWidget(Spacer(20, self)) + + layout.addWidget(reload_pipeline_btn) + + self.setLayout(layout) + + workfiles_btn.clicked.connect(self.on_reload_pipeline_clicked) + create_btn.clicked.connect(self.on_create_clicked) + publish_btn.clicked.connect(self.on_publish_clicked) + load_btn.clicked.connect(self.on_load_clicked) + inventory_btn.clicked.connect(self.on_inventory_clicked) + rename_btn.clicked.connect(self.on_rename_clicked) + set_colorspace_btn.clicked.connect(self.on_set_colorspace_clicked) + reset_resolution_btn.clicked.connect(self.on_reset_resolution_clicked) + reload_pipeline_btn.clicked.connect(self.on_reload_pipeline_clicked) + + def on_workfile_clicked(self): + print("Clicked Workfile") + + def on_create_clicked(self): + print("Clicked Create") + + def on_publish_clicked(self): + print("Clicked Publish") + + def on_load_clicked(self): + print("Clicked Load") + + def on_inventory_clicked(self): + print("Clicked Inventory") + + def on_rename_clicked(self): + print("Clicked Rename") + + def on_set_colorspace_clicked(self): + print("Clicked Set Colorspace") + + def on_reset_resolution_clicked(self): + print("Clicked Reset Resolution") + + def on_reload_pipeline_clicked(self): + print("Clicked Reload Pipeline") + + +def launch_pype_menu(): + app = QtWidgets.QApplication(sys.argv) + + pype_menu = PypeMenu() + + stylesheet = load_stylesheet() + pype_menu.setStyleSheet(stylesheet) + + pype_menu.show() + + sys.exit(app.exec_()) diff --git a/pype/resolve/menu_style.qss b/pype/resolve/menu_style.qss new file mode 100644 index 0000000000..52672364db --- /dev/null +++ b/pype/resolve/menu_style.qss @@ -0,0 +1,34 @@ +QWidget { + background-color: #3a3939; + border-radius: 5; +} + +QPushButton { + border: 1px solid #6d6d6d; + background-color: #201f1f; + color: #6d6d6d; + padding: 5; +} + +QPushButton:focus { + background-color: "#272525"; +} + +QPushButton:pressed { + background-color: "#686464"; + color: #333333; +} + +QPushButton:hover { + color: #d0d0d0; + background-color: "#343232"; +} + +#PypeMenu { + border: 1px solid #333333; +} + +#Spacer { + padding: 10; + background-color: #464646; +} diff --git a/pype/resolve/pipeline.py b/pype/resolve/pipeline.py new file mode 100644 index 0000000000..b6cae307b0 --- /dev/null +++ b/pype/resolve/pipeline.py @@ -0,0 +1,184 @@ +""" +Basic avalon integration +""" +import os +import sys +from avalon.tools import workfiles +from avalon import api as avalon +from pyblish import api as pyblish +from pypeapp import Logger + +log = Logger().get_logger(__name__, "resolve") + +# self = sys.modules[__name__] + +AVALON_CONFIG = os.environ["AVALON_CONFIG"] +PARENT_DIR = os.path.dirname(__file__) +PACKAGE_DIR = os.path.dirname(PARENT_DIR) +PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") + +LOAD_PATH = os.path.join(PLUGINS_DIR, "resolve", "load") +CREATE_PATH = os.path.join(PLUGINS_DIR, "resolve", "create") +INVENTORY_PATH = os.path.join(PLUGINS_DIR, "resolve", "inventory") + +PUBLISH_PATH = os.path.join( + PLUGINS_DIR, "resolve", "publish" +).replace("\\", "/") + +AVALON_CONTAINERS = ":AVALON_CONTAINERS" +# IS_HEADLESS = not hasattr(cmds, "about") or cmds.about(batch=True) + + +def install(): + """Install resolve-specific functionality of avalon-core. + + This is where you install menus and register families, data + and loaders into resolve. + + It is called automatically when installing via `api.install(resolve)`. + + See the Maya equivalent for inspiration on how to implement this. + + """ + from .menu import launch_pype_menu + + # Disable all families except for the ones we explicitly want to see + family_states = [ + "imagesequence", + "mov" + ] + avalon.data["familiesStateDefault"] = False + avalon.data["familiesStateToggled"] = family_states + + log.info("pype.resolve installed") + + pyblish.register_host("resolve") + pyblish.register_plugin_path(PUBLISH_PATH) + log.info("Registering DaVinci Resovle plug-ins..") + + avalon.register_plugin_path(avalon.Loader, LOAD_PATH) + avalon.register_plugin_path(avalon.Creator, CREATE_PATH) + avalon.register_plugin_path(avalon.InventoryAction, INVENTORY_PATH) + + # opening menu + launch_pype_menu() + + +def uninstall(): + """Uninstall all tha was installed + + This is where you undo everything that was done in `install()`. + That means, removing menus, deregistering families and data + and everything. It should be as though `install()` was never run, + because odds are calling this function means the user is interested + in re-installing shortly afterwards. If, for example, he has been + modifying the menu or registered families. + + """ + pyblish.deregister_host("resolve") + pyblish.deregister_plugin_path(PUBLISH_PATH) + log.info("Deregistering DaVinci Resovle plug-ins..") + + avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH) + avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH) + avalon.deregister_plugin_path(avalon.InventoryAction, INVENTORY_PATH) + + +def containerise(obj, + name, + namespace, + context, + loader=None, + data=None): + """Bundle Resolve's object into an assembly and imprint it with metadata + + Containerisation enables a tracking of version, author and origin + for loaded assets. + + Arguments: + obj (obj): Resolve's object to imprint as container + name (str): Name of resulting assembly + namespace (str): Namespace under which to host container + context (dict): Asset information + loader (str, optional): Name of node used to produce this container. + + Returns: + obj (obj): containerised object + + """ + pass + + +def ls(): + """List available containers. + + This function is used by the Container Manager in Nuke. You'll + need to implement a for-loop that then *yields* one Container at + a time. + + See the `container.json` schema for details on how it should look, + and the Maya equivalent, which is in `avalon.maya.pipeline` + """ + pass + + +def parse_container(container): + """Return the container node's full container data. + + Args: + container (str): A container node name. + + Returns: + dict: The container schema data for this container node. + + """ + pass + + +def launch_workfiles_app(*args): + workdir = os.environ["AVALON_WORKDIR"] + workfiles.show(workdir) + + +def reload_pipeline(): + """Attempt to reload pipeline at run-time. + + CAUTION: This is primarily for development and debugging purposes. + + """ + + import importlib + import pype.resolve + + avalon.uninstall() + + # get avalon config name + config = os.getenv("AVALON_CONFIG", "pype") + + for module in ("avalon.io", + "avalon.lib", + "avalon.pipeline", + "avalon.api", + "avalon.tools", + + "{}".format(config), + "{}.resolve".format(config), + "{}.resolve.lib".format(config), + "{}.resolve.menu".format(config), + "{}.resolve.plugin".format(config), + "{}.resolve.pipeline".format(config) + ): + log.info("Reloading module: {}...".format(module)) + try: + module = importlib.import_module(module) + importlib.reload(module) + except Exception as e: + log.warning("Cannot reload module: {}".format(e)) + + avalon.install(pype.resolve) + + +def publish(parent): + """Shorthand to publish from within host""" + from avalon.tools import publish + return publish.show(parent) diff --git a/pype/resolve/plugin.py b/pype/resolve/plugin.py new file mode 100644 index 0000000000..a463495af3 --- /dev/null +++ b/pype/resolve/plugin.py @@ -0,0 +1,75 @@ +from avalon import api +from pype.resolve import lib as drlib +from avalon.vendor import qargparse + + +def get_reference_node_parents(ref): + """Return all parent reference nodes of reference node + + Args: + ref (str): reference node. + + Returns: + list: The upstream parent reference nodes. + + """ + parents = [] + return parents + + +class SequenceLoader(api.Loader): + """A basic SequenceLoader for Resolve + + This will implement the basic behavior for a loader to inherit from that + will containerize the reference and will implement the `remove` and + `update` logic. + + """ + + options = [ + qargparse.Toggle( + "handles", + label="Include handles", + default=0, + help="Load with handles or without?" + ), + qargparse.Choice( + "load_to", + label="Where to load clips", + items=[ + "Current timeline", + "New timeline" + ], + default=0, + help="Where do you want clips to be loaded?" + ), + qargparse.Choice( + "load_how", + label="How to load clips", + items=[ + "original timing", + "sequential in order" + ], + default=0, + help="Would you like to place it at orignal timing?" + ) + ] + + def load( + self, + context, + name=None, + namespace=None, + options=None + ): + pass + + def update(self, container, representation): + """Update an existing `container` + """ + pass + + def remove(self, container): + """Remove an existing `container` + """ + pass diff --git a/pype/resolve/preload_console.py b/pype/resolve/preload_console.py new file mode 100644 index 0000000000..7d602df339 --- /dev/null +++ b/pype/resolve/preload_console.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +import time +from pype.resolve.utils import get_resolve_module +from pypeapp import Logger + +log = Logger().get_logger(__name__, "resolve") + +wait_delay = 2.5 +wait = 0.00 +ready = None +while True: + try: + # Create project and set parameters: + resolve = get_resolve_module() + pm = resolve.GetProjectManager() + p = pm.GetCurrentProject() + if p.GetName() == "Untitled Project": + ready = None + else: + ready = True + except AttributeError: + pass + + if ready is None: + time.sleep(wait_delay) + log.info(f"Waiting {wait}s for Resolve to be open in project") + wait += wait_delay + else: + break diff --git a/pype/resolve/resolve_utility_scripts/Pype_menu.py b/pype/resolve/resolve_utility_scripts/Pype_menu.py new file mode 100644 index 0000000000..e9f5d68d70 --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/Pype_menu.py @@ -0,0 +1,34 @@ +import os +import sys +import importlib +import avalon +import pype + +from pypeapp import Logger + +log = Logger().get_logger(__name__) + + +def main(env): + # Registers pype's Global pyblish plugins + pype.install() + + # Register Host (and it's pyblish plugins) + host_name = env["AVALON_APP"] + host_import_str = "pype.resolve" + + try: + host_module = importlib.import_module(host_import_str) + except ModuleNotFoundError: + log.error(( + f"Host \"{host_name}\" can't be imported." + f" Import string \"{host_import_str}\" failed." + )) + return False + + avalon.api.install(host_module) + + +if __name__ == "__main__": + result = main(os.environ) + sys.exit(not bool(result)) diff --git a/pype/resolve/resolve_utility_scripts/README.markdown b/pype/resolve/resolve_utility_scripts/README.markdown new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/README.markdown @@ -0,0 +1 @@ + diff --git a/pype/resolve/resolve_utility_scripts/__test_gui.py b/pype/resolve/resolve_utility_scripts/__test_gui.py new file mode 100644 index 0000000000..2b91732667 --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/__test_gui.py @@ -0,0 +1,111 @@ +#! python3 +# -*- coding: utf-8 -*- + +# DaVinci Resolve scripting proof of concept. Resolve page external switcher. +# Local or TCP/IP control mode. +# Refer to Resolve V15 public beta 2 scripting API documentation for host setup. +# Copyright 2018 Igor Riđanović, www.hdhead.com +from Qt.QtGui import * +from Qt.QtWidgets import * +from Qt.QtCore import * + +import sys + +# If API module not found assume we"re working as a remote control +try: + import DaVinciResolveScript + # Instantiate Resolve object + resolve = DaVinciResolveScript.scriptapp("Resolve") + checkboxState = False +except ImportError: + print("Resolve API not found.") + checkboxState = True + +try: + _encoding = QApplication.UnicodeUTF8 + + def _translate(context, text, disambig): + return QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QApplication.translate(context, text, disambig) + + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName(str("Resolve Page Switcher")) + Form.resize(561, 88) + Form.setStyleSheet(str(( + "background-color: #282828;" + "border-color: #555555;" + "color: #929292;" + "font-size: 13px;" + ))) + self.horizontalLayout = QHBoxLayout(Form) + self.horizontalLayout.setObjectName(str("horizontalLayout")) + self.mediaButton = QPushButton(Form) + self.mediaButton.setObjectName(str("mediaButton")) + self.horizontalLayout.addWidget(self.mediaButton) + self.editButton = QPushButton(Form) + self.editButton.setObjectName(str("editButton")) + self.horizontalLayout.addWidget(self.editButton) + self.fusionButton = QPushButton(Form) + self.fusionButton.setObjectName(str("fusionButton")) + self.horizontalLayout.addWidget(self.fusionButton) + self.colorButton = QPushButton(Form) + self.colorButton.setObjectName(str("colorButton")) + self.horizontalLayout.addWidget(self.colorButton) + self.fairlightButton = QPushButton(Form) + self.fairlightButton.setObjectName(str("fairlightButton")) + self.horizontalLayout.addWidget(self.fairlightButton) + self.deliverButton = QPushButton(Form) + self.deliverButton.setObjectName(str("deliverButton")) + self.horizontalLayout.addWidget(self.deliverButton) + + self.mediaButton.clicked.connect(lambda: self.pageswitch("media")) + self.editButton.clicked.connect(lambda: self.pageswitch("edit")) + self.fusionButton.clicked.connect(lambda: self.pageswitch("fusion")) + self.colorButton.clicked.connect(lambda: self.pageswitch("color")) + self.fairlightButton.clicked.connect( + lambda: self.pageswitch("fairlight")) + self.deliverButton.clicked.connect(lambda: self.pageswitch("deliver")) + + self.mediaButton.setStyleSheet(str("background-color: #181818;")) + self.editButton.setStyleSheet(str("background-color: #181818;")) + self.fusionButton.setStyleSheet( + str("background-color: #181818;")) + self.colorButton.setStyleSheet(str("background-color: #181818;")) + self.fairlightButton.setStyleSheet( + str("background-color: #181818;")) + self.deliverButton.setStyleSheet( + str("background-color: #181818;")) + + self.retranslateUi(Form) + QMetaObject.connectSlotsByName(Form) + + def retranslateUi(self, Form): + Form.setWindowTitle(_translate("Resolve Page Switcher", + "Resolve Page Switcher", None)) + self.mediaButton.setText(_translate("Form", "Media", None)) + self.editButton.setText(_translate("Form", "Edit", None)) + self.fusionButton.setText(_translate("Form", "Fusion", None)) + self.colorButton.setText(_translate("Form", "Color", None)) + self.fairlightButton.setText(_translate("Form", "Fairlight", None)) + self.deliverButton.setText(_translate("Form", "Deliver", None)) + + def pageswitch(self, page): + # Send page name to server to switch remote Resolve"s page + try: + resolve.OpenPage(page) + print(f"Switched to {page}") + except NameError: + print("Resolve API not found. Run in remote mode instead?") + + +if __name__ == "__main__": + app = QApplication(sys.argv) + Form = QWidget() + ui = Ui_Form() + ui.setupUi(Form) + Form.show() + sys.exit(app.exec_()) diff --git a/pype/resolve/resolve_utility_scripts/__test_pyblish.py b/pype/resolve/resolve_utility_scripts/__test_pyblish.py new file mode 100644 index 0000000000..a6fe991025 --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/__test_pyblish.py @@ -0,0 +1,57 @@ +import os +import sys +import pype +import importlib +import pyblish.api +import pyblish.util +import avalon.api +from avalon.tools import publish +from pypeapp import Logger + +log = Logger().get_logger(__name__) + + +def main(env): + # Registers pype's Global pyblish plugins + pype.install() + + # 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"pype.{host_name}" + + try: + host_module = importlib.import_module(host_import_str) + except ModuleNotFoundError: + log.error(( + f"Host \"{host_name}\" can't be imported." + f" Import string \"{host_import_str}\" failed." + )) + return False + + avalon.api.install(host_module) + + # Register additional paths + addition_paths_str = env.get("PUBLISH_PATHS") or "" + addition_paths = addition_paths_str.split(os.pathsep) + for path in addition_paths: + path = os.path.normpath(path) + if not os.path.exists(path): + continue + + pyblish.api.register_plugin_path(path) + + # Register project specific plugins + project_name = os.environ["AVALON_PROJECT"] + project_plugins_paths = env.get("PYPE_PROJECT_PLUGINS") or "" + for path in project_plugins_paths.split(os.pathsep): + plugin_path = os.path.join(path, project_name, "plugins") + if os.path.exists(plugin_path): + pyblish.api.register_plugin_path(plugin_path) + + return publish.show() + + +if __name__ == "__main__": + result = main(os.environ) + sys.exit(not bool(result)) diff --git a/pype/resolve/resolve_utility_scripts/__test_subprocess.py b/pype/resolve/resolve_utility_scripts/__test_subprocess.py new file mode 100644 index 0000000000..438b1f716c --- /dev/null +++ b/pype/resolve/resolve_utility_scripts/__test_subprocess.py @@ -0,0 +1,36 @@ +#! python3 +# -*- coding: utf-8 -*- +import os +import sys +from pypeapp import execute, Logger +from pype.resolve.utils import get_resolve_module + +log = Logger().get_logger("Resolve") + +CURRENT_DIR = os.getenv("RESOLVE_UTILITY_SCRIPTS_DIR", "") +python_dir = os.getenv("PYTHON36_RESOLVE") +python_exe = os.path.normpath( + os.path.join(python_dir, "python.exe") +) + +resolve = get_resolve_module() +PM = resolve.GetProjectManager() +P = PM.GetCurrentProject() + +log.info(P.GetName()) + + +# ______________________________________________________ +# testing subprocessing Scripts +testing_py = os.path.join(CURRENT_DIR, "ResolvePageSwitcher.py") +testing_py = os.path.normpath(testing_py) +log.info(f"Testing path to script: `{testing_py}`") + +returncode = execute( + [python_exe, os.path.normpath(testing_py)], + env=dict(os.environ) +) + +# Check if output file exists +if returncode != 0: + log.error("Executing failed!") diff --git a/pype/resolve/resolve_utility_scripts/python_get_resolve.py b/pype/resolve/resolve_utility_scripts/python_get_resolve.py deleted file mode 100644 index 862a5bb758..0000000000 --- a/pype/resolve/resolve_utility_scripts/python_get_resolve.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python - -""" -This file serves to return a DaVinci Resolve object -""" - -import sys - -def GetResolve(): - try: - # The PYTHONPATH needs to be set correctly for this import statement to work. - # An alternative is to import the DaVinciResolveScript by specifying absolute path (see ExceptionHandler logic) - import DaVinciResolveScript as bmd - except ImportError: - if sys.platform.startswith("darwin"): - expectedPath="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules/" - elif sys.platform.startswith("win") or sys.platform.startswith("cygwin"): - import os - expectedPath=os.getenv('PROGRAMDATA') + "\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\Modules\\" - elif sys.platform.startswith("linux"): - expectedPath="/opt/resolve/libs/Fusion/Modules/" - - # check if the default path has it... - print("Unable to find module DaVinciResolveScript from $PYTHONPATH - trying default locations") - try: - import imp - bmd = imp.load_source('DaVinciResolveScript', expectedPath+"DaVinciResolveScript.py") - except ImportError: - # No fallbacks ... report error: - print("Unable to find module DaVinciResolveScript - please ensure that the module DaVinciResolveScript is discoverable by python") - print("For a default DaVinci Resolve installation, the module is expected to be located in: "+expectedPath) - sys.exit() - - return bmd.scriptapp("Resolve") diff --git a/pype/resolve/resolve_utility_scripts/resolveapitest.py b/pype/resolve/resolve_utility_scripts/resolveapitest.py deleted file mode 100644 index e7cc32a864..0000000000 --- a/pype/resolve/resolve_utility_scripts/resolveapitest.py +++ /dev/null @@ -1,72 +0,0 @@ -#! /usr/bin/env python -# -*- coding: utf-8 -*- - -# This script tests Resolve 15 scripting API on MacOS. -# We suspect an issue with import of fusionscript.so. -# To test launch Resolve Studio first and then run this script. -# The script will save a text report. -# igor@hdhead.com - -from datetime import datetime -import os -import sys -import imp - -eol = '\n' -pathLib = 'C:\\Program Files\\Blackmagic Design\\DaVinci Resolve\\fusionscript.dll' - -reportDir = "C:\\Users\\jezsc" - -# Create initial report file. It will overwrite existing! -reportName = 'Resolve_API_Report.txt' -reportPath = os.path.join(reportDir, reportName) -reportfile = open(reportPath, 'w') -reportfile.close() - - -def report(entry): - # Print to console - print entry - - # Write a report entry - reportfile = open(reportPath, 'a') - reportfile.write(entry) - reportfile.write(eol) - reportfile.close() - - -# These are the values we'll discover and save -report('Time: ' + str(datetime.now())) -report('Python Version: ' + sys.version) -report('Interpreter Path: ' + sys.executable) -report('___________________________________' + eol) - -report('If no lines follow we have likely experienced a Fatal Python Error.') - -try: - # Will the API library import? Does it exist? - smodule = imp.load_dynamic('fusionscript', pathLib) - report('Imported fusionscript.so') - - # It looks like the library imported. Can we create a resolve instance now? - try: - resolve = smodule.scriptapp('Resolve') - if 'None' in str(type(resolve)): - report('Resolve instance is created, but Resolve is not found.') - sys.exit() - if 'PyRemoteObject' in str(type(resolve)): - report('Resolve instance is created and Resolve is responsive.') - except Exception, e: - report(str(e)) - - # Let's go nuts and count how many projects are in the Project Manager - try: - projman = resolve.GetProjectManager() - projects = projman.GetProjectsInCurrentFolder() - report('Project Count: ' + str(len(projects))) - report('All is well!') - except Exception, e: - report(str(e)) - -except Exception, e: - report(str(e)) diff --git a/pype/resolve/resolve_utility_scripts/test.py b/pype/resolve/resolve_utility_scripts/test.py deleted file mode 100644 index 7d32aabfe5..0000000000 --- a/pype/resolve/resolve_utility_scripts/test.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3.6 -from python_get_resolve import GetResolve - -resolve = GetResolve() -PM = resolve.GetProjectManager() -P = PM.GetCurrentProject() - -print(P.GetName()) diff --git a/pype/resolve/utility/pre_python_console_script.py b/pype/resolve/utility/pre_python_console_script.py deleted file mode 100644 index 1c1aceaddd..0000000000 --- a/pype/resolve/utility/pre_python_console_script.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -import time -from python_get_resolve import GetResolve - -wait_delay = 2.5 -wait = 0.00 -ready = None -while True: - try: - # Create project and set parameters: - resolve = GetResolve() - PM = resolve.GetProjectManager() - P = PM.GetCurrentProject() - if P.GetName() == "Untitled Project": - ready = None - else: - ready = True - except AttributeError: - pass - - if ready is None: - time.sleep(wait_delay) - print(f"Waiting {wait}s for Resolve to be open inproject") - wait += wait_delay - else: - break diff --git a/pype/resolve/utility/python_get_resolve.py b/pype/resolve/utility/python_get_resolve.py deleted file mode 100644 index 862a5bb758..0000000000 --- a/pype/resolve/utility/python_get_resolve.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python - -""" -This file serves to return a DaVinci Resolve object -""" - -import sys - -def GetResolve(): - try: - # The PYTHONPATH needs to be set correctly for this import statement to work. - # An alternative is to import the DaVinciResolveScript by specifying absolute path (see ExceptionHandler logic) - import DaVinciResolveScript as bmd - except ImportError: - if sys.platform.startswith("darwin"): - expectedPath="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules/" - elif sys.platform.startswith("win") or sys.platform.startswith("cygwin"): - import os - expectedPath=os.getenv('PROGRAMDATA') + "\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\Modules\\" - elif sys.platform.startswith("linux"): - expectedPath="/opt/resolve/libs/Fusion/Modules/" - - # check if the default path has it... - print("Unable to find module DaVinciResolveScript from $PYTHONPATH - trying default locations") - try: - import imp - bmd = imp.load_source('DaVinciResolveScript', expectedPath+"DaVinciResolveScript.py") - except ImportError: - # No fallbacks ... report error: - print("Unable to find module DaVinciResolveScript - please ensure that the module DaVinciResolveScript is discoverable by python") - print("For a default DaVinci Resolve installation, the module is expected to be located in: "+expectedPath) - sys.exit() - - return bmd.scriptapp("Resolve") diff --git a/pype/resolve/utils.py b/pype/resolve/utils.py new file mode 100644 index 0000000000..e421d02de5 --- /dev/null +++ b/pype/resolve/utils.py @@ -0,0 +1,114 @@ +#! python3 + +""" +Resolve's tools for setting environment +""" + +import sys +import os +import shutil + +from pypeapp import Logger + +log = Logger().get_logger(__name__, "resolve") + +UTILITY_SCRIPTS = os.path.join( + os.path.dirname(__file__), + "resolve_utility_scripts" +) + + +def get_resolve_module(): + try: + """ + The PYTHONPATH needs to be set correctly for this import + statement to work. An alternative is to import the + DaVinciResolveScript by specifying absolute path + (see ExceptionHandler logic) + """ + import DaVinciResolveScript as bmd + except ImportError: + if sys.platform.startswith("darwin"): + expected_path = ("/Library/Application Support/Blackmagic Design" + "/DaVinci Resolve/Developer/Scripting/Modules") + elif sys.platform.startswith("win") \ + or sys.platform.startswith("cygwin"): + expected_path = os.path.normpath( + os.getenv('PROGRAMDATA') + ( + "/Blackmagic Design/DaVinci Resolve/Support/Developer" + "/Scripting/Modules" + ) + ) + elif sys.platform.startswith("linux"): + expected_path = "/opt/resolve/libs/Fusion/Modules" + + # check if the default path has it... + print(("Unable to find module DaVinciResolveScript from " + "$PYTHONPATH - trying default locations")) + + module_path = os.path.normpath( + os.path.join( + expected_path, + "DaVinciResolveScript.py" + ) + ) + + try: + import imp + bmd = imp.load_source('DaVinciResolveScript', module_path) + except ImportError: + # No fallbacks ... report error: + log.error( + ("Unable to find module DaVinciResolveScript - please " + "ensure that the module DaVinciResolveScript is " + "discoverable by python") + ) + log.error( + ("For a default DaVinci Resolve installation, the " + f"module is expected to be located in: {expected_path}") + ) + sys.exit() + + return bmd.scriptapp("Resolve") + + +def _sync_utility_scripts(env=None): + """ Synchronizing basic utlility scripts for resolve. + + To be able to run scripts from inside `Resolve/Workspace/Scripts` menu + all scripts has to be accessible from defined folder. + """ + if not env: + env = os.environ + + us_dir = env.get("RESOLVE_UTILITY_SCRIPTS_DIR", "") + scripts = os.listdir(UTILITY_SCRIPTS) + + log.info(f"Utility Scripts Dir: `{UTILITY_SCRIPTS}`") + log.info(f"Utility Scripts: `{scripts}`") + + # make sure no script file is in folder + if next((s for s in os.listdir(us_dir)), None): + for s in os.listdir(us_dir): + path = os.path.join(us_dir, s) + log.info(f"Removing `{path}`...") + os.remove(path) + + # copy scripts into Resolve's utility scripts dir + for s in scripts: + src = os.path.join(UTILITY_SCRIPTS, s) + dst = os.path.join(us_dir, s) + log.info(f"Copying `{src}` to `{dst}`...") + shutil.copy2(src, dst) + + +def setup(env=None): + """ Wrapper installer started from pype.hooks.resolve.ResolvePrelaunch() + """ + if not env: + env = os.environ + + # synchronize resolve utility scripts + _sync_utility_scripts(env) + + log.info("Resolve Pype wrapper has been installed") diff --git a/pype/resolve/workio.py b/pype/resolve/workio.py new file mode 100644 index 0000000000..49c027259b --- /dev/null +++ b/pype/resolve/workio.py @@ -0,0 +1,88 @@ +"""Host API required Work Files tool""" + +import os +import sys +from pypeapp import Logger +from .utils import get_resolve_module + +log = Logger().get_logger(__name__, "nukestudio") + +exported_projet_ext = ".drp" + +self = sys.modules[__name__] +self.pm = None + + +def get_project_manager(): + if not self.pm: + resolve = get_resolve_module() + self.pm = resolve.GetProjectManager() + return self.pm + + +def file_extensions(): + return [exported_projet_ext] + + +def has_unsaved_changes(): + get_project_manager().SaveProject() + return False + + +def save_file(filepath): + pm = get_project_manager() + file = os.path.basename(filepath) + fname, _ = os.path.splitext(file) + project = pm.GetCurrentProject() + name = project.GetName() + + if "Untitled Project" not in name: + log.info("Saving project: `{}` as '{}'".format(name, file)) + pm.ExportProject(name, filepath) + else: + log.info("Creating new project...") + pm.CreateProject(fname) + pm.ExportProject(name, filepath) + + +def open_file(filepath): + """ + Loading project + """ + pm = get_project_manager() + file = os.path.basename(filepath) + fname, _ = os.path.splitext(file) + + # deal with current project + project = pm.GetCurrentProject() + pm.SaveProject() + pm.CloseProject(project) + + try: + # load project from input path + project = pm.LoadProject(fname) + log.info(f"Project {project.GetName()} opened...") + return True + except NameError as E: + log.error(f"Project with name `{fname}` does not exist!\n\nError: {E}") + return False + + +def current_file(): + pm = get_project_manager() + current_dir = os.getenv("AVALON_WORKDIR") + project = pm.GetCurrentProject() + name = project.GetName() + fname = name + exported_projet_ext + current_file = os.path.join(current_dir, fname) + normalised = os.path.normpath(current_file) + + # Unsaved current file + if normalised == "": + return None + + return normalised + + +def work_root(session): + return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") From 157a9e3498727e569c265eff92b565340f7e832a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 28 May 2020 14:24:51 +0200 Subject: [PATCH 05/40] feat(resolve): integration wip --- pype/hooks/resolve/prelaunch.py | 2 + pype/plugins/resolve/publish/collect_host.py | 4 +- pype/resolve/lib.py | 12 +++++ pype/resolve/menu.py | 30 ++++++++--- pype/resolve/menu_style.qss | 25 ++++----- pype/resolve/pipeline.py | 5 -- pype/resolve/preload_console.py | 3 ++ .../Pype_menu.py | 1 + .../README.markdown | 0 .../__test_gui.py | 0 .../__test_pyblish.py | 0 .../__test_subprocess.py | 0 pype/resolve/utils.py | 51 +++++++++++++------ pype/resolve/workio.py | 14 +---- 14 files changed, 92 insertions(+), 55 deletions(-) rename pype/resolve/{resolve_utility_scripts => utility_scripts}/Pype_menu.py (94%) rename pype/resolve/{resolve_utility_scripts => utility_scripts}/README.markdown (100%) rename pype/resolve/{resolve_utility_scripts => utility_scripts}/__test_gui.py (100%) rename pype/resolve/{resolve_utility_scripts => utility_scripts}/__test_pyblish.py (100%) rename pype/resolve/{resolve_utility_scripts => utility_scripts}/__test_subprocess.py (100%) diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py index d0b7448a41..ccc5e48dfd 100644 --- a/pype/hooks/resolve/prelaunch.py +++ b/pype/hooks/resolve/prelaunch.py @@ -1,5 +1,6 @@ import os import traceback +import importlib from pype.lib import PypeHook from pypeapp import Logger from pype.resolve import utils @@ -60,6 +61,7 @@ class ResolvePrelaunch(PypeHook): else: # Resolve Setup integration + importlib.reload(utils) utils.setup(env) return True diff --git a/pype/plugins/resolve/publish/collect_host.py b/pype/plugins/resolve/publish/collect_host.py index 9119ba1f4f..7579be487c 100644 --- a/pype/plugins/resolve/publish/collect_host.py +++ b/pype/plugins/resolve/publish/collect_host.py @@ -1,5 +1,5 @@ import pyblish.api -from python_get_resolve import GetResolve +from pype.resolve.utils import get_resolve_module class CollectProject(pyblish.api.ContextPlugin): @@ -10,7 +10,7 @@ class CollectProject(pyblish.api.ContextPlugin): hosts = ["resolve"] def process(self, context): - resolve = GetResolve() + resolve = get_resolve_module() PM = resolve.GetProjectManager() P = PM.GetCurrentProject() diff --git a/pype/resolve/lib.py b/pype/resolve/lib.py index e69de29bb2..a6f10a1533 100644 --- a/pype/resolve/lib.py +++ b/pype/resolve/lib.py @@ -0,0 +1,12 @@ +import sys +from .utils import get_resolve_module + +self = sys.modules[__name__] +self.pm = None + + +def get_project_manager(): + if not self.pm: + resolve = get_resolve_module() + self.pm = resolve.GetProjectManager() + return self.pm diff --git a/pype/resolve/menu.py b/pype/resolve/menu.py index 9f45ec9b70..6edf2e8f0c 100644 --- a/pype/resolve/menu.py +++ b/pype/resolve/menu.py @@ -3,6 +3,18 @@ import sys from Qt import QtWidgets, QtCore +from .pipeline import ( + publish, + launch_workfiles_app, + reload_pipeline + ) + +from avalon.tools import ( + creator, + loader, + sceneinventory, + libraryloader +) def load_stylesheet(): path = os.path.join(os.path.dirname(__file__), "menu_style.qss") @@ -23,10 +35,10 @@ class Spacer(QtWidgets.QWidget): real_spacer = QtWidgets.QWidget(self) real_spacer.setObjectName("Spacer") - real_spacer.setFixedHeight(int(height / 3)) + real_spacer.setFixedHeight(height) layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) + layout.setContentsMargins(0, 11, 0, 0) layout.addWidget(real_spacer) self.setLayout(layout) @@ -62,7 +74,7 @@ class PypeMenu(QtWidgets.QWidget): reload_pipeline_btn = QtWidgets.QPushButton("Reload pipeline", self) layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(10, 10, 10, 10) + layout.setContentsMargins(10, 20, 10, 20) layout.addWidget(workfiles_btn) layout.addWidget(create_btn) @@ -70,19 +82,19 @@ class PypeMenu(QtWidgets.QWidget): layout.addWidget(load_btn) layout.addWidget(inventory_btn) - layout.addWidget(Spacer(20, self)) + layout.addWidget(Spacer(11, self)) layout.addWidget(rename_btn) layout.addWidget(set_colorspace_btn) layout.addWidget(reset_resolution_btn) - layout.addWidget(Spacer(20, self)) + layout.addWidget(Spacer(11, self)) layout.addWidget(reload_pipeline_btn) self.setLayout(layout) - workfiles_btn.clicked.connect(self.on_reload_pipeline_clicked) + workfiles_btn.clicked.connect(self.on_workfile_clicked) create_btn.clicked.connect(self.on_create_clicked) publish_btn.clicked.connect(self.on_publish_clicked) load_btn.clicked.connect(self.on_load_clicked) @@ -94,18 +106,23 @@ class PypeMenu(QtWidgets.QWidget): def on_workfile_clicked(self): print("Clicked Workfile") + launch_workfiles_app() def on_create_clicked(self): print("Clicked Create") + creator.show() def on_publish_clicked(self): print("Clicked Publish") + publish(None) def on_load_clicked(self): print("Clicked Load") + loader.show(use_context=True) def on_inventory_clicked(self): print("Clicked Inventory") + sceneinventory.show() def on_rename_clicked(self): print("Clicked Rename") @@ -118,6 +135,7 @@ class PypeMenu(QtWidgets.QWidget): def on_reload_pipeline_clicked(self): print("Clicked Reload Pipeline") + reload_pipeline() def launch_pype_menu(): diff --git a/pype/resolve/menu_style.qss b/pype/resolve/menu_style.qss index 52672364db..b74ed46868 100644 --- a/pype/resolve/menu_style.qss +++ b/pype/resolve/menu_style.qss @@ -1,34 +1,29 @@ QWidget { - background-color: #3a3939; - border-radius: 5; + background-color: #282828; + border-radius: 3; } QPushButton { - border: 1px solid #6d6d6d; + border: 1px solid #090909; background-color: #201f1f; - color: #6d6d6d; + color: #ffffff; padding: 5; } QPushButton:focus { - background-color: "#272525"; -} - -QPushButton:pressed { - background-color: "#686464"; - color: #333333; + background-color: "#171717"; + color: #d0d0d0; } QPushButton:hover { - color: #d0d0d0; - background-color: "#343232"; + background-color: "#171717"; + color: #e64b3d; } #PypeMenu { - border: 1px solid #333333; + border: 1px solid #fef9ef; } #Spacer { - padding: 10; - background-color: #464646; + background-color: #121212; } diff --git a/pype/resolve/pipeline.py b/pype/resolve/pipeline.py index b6cae307b0..377c5ae161 100644 --- a/pype/resolve/pipeline.py +++ b/pype/resolve/pipeline.py @@ -150,8 +150,6 @@ def reload_pipeline(): import importlib import pype.resolve - avalon.uninstall() - # get avalon config name config = os.getenv("AVALON_CONFIG", "pype") @@ -164,7 +162,6 @@ def reload_pipeline(): "{}".format(config), "{}.resolve".format(config), "{}.resolve.lib".format(config), - "{}.resolve.menu".format(config), "{}.resolve.plugin".format(config), "{}.resolve.pipeline".format(config) ): @@ -175,8 +172,6 @@ def reload_pipeline(): except Exception as e: log.warning("Cannot reload module: {}".format(e)) - avalon.install(pype.resolve) - def publish(parent): """Shorthand to publish from within host""" diff --git a/pype/resolve/preload_console.py b/pype/resolve/preload_console.py index 7d602df339..c1b70de11d 100644 --- a/pype/resolve/preload_console.py +++ b/pype/resolve/preload_console.py @@ -26,4 +26,7 @@ while True: log.info(f"Waiting {wait}s for Resolve to be open in project") wait += wait_delay else: + print(f"Preloaded variables: \n\n\tResolve module: " + f"`resolve` > {type(resolve)} \n\tProject manager: " + f"`pm` > {type(pm)} \n\tCurrent project: `p` > {type(p)}") break diff --git a/pype/resolve/resolve_utility_scripts/Pype_menu.py b/pype/resolve/utility_scripts/Pype_menu.py similarity index 94% rename from pype/resolve/resolve_utility_scripts/Pype_menu.py rename to pype/resolve/utility_scripts/Pype_menu.py index e9f5d68d70..10d8d8939d 100644 --- a/pype/resolve/resolve_utility_scripts/Pype_menu.py +++ b/pype/resolve/utility_scripts/Pype_menu.py @@ -27,6 +27,7 @@ def main(env): return False avalon.api.install(host_module) + avalon.api.register_host("resolve") if __name__ == "__main__": diff --git a/pype/resolve/resolve_utility_scripts/README.markdown b/pype/resolve/utility_scripts/README.markdown similarity index 100% rename from pype/resolve/resolve_utility_scripts/README.markdown rename to pype/resolve/utility_scripts/README.markdown diff --git a/pype/resolve/resolve_utility_scripts/__test_gui.py b/pype/resolve/utility_scripts/__test_gui.py similarity index 100% rename from pype/resolve/resolve_utility_scripts/__test_gui.py rename to pype/resolve/utility_scripts/__test_gui.py diff --git a/pype/resolve/resolve_utility_scripts/__test_pyblish.py b/pype/resolve/utility_scripts/__test_pyblish.py similarity index 100% rename from pype/resolve/resolve_utility_scripts/__test_pyblish.py rename to pype/resolve/utility_scripts/__test_pyblish.py diff --git a/pype/resolve/resolve_utility_scripts/__test_subprocess.py b/pype/resolve/utility_scripts/__test_subprocess.py similarity index 100% rename from pype/resolve/resolve_utility_scripts/__test_subprocess.py rename to pype/resolve/utility_scripts/__test_subprocess.py diff --git a/pype/resolve/utils.py b/pype/resolve/utils.py index e421d02de5..252a43da8d 100644 --- a/pype/resolve/utils.py +++ b/pype/resolve/utils.py @@ -12,13 +12,14 @@ from pypeapp import Logger log = Logger().get_logger(__name__, "resolve") -UTILITY_SCRIPTS = os.path.join( - os.path.dirname(__file__), - "resolve_utility_scripts" -) - +self = sys.modules[__name__] +self.bmd = None def get_resolve_module(): + # dont run if already loaded + if self.bmd: + return self.bmd + try: """ The PYTHONPATH needs to be set correctly for this import @@ -52,7 +53,7 @@ def get_resolve_module(): "DaVinciResolveScript.py" ) ) - + try: import imp bmd = imp.load_source('DaVinciResolveScript', module_path) @@ -68,8 +69,9 @@ def get_resolve_module(): f"module is expected to be located in: {expected_path}") ) sys.exit() - - return bmd.scriptapp("Resolve") + # assign global var and return + self.bmd = bmd.scriptapp("Resolve") + return self.bmd def _sync_utility_scripts(env=None): @@ -81,10 +83,26 @@ def _sync_utility_scripts(env=None): if not env: env = os.environ + # initiate inputs + scripts = {} + us_env = env.get("RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR") us_dir = env.get("RESOLVE_UTILITY_SCRIPTS_DIR", "") - scripts = os.listdir(UTILITY_SCRIPTS) + us_paths = [os.path.join( + os.path.dirname(__file__), + "utility_scripts" + )] - log.info(f"Utility Scripts Dir: `{UTILITY_SCRIPTS}`") + # collect script dirs + if us_env: + log.info(f"Utility Scripts Env: `{us_env}`") + us_paths = us_env.split( + os.pathsep) + us_paths + + # collect scripts from dirs + for path in us_paths: + scripts.update({path: os.listdir(path)}) + + log.info(f"Utility Scripts Dir: `{us_paths}`") log.info(f"Utility Scripts: `{scripts}`") # make sure no script file is in folder @@ -95,11 +113,14 @@ def _sync_utility_scripts(env=None): os.remove(path) # copy scripts into Resolve's utility scripts dir - for s in scripts: - src = os.path.join(UTILITY_SCRIPTS, s) - dst = os.path.join(us_dir, s) - log.info(f"Copying `{src}` to `{dst}`...") - shutil.copy2(src, dst) + for d, sl in scripts.items(): + # directory and scripts list + for s in sl: + # script in script list + src = os.path.join(d, s) + dst = os.path.join(us_dir, s) + log.info(f"Copying `{src}` to `{dst}`...") + shutil.copy2(src, dst) def setup(env=None): diff --git a/pype/resolve/workio.py b/pype/resolve/workio.py index 49c027259b..b9562449bf 100644 --- a/pype/resolve/workio.py +++ b/pype/resolve/workio.py @@ -1,24 +1,14 @@ """Host API required Work Files tool""" import os -import sys from pypeapp import Logger -from .utils import get_resolve_module +from .lib import get_project_manager + log = Logger().get_logger(__name__, "nukestudio") exported_projet_ext = ".drp" -self = sys.modules[__name__] -self.pm = None - - -def get_project_manager(): - if not self.pm: - resolve = get_resolve_module() - self.pm = resolve.GetProjectManager() - return self.pm - def file_extensions(): return [exported_projet_ext] From 1e6e6fd7c338161e0e3e761093f0a20df1a90140 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 May 2020 12:32:33 +0200 Subject: [PATCH 06/40] clean(resolve): print outs too long --- pype/hooks/resolve/prelaunch.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py index ccc5e48dfd..6f5c22a7d0 100644 --- a/pype/hooks/resolve/prelaunch.py +++ b/pype/hooks/resolve/prelaunch.py @@ -31,9 +31,9 @@ class ResolvePrelaunch(PypeHook): py36_dir = os.path.normpath(env.get("PYTHON36_RESOLVE", "")) assert os.path.isdir(py36_dir), ( "Python 3.6 is not installed at the provided folder path. Either " - "make sure the `environments\resolve.json` is having correctly set " - "`PYTHON36_RESOLVE` or make sure Python 3.6 is installed in given path." - f"\nPYTHON36_RESOLVE: `{py36_dir}`" + "make sure the `environments\resolve.json` is having correctly " + "set `PYTHON36_RESOLVE` or make sure Python 3.6 is installed " + f"in given path. \nPYTHON36_RESOLVE: `{py36_dir}`" ) self.log.info(f"Path to Resolve Python folder: `{py36_dir}`...") env["PYTHON36_RESOLVE"] = py36_dir From d0aa618f1abc55c452f3a21f030e7f7822ad78b1 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 May 2020 13:11:42 +0200 Subject: [PATCH 07/40] feat(resolve): integration wip --- pype/resolve/__init__.py | 13 +- pype/resolve/action.py | 1 + pype/resolve/menu.py | 33 +++--- pype/resolve/menu_style.qss | 2 +- pype/resolve/pipeline.py | 39 +----- pype/resolve/plugin.py | 2 +- pype/resolve/utility_scripts/Pype_menu.py | 22 +--- pype/resolve/utility_scripts/__test_gui.py | 111 ------------------ .../utility_scripts/__test_subprocess.py | 1 - pype/resolve/utils.py | 1 + 10 files changed, 38 insertions(+), 187 deletions(-) delete mode 100644 pype/resolve/utility_scripts/__test_gui.py diff --git a/pype/resolve/__init__.py b/pype/resolve/__init__.py index 966d7aef4c..ea5946381c 100644 --- a/pype/resolve/__init__.py +++ b/pype/resolve/__init__.py @@ -3,7 +3,6 @@ from .pipeline import ( uninstall, ls, containerise, - reload_pipeline, publish, launch_workfiles_app ) @@ -22,9 +21,11 @@ from .workio import ( work_root ) -# from .lib import ( -# -# ) +from .lib import ( + get_project_manager +) + +from .menu import launch_pype_menu __all__ = [ "install", @@ -38,6 +39,10 @@ __all__ = [ "setup", "get_resolve_module", + "get_project_manager" + + "launch_pype_menu", + "open_file", "save_file", "current_file", diff --git a/pype/resolve/action.py b/pype/resolve/action.py index 94d0f5eb67..dfbe23087c 100644 --- a/pype/resolve/action.py +++ b/pype/resolve/action.py @@ -23,6 +23,7 @@ class SelectInvalidAction(pyblish.api.Action): try: from pype.resolve.utils import get_resolve_module resolve = get_resolve_module() + self.log.debug(resolve) except ImportError: raise ImportError("Current host is not Resolve") diff --git a/pype/resolve/menu.py b/pype/resolve/menu.py index 6edf2e8f0c..73ea937513 100644 --- a/pype/resolve/menu.py +++ b/pype/resolve/menu.py @@ -5,9 +5,8 @@ from Qt import QtWidgets, QtCore from .pipeline import ( publish, - launch_workfiles_app, - reload_pipeline - ) + launch_workfiles_app +) from avalon.tools import ( creator, @@ -16,6 +15,7 @@ from avalon.tools import ( libraryloader ) + def load_stylesheet(): path = os.path.join(os.path.dirname(__file__), "menu_style.qss") if not os.path.exists(path): @@ -38,7 +38,7 @@ class Spacer(QtWidgets.QWidget): real_spacer.setFixedHeight(height) layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 11, 0, 0) + layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(real_spacer) self.setLayout(layout) @@ -64,6 +64,7 @@ class PypeMenu(QtWidgets.QWidget): publish_btn = QtWidgets.QPushButton("Publish", self) load_btn = QtWidgets.QPushButton("Load", self) inventory_btn = QtWidgets.QPushButton("Inventory", self) + libload_btn = QtWidgets.QPushButton("Library", self) rename_btn = QtWidgets.QPushButton("Rename", self) set_colorspace_btn = QtWidgets.QPushButton( "Set colorspace from presets", self @@ -71,7 +72,6 @@ class PypeMenu(QtWidgets.QWidget): reset_resolution_btn = QtWidgets.QPushButton( "Reset Resolution from peresets", self ) - reload_pipeline_btn = QtWidgets.QPushButton("Reload pipeline", self) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(10, 20, 10, 20) @@ -82,16 +82,19 @@ class PypeMenu(QtWidgets.QWidget): layout.addWidget(load_btn) layout.addWidget(inventory_btn) - layout.addWidget(Spacer(11, self)) + layout.addWidget(Spacer(15, self)) + + layout.addWidget(libload_btn) + + layout.addWidget(Spacer(15, self)) layout.addWidget(rename_btn) + + layout.addWidget(Spacer(15, self)) + layout.addWidget(set_colorspace_btn) layout.addWidget(reset_resolution_btn) - layout.addWidget(Spacer(11, self)) - - layout.addWidget(reload_pipeline_btn) - self.setLayout(layout) workfiles_btn.clicked.connect(self.on_workfile_clicked) @@ -99,10 +102,10 @@ class PypeMenu(QtWidgets.QWidget): publish_btn.clicked.connect(self.on_publish_clicked) load_btn.clicked.connect(self.on_load_clicked) inventory_btn.clicked.connect(self.on_inventory_clicked) + libload_btn.clicked.connect(self.on_libload_clicked) rename_btn.clicked.connect(self.on_rename_clicked) set_colorspace_btn.clicked.connect(self.on_set_colorspace_clicked) reset_resolution_btn.clicked.connect(self.on_reset_resolution_clicked) - reload_pipeline_btn.clicked.connect(self.on_reload_pipeline_clicked) def on_workfile_clicked(self): print("Clicked Workfile") @@ -124,6 +127,10 @@ class PypeMenu(QtWidgets.QWidget): print("Clicked Inventory") sceneinventory.show() + def on_libload_clicked(self): + print("Clicked Library") + libraryloader.show() + def on_rename_clicked(self): print("Clicked Rename") @@ -133,10 +140,6 @@ class PypeMenu(QtWidgets.QWidget): def on_reset_resolution_clicked(self): print("Clicked Reset Resolution") - def on_reload_pipeline_clicked(self): - print("Clicked Reload Pipeline") - reload_pipeline() - def launch_pype_menu(): app = QtWidgets.QApplication(sys.argv) diff --git a/pype/resolve/menu_style.qss b/pype/resolve/menu_style.qss index b74ed46868..df4fd7e949 100644 --- a/pype/resolve/menu_style.qss +++ b/pype/resolve/menu_style.qss @@ -25,5 +25,5 @@ QPushButton:hover { } #Spacer { - background-color: #121212; + background-color: #282828; } diff --git a/pype/resolve/pipeline.py b/pype/resolve/pipeline.py index 377c5ae161..7b7829a8a8 100644 --- a/pype/resolve/pipeline.py +++ b/pype/resolve/pipeline.py @@ -2,7 +2,7 @@ Basic avalon integration """ import os -import sys +# import sys from avalon.tools import workfiles from avalon import api as avalon from pyblish import api as pyblish @@ -40,7 +40,6 @@ def install(): See the Maya equivalent for inspiration on how to implement this. """ - from .menu import launch_pype_menu # Disable all families except for the ones we explicitly want to see family_states = [ @@ -60,9 +59,6 @@ def install(): avalon.register_plugin_path(avalon.Creator, CREATE_PATH) avalon.register_plugin_path(avalon.InventoryAction, INVENTORY_PATH) - # opening menu - launch_pype_menu() - def uninstall(): """Uninstall all tha was installed @@ -140,39 +136,6 @@ def launch_workfiles_app(*args): workfiles.show(workdir) -def reload_pipeline(): - """Attempt to reload pipeline at run-time. - - CAUTION: This is primarily for development and debugging purposes. - - """ - - import importlib - import pype.resolve - - # get avalon config name - config = os.getenv("AVALON_CONFIG", "pype") - - for module in ("avalon.io", - "avalon.lib", - "avalon.pipeline", - "avalon.api", - "avalon.tools", - - "{}".format(config), - "{}.resolve".format(config), - "{}.resolve.lib".format(config), - "{}.resolve.plugin".format(config), - "{}.resolve.pipeline".format(config) - ): - log.info("Reloading module: {}...".format(module)) - try: - module = importlib.import_module(module) - importlib.reload(module) - except Exception as e: - log.warning("Cannot reload module: {}".format(e)) - - def publish(parent): """Shorthand to publish from within host""" from avalon.tools import publish diff --git a/pype/resolve/plugin.py b/pype/resolve/plugin.py index a463495af3..610fc6bcfe 100644 --- a/pype/resolve/plugin.py +++ b/pype/resolve/plugin.py @@ -1,5 +1,5 @@ from avalon import api -from pype.resolve import lib as drlib +# from pype.resolve import lib as drlib from avalon.vendor import qargparse diff --git a/pype/resolve/utility_scripts/Pype_menu.py b/pype/resolve/utility_scripts/Pype_menu.py index 10d8d8939d..c7066930d5 100644 --- a/pype/resolve/utility_scripts/Pype_menu.py +++ b/pype/resolve/utility_scripts/Pype_menu.py @@ -1,7 +1,6 @@ import os import sys -import importlib -import avalon +import avalon.api as avalon import pype from pypeapp import Logger @@ -10,25 +9,16 @@ log = Logger().get_logger(__name__) def main(env): + import pype.resolve as bmdvr # Registers pype's Global pyblish plugins pype.install() - # Register Host (and it's pyblish plugins) - host_name = env["AVALON_APP"] - host_import_str = "pype.resolve" + # activate resolve from pype + avalon.install(bmdvr) - try: - host_module = importlib.import_module(host_import_str) - except ModuleNotFoundError: - log.error(( - f"Host \"{host_name}\" can't be imported." - f" Import string \"{host_import_str}\" failed." - )) - return False - - avalon.api.install(host_module) - avalon.api.register_host("resolve") + log.info(f"Avalon registred hosts: {avalon.registered_host()}") + bmdvr.launch_pype_menu() if __name__ == "__main__": result = main(os.environ) diff --git a/pype/resolve/utility_scripts/__test_gui.py b/pype/resolve/utility_scripts/__test_gui.py deleted file mode 100644 index 2b91732667..0000000000 --- a/pype/resolve/utility_scripts/__test_gui.py +++ /dev/null @@ -1,111 +0,0 @@ -#! python3 -# -*- coding: utf-8 -*- - -# DaVinci Resolve scripting proof of concept. Resolve page external switcher. -# Local or TCP/IP control mode. -# Refer to Resolve V15 public beta 2 scripting API documentation for host setup. -# Copyright 2018 Igor Riđanović, www.hdhead.com -from Qt.QtGui import * -from Qt.QtWidgets import * -from Qt.QtCore import * - -import sys - -# If API module not found assume we"re working as a remote control -try: - import DaVinciResolveScript - # Instantiate Resolve object - resolve = DaVinciResolveScript.scriptapp("Resolve") - checkboxState = False -except ImportError: - print("Resolve API not found.") - checkboxState = True - -try: - _encoding = QApplication.UnicodeUTF8 - - def _translate(context, text, disambig): - return QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def _translate(context, text, disambig): - return QApplication.translate(context, text, disambig) - - -class Ui_Form(object): - def setupUi(self, Form): - Form.setObjectName(str("Resolve Page Switcher")) - Form.resize(561, 88) - Form.setStyleSheet(str(( - "background-color: #282828;" - "border-color: #555555;" - "color: #929292;" - "font-size: 13px;" - ))) - self.horizontalLayout = QHBoxLayout(Form) - self.horizontalLayout.setObjectName(str("horizontalLayout")) - self.mediaButton = QPushButton(Form) - self.mediaButton.setObjectName(str("mediaButton")) - self.horizontalLayout.addWidget(self.mediaButton) - self.editButton = QPushButton(Form) - self.editButton.setObjectName(str("editButton")) - self.horizontalLayout.addWidget(self.editButton) - self.fusionButton = QPushButton(Form) - self.fusionButton.setObjectName(str("fusionButton")) - self.horizontalLayout.addWidget(self.fusionButton) - self.colorButton = QPushButton(Form) - self.colorButton.setObjectName(str("colorButton")) - self.horizontalLayout.addWidget(self.colorButton) - self.fairlightButton = QPushButton(Form) - self.fairlightButton.setObjectName(str("fairlightButton")) - self.horizontalLayout.addWidget(self.fairlightButton) - self.deliverButton = QPushButton(Form) - self.deliverButton.setObjectName(str("deliverButton")) - self.horizontalLayout.addWidget(self.deliverButton) - - self.mediaButton.clicked.connect(lambda: self.pageswitch("media")) - self.editButton.clicked.connect(lambda: self.pageswitch("edit")) - self.fusionButton.clicked.connect(lambda: self.pageswitch("fusion")) - self.colorButton.clicked.connect(lambda: self.pageswitch("color")) - self.fairlightButton.clicked.connect( - lambda: self.pageswitch("fairlight")) - self.deliverButton.clicked.connect(lambda: self.pageswitch("deliver")) - - self.mediaButton.setStyleSheet(str("background-color: #181818;")) - self.editButton.setStyleSheet(str("background-color: #181818;")) - self.fusionButton.setStyleSheet( - str("background-color: #181818;")) - self.colorButton.setStyleSheet(str("background-color: #181818;")) - self.fairlightButton.setStyleSheet( - str("background-color: #181818;")) - self.deliverButton.setStyleSheet( - str("background-color: #181818;")) - - self.retranslateUi(Form) - QMetaObject.connectSlotsByName(Form) - - def retranslateUi(self, Form): - Form.setWindowTitle(_translate("Resolve Page Switcher", - "Resolve Page Switcher", None)) - self.mediaButton.setText(_translate("Form", "Media", None)) - self.editButton.setText(_translate("Form", "Edit", None)) - self.fusionButton.setText(_translate("Form", "Fusion", None)) - self.colorButton.setText(_translate("Form", "Color", None)) - self.fairlightButton.setText(_translate("Form", "Fairlight", None)) - self.deliverButton.setText(_translate("Form", "Deliver", None)) - - def pageswitch(self, page): - # Send page name to server to switch remote Resolve"s page - try: - resolve.OpenPage(page) - print(f"Switched to {page}") - except NameError: - print("Resolve API not found. Run in remote mode instead?") - - -if __name__ == "__main__": - app = QApplication(sys.argv) - Form = QWidget() - ui = Ui_Form() - ui.setupUi(Form) - Form.show() - sys.exit(app.exec_()) diff --git a/pype/resolve/utility_scripts/__test_subprocess.py b/pype/resolve/utility_scripts/__test_subprocess.py index 438b1f716c..30613feb22 100644 --- a/pype/resolve/utility_scripts/__test_subprocess.py +++ b/pype/resolve/utility_scripts/__test_subprocess.py @@ -1,7 +1,6 @@ #! python3 # -*- coding: utf-8 -*- import os -import sys from pypeapp import execute, Logger from pype.resolve.utils import get_resolve_module diff --git a/pype/resolve/utils.py b/pype/resolve/utils.py index 252a43da8d..f5add53a6b 100644 --- a/pype/resolve/utils.py +++ b/pype/resolve/utils.py @@ -15,6 +15,7 @@ log = Logger().get_logger(__name__, "resolve") self = sys.modules[__name__] self.bmd = None + def get_resolve_module(): # dont run if already loaded if self.bmd: From e0166d0e395eff1c1a4ef285a9a6df41562749ea Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 May 2020 13:14:38 +0200 Subject: [PATCH 08/40] clean(resolve): hound suggestions --- pype/resolve/__init__.py | 7 ++++++- pype/resolve/utility_scripts/Pype_menu.py | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/resolve/__init__.py b/pype/resolve/__init__.py index ea5946381c..70163718c1 100644 --- a/pype/resolve/__init__.py +++ b/pype/resolve/__init__.py @@ -28,6 +28,7 @@ from .lib import ( from .menu import launch_pype_menu __all__ = [ + # pipeline "install", "uninstall", "ls", @@ -36,13 +37,17 @@ __all__ = [ "publish", "launch_workfiles_app", + # utils "setup", "get_resolve_module", - "get_project_manager" + # lib + "get_project_manager", + # menu "launch_pype_menu", + # workio "open_file", "save_file", "current_file", diff --git a/pype/resolve/utility_scripts/Pype_menu.py b/pype/resolve/utility_scripts/Pype_menu.py index c7066930d5..5c68fb431b 100644 --- a/pype/resolve/utility_scripts/Pype_menu.py +++ b/pype/resolve/utility_scripts/Pype_menu.py @@ -20,6 +20,7 @@ def main(env): bmdvr.launch_pype_menu() + if __name__ == "__main__": result = main(os.environ) sys.exit(not bool(result)) From c5213d3fba6f878a48478398de07c8927845d7e9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 May 2020 14:39:50 +0200 Subject: [PATCH 09/40] feat(resolve): adding official api readme --- pype/resolve/RESOLVE_API_README.txt | 189 ++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 pype/resolve/RESOLVE_API_README.txt diff --git a/pype/resolve/RESOLVE_API_README.txt b/pype/resolve/RESOLVE_API_README.txt new file mode 100644 index 0000000000..139b66bc24 --- /dev/null +++ b/pype/resolve/RESOLVE_API_README.txt @@ -0,0 +1,189 @@ +Updated as of 08 March 2019 + +-------------------------- +In this package, you will find a brief introduction to the Scripting API for DaVinci Resolve Studio. Apart from this README.txt file, this package contains folders containing the basic import modules for scripting access (DaVinciResolve.py) and some representative examples. + +Overview +-------- + +As with Blackmagic Design Fusion scripts, user scripts written in Lua and Python programming languages are supported. By default, scripts can be invoked from the Console window in the Fusion page, or via command line. This permission can be changed in Resolve Preferences, to be only from Console, or to be invoked from the local network. Please be aware of the security implications when allowing scripting access from outside of the Resolve application. + + +Using a script +-------------- +DaVinci Resolve needs to be running for a script to be invoked. + +For a Resolve script to be executed from an external folder, the script needs to know of the API location. +You may need to set the these environment variables to allow for your Python installation to pick up the appropriate dependencies as shown below: + + Mac OS X: + RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/" + RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so" + PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/" + + Windows: + RESOLVE_SCRIPT_API="%PROGRAMDATA%\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\" + RESOLVE_SCRIPT_LIB="C:\\Program Files\\Blackmagic Design\\DaVinci Resolve\\fusionscript.dll" + PYTHONPATH="%PYTHONPATH%;%RESOLVE_SCRIPT_API%\\Modules\\" + + Linux: + RESOLVE_SCRIPT_API="/opt/resolve/Developer/Scripting/" + RESOLVE_SCRIPT_LIB="/opt/resolve/libs/Fusion/fusionscript.so" + PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/" + (Note: For standard ISO Linux installations, the path above may need to be modified to refer to /home/resolve instead of /opt/resolve) + +As with Fusion scripts, Resolve scripts can also be invoked via the menu and the Console. + +On startup, DaVinci Resolve scans the Utility Scripts directory and enumerates the scripts found in the Script application menu. Placing your script in this folder and invoking it from this menu is the easiest way to use scripts. The Utility Scripts folder is located in: + Mac OS X: /Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Comp/ + Windows: %APPDATA%\Blackmagic Design\DaVinci Resolve\Fusion\Scripts\Comp\ + Linux: /opt/resolve/Fusion/Scripts/Comp/ (or /home/resolve/Fusion/Scripts/Comp/ depending on installation) + +The interactive Console window allows for an easy way to execute simple scripting commands, to query or modify properties, and to test scripts. The console accepts commands in Python 2.7, Python 3.6 and Lua and evaluates and executes them immediately. For more information on how to use the Console, please refer to the DaVinci Resolve User Manual. + +This example Python script creates a simple project: + #!/usr/bin/env python + import DaVinciResolveScript as dvr_script + resolve = dvr_script.scriptapp("Resolve") + fusion = resolve.Fusion() + projectManager = resolve.GetProjectManager() + projectManager.CreateProject("Hello World") + +The resolve object is the fundamental starting point for scripting via Resolve. As a native object, it can be inspected for further scriptable properties - using table iteration and `getmetatable` in Lua and dir, help etc in Python (among other methods). A notable scriptable object above is fusion - it allows access to all existing Fusion scripting functionality. + +Running DaVinci Resolve in headless mode +---------------------------------------- + +DaVinci Resolve can be launched in a headless mode without the user interface using the -nogui command line option. When DaVinci Resolve is launched using this option, the user interface is disabled. However, the various scripting APIs will continue to work as expected. + +Basic Resolve API +----------------- + +Some commonly used API functions are described below (*). As with the resolve object, each object is inspectable for properties and functions. + + +Resolve + Fusion() --> Fusion # Returns the Fusion object. Starting point for Fusion scripts. + GetMediaStorage() --> MediaStorage # Returns media storage object to query and act on media locations. + GetProjectManager() --> ProjectManager # Returns project manager object for currently open database. + OpenPage(pageName) --> None # Switches to indicated page in DaVinci Resolve. Input can be one of ("media", "edit", "fusion", "color", "fairlight", "deliver"). +ProjectManager + CreateProject(projectName) --> Project # Creates and returns a project if projectName (text) is unique, and None if it is not. + LoadProject(projectName) --> Project # Loads and returns the project with name = projectName (text) if there is a match found, and None if there is no matching Project. + GetCurrentProject() --> Project # Returns the currently loaded Resolve project. + SaveProject() --> Bool # Saves the currently loaded project with its own name. Returns True if successful. + CreateFolder(folderName) --> Bool # Creates a folder if folderName (text) is unique. + GetProjectsInCurrentFolder() --> [project names...] # Returns an array of project names in current folder. + GetFoldersInCurrentFolder() --> [folder names...] # Returns an array of folder names in current folder. + GotoRootFolder() --> Bool # Opens root folder in database. + GotoParentFolder() --> Bool # Opens parent folder of current folder in database if current folder has parent. + OpenFolder(folderName) --> Bool # Opens folder under given name. + ImportProject(filePath) --> Bool # Imports a project under given file path. Returns true in case of success. + ExportProject(projectName, filePath) --> Bool # Exports a project based on given name into provided file path. Returns true in case of success. + RestoreProject(filePath) --> Bool # Restores a project under given backup file path. Returns true in case of success. +Project + GetMediaPool() --> MediaPool # Returns the Media Pool object. + GetTimelineCount() --> int # Returns the number of timelines currently present in the project. + GetTimelineByIndex(idx) --> Timeline # Returns timeline at the given index, 1 <= idx <= project.GetTimelineCount() + GetCurrentTimeline() --> Timeline # Returns the currently loaded timeline. + SetCurrentTimeline(timeline) --> Bool # Sets given timeline as current timeline for the project. Returns True if successful. + GetName() --> string # Returns project name. + SetName(projectName) --> Bool # Sets project name if given projectname (text) is unique. + GetPresets() --> [presets...] # Returns a table of presets and their information. + SetPreset(presetName) --> Bool # Sets preset by given presetName (string) into project. + GetRenderJobs() --> [render jobs...] # Returns a table of render jobs and their information. + GetRenderPresets() --> [presets...] # Returns a table of render presets and their information. + StartRendering(index1, index2, ...) --> Bool # Starts rendering for given render jobs based on their indices. If no parameter is given rendering would start for all render jobs. + StartRendering([idxs...]) --> Bool # Starts rendering for given render jobs based on their indices. If no parameter is given rendering would start for all render jobs. + StopRendering() --> None # Stops rendering for all render jobs. + IsRenderingInProgress() --> Bool # Returns true is rendering is in progress. + AddRenderJob() --> Bool # Adds render job to render queue. + DeleteRenderJobByIndex(idx) --> Bool # Deletes render job based on given job index (int). + DeleteAllRenderJobs() --> Bool # Deletes all render jobs. + LoadRenderPreset(presetName) --> Bool # Sets a preset as current preset for rendering if presetName (text) exists. + SaveAsNewRenderPreset(presetName) --> Bool # Creates a new render preset by given name if presetName(text) is unique. + SetRenderSettings([settings map]) --> Bool # Sets given settings for rendering. Settings map is a map, keys of map are: "SelectAllFrames", "MarkIn", "MarkOut", "TargetDir", "CustomName". + GetRenderJobStatus(idx) --> [status info] # Returns job status and completion rendering percentage of the job by given job index (int). + GetSetting(settingName) --> string # Returns setting value by given settingName (string) if the setting exist. With empty settingName the function returns a full list of settings. + SetSetting(settingName, settingValue) --> Bool # Sets project setting base on given name (string) and value (string). + GetRenderFormats() --> [render formats...]# Returns a list of available render formats. + GetRenderCodecs(renderFormat) --> [render codecs...] # Returns a list of available codecs for given render format (string). + GetCurrentRenderFormatAndCodec() --> [format, codec] # Returns currently selected render format and render codec. + SetCurrentRenderFormatAndCodec(format, codec) --> Bool # Sets given render format (string) and render codec (string) as options for rendering. +MediaStorage + GetMountedVolumes() --> [paths...] # Returns an array of folder paths corresponding to mounted volumes displayed in Resolve’s Media Storage. + GetSubFolders(folderPath) --> [paths...] # Returns an array of folder paths in the given absolute folder path. + GetFiles(folderPath) --> [paths...] # Returns an array of media and file listings in the given absolute folder path. Note that media listings may be logically consolidated entries. + RevealInStorage(path) --> None # Expands and displays a given file/folder path in Resolve’s Media Storage. + AddItemsToMediaPool(item1, item2, ...) --> [clips...] # Adds specified file/folder paths from Media Store into current Media Pool folder. Input is one or more file/folder paths. + AddItemsToMediaPool([items...]) --> [clips...] # Adds specified file/folder paths from Media Store into current Media Pool folder. Input is an array of file/folder paths. +MediaPool + GetRootFolder() --> Folder # Returns the root Folder of Media Pool + AddSubFolder(folder, name) --> Folder # Adds a new subfolder under specified Folder object with the given name. + CreateEmptyTimeline(name) --> Timeline # Adds a new timeline with given name. + AppendToTimeline(clip1, clip2...) --> Bool # Appends specified MediaPoolItem objects in the current timeline. Returns True if successful. + AppendToTimeline([clips]) --> Bool # Appends specified MediaPoolItem objects in the current timeline. Returns True if successful. + CreateTimelineFromClips(name, clip1, clip2, ...)--> Timeline # Creates a new timeline with specified name, and appends the specified MediaPoolItem objects. + CreateTimelineFromClips(name, [clips]) --> Timeline # Creates a new timeline with specified name, and appends the specified MediaPoolItem objects. + ImportTimelineFromFile(filePath) --> Timeline # Creates timeline based on parameters within given file. + GetCurrentFolder() --> Folder # Returns currently selected Folder. + SetCurrentFolder(Folder) --> Bool # Sets current folder by given Folder. +Folder + GetClips() --> [clips...] # Returns a list of clips (items) within the folder. + GetName() --> string # Returns user-defined name of the folder. + GetSubFolders() --> [folders...] # Returns a list of subfolders in the folder. +MediaPoolItem + GetMetadata(metadataType) --> [[types],[values]] # Returns a value of metadataType. If parameter is not specified returns all set metadata parameters. + SetMetadata(metadataType, metadataValue) --> Bool # Sets metadata by given type and value. Returns True if successful. + GetMediaId() --> string # Returns a unique ID name related to MediaPoolItem. + AddMarker(frameId, color, name, note, duration) --> Bool # Creates a new marker at given frameId position and with given marker information. + GetMarkers() --> [markers...] # Returns a list of all markers and their information. + AddFlag(color) --> Bool # Adds a flag with given color (text). + GetFlags() --> [colors...] # Returns a list of flag colors assigned to the item. + GetClipColor() --> string # Returns an item color as a string. + GetClipProperty(propertyName) --> [[types],[values]] # Returns property value related to the item based on given propertyName (string). if propertyName is empty then it returns a full list of properties. + SetClipProperty(propertyName, propertyValue) --> Bool # Sets into given propertyName (string) propertyValue (string). +Timeline + GetName() --> string # Returns user-defined name of the timeline. + SetName(timelineName) --> Bool # Sets timeline name is timelineName (text) is unique. + GetStartFrame() --> int # Returns frame number at the start of timeline. + GetEndFrame() --> int # Returns frame number at the end of timeline. + GetTrackCount(trackType) --> int # Returns a number of track based on specified track type ("audio", "video" or "subtitle"). + GetItemsInTrack(trackType, index) --> [items...] # Returns an array of Timeline items on the video or audio track (based on trackType) at specified index. 1 <= index <= GetTrackCount(trackType). + AddMarker(frameId, color, name, note, duration) --> Bool # Creates a new marker at given frameId position and with given marker information. + GetMarkers() --> [markers...] # Returns a list of all markers and their information. + ApplyGradeFromDRX(path, gradeMode, item1, item2, ...)--> Bool # Loads a still from given file path (string) and applies grade to Timeline Items with gradeMode (int): 0 - "No keyframes", 1 - "Source Timecode aligned", 2 - "Start Frames aligned". + ApplyGradeFromDRX(path, gradeMode, [items]) --> Bool # Loads a still from given file path (string) and applies grade to Timeline Items with gradeMode (int): 0 - "No keyframes", 1 - "Source Timecode aligned", 2 - "Start Frames aligned". + GetCurrentTimecode() --> string # Returns a string representing a timecode for current position of the timeline, while on Cut, Edit, Color and Deliver page. + GetCurrentVideoItem() --> item # Returns current video timeline item. + GetCurrentClipThumbnailImage() --> [width, height, format, data] # Returns raw thumbnail image data (This image data is encoded in base 64 format and the image format is RGB 8 bit) for the current media in the Color Page in the format of dictionary (in Python) and table (in Lua). Information return are "width", "height", "format" and "data". Example is provided in 6_get_current_media_thumbnail.py in Example folder. +TimelineItem + GetName() --> string # Returns a name of the item. + GetDuration() --> int # Returns a duration of item. + GetEnd() --> int # Returns a position of end frame. + GetFusionCompCount() --> int # Returns the number of Fusion compositions associated with the timeline item. + GetFusionCompByIndex(compIndex) --> fusionComp # Returns Fusion composition object based on given index. 1 <= compIndex <= timelineItem.GetFusionCompCount() + GetFusionCompNames() --> [names...] # Returns a list of Fusion composition names associated with the timeline item. + GetFusionCompByName(compName) --> fusionComp # Returns Fusion composition object based on given name. + GetLeftOffset() --> int # Returns a maximum extension by frame for clip from left side. + GetRightOffset() --> int # Returns a maximum extension by frame for clip from right side. + GetStart() --> int # Returns a position of first frame. + AddMarker(frameId, color, name, note, duration) --> Bool # Creates a new marker at given frameId position and with given marker information. + GetMarkers() --> [markers...] # Returns a list of all markers and their information. + GetFlags() --> [colors...] # Returns a list of flag colors assigned to the item. + GetClipColor() --> string # Returns an item color as a string. + AddFusionComp() --> fusionComp # Adds a new Fusion composition associated with the timeline item. + ImportFusionComp(path) --> fusionComp # Imports Fusion composition from given file path by creating and adding a new composition for the item. + ExportFusionComp(path, compIndex) --> Bool # Exports Fusion composition based on given index into provided file name path. + DeleteFusionCompByName(compName) --> Bool # Deletes Fusion composition by provided name. + LoadFusionCompByName(compName) --> fusionComp # Loads Fusion composition by provided name and sets it as active composition. + RenameFusionCompByName(oldName, newName) --> Bool # Renames Fusion composition by provided name with new given name. + AddVersion(versionName, versionType) --> Bool # Adds a new Version associated with the timeline item. versionType: 0 - local, 1 - remote. + DeleteVersionByName(versionName, versionType) --> Bool # Deletes Version by provided name. versionType: 0 - local, 1 - remote. + LoadVersionByName(versionName, versionType) --> Bool # Loads Version by provided name and sets it as active Version. versionType: 0 - local, 1 - remote. + RenameVersionByName(oldName, newName, versionType)--> Bool # Renames Version by provided name with new given name. versionType: 0 - local, 1 - remote. + GetMediaPoolItem() --> MediaPoolItem # Returns a corresponding to the timeline item media pool item if it exists. + GetVersionNames(versionType) --> [strings...] # Returns a list of version names by provided versionType: 0 - local, 1 - remote. + GetStereoConvergenceValues() --> [offset, value] # Returns a table of keyframe offsets and respective convergence values + GetStereoLeftFloatingWindowParams() --> [offset, value] # For the LEFT eye -> returns a table of keyframe offsets and respective floating window params. Value at particular offset includes the left, right, top and bottom floating window values + GetStereoRightFloatingWindowParams() --> [offset, value] # For the RIGHT eye -> returns a table of keyframe offsets and respective floating window params. Value at particular offset includes the left, right, top and bottom floating window values From ad9f4b340bfcefd8533dc3ab27d7816bc156414e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 May 2020 14:47:26 +0200 Subject: [PATCH 10/40] fix(resolve): workio was not opening project --- pype/resolve/workio.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pype/resolve/workio.py b/pype/resolve/workio.py index b9562449bf..8e6e50a1ed 100644 --- a/pype/resolve/workio.py +++ b/pype/resolve/workio.py @@ -5,7 +5,7 @@ from pypeapp import Logger from .lib import get_project_manager -log = Logger().get_logger(__name__, "nukestudio") +log = Logger().get_logger(__name__, "resolve") exported_projet_ext = ".drp" @@ -45,17 +45,24 @@ def open_file(filepath): # deal with current project project = pm.GetCurrentProject() + log.info(f"Test `pm`: {pm}") pm.SaveProject() - pm.CloseProject(project) try: # load project from input path project = pm.LoadProject(fname) log.info(f"Project {project.GetName()} opened...") return True - except NameError as E: - log.error(f"Project with name `{fname}` does not exist!\n\nError: {E}") - return False + except AttributeError: + log.warning((f"Project with name `{fname}` does not exist! It will " + f"be imported from {filepath} and then loaded...")) + if pm.ImportProject(filepath): + # load project from input path + project = pm.LoadProject(fname) + log.info(f"Project imported/loaded {project.GetName()}...") + return True + else: + return False def current_file(): From af5957b0c5fedcca15a6d868a5ed4ba6ca0ec838 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 May 2020 15:43:41 +0200 Subject: [PATCH 11/40] feat(resolve): workfiles are creating project folder in manager --- pype/resolve/__init__.py | 4 ++- pype/resolve/lib.py | 66 ++++++++++++++++++++++++++++++++++++++++ pype/resolve/workio.py | 9 +++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/pype/resolve/__init__.py b/pype/resolve/__init__.py index 70163718c1..72d6314b5e 100644 --- a/pype/resolve/__init__.py +++ b/pype/resolve/__init__.py @@ -22,7 +22,8 @@ from .workio import ( ) from .lib import ( - get_project_manager + get_project_manager, + set_project_manager_to_folder_name ) from .menu import launch_pype_menu @@ -43,6 +44,7 @@ __all__ = [ # lib "get_project_manager", + "set_project_manager_to_folder_name", # menu "launch_pype_menu", diff --git a/pype/resolve/lib.py b/pype/resolve/lib.py index a6f10a1533..2576136df5 100644 --- a/pype/resolve/lib.py +++ b/pype/resolve/lib.py @@ -1,5 +1,8 @@ import sys from .utils import get_resolve_module +from pypeapp import Logger + +log = Logger().get_logger(__name__, "resolve") self = sys.modules[__name__] self.pm = None @@ -10,3 +13,66 @@ def get_project_manager(): resolve = get_resolve_module() self.pm = resolve.GetProjectManager() return self.pm + + +def set_project_manager_to_folder_name(folder_name): + """ + Sets context of Project manager to given folder by name. + + Searching for folder by given name from root folder to nested. + If no existing folder by name it will create one in root folder. + + Args: + folder_name (str): name of searched folder + + Returns: + bool: True if success + + Raises: + Exception: Cannot create folder in root + + """ + # initialize project manager + get_project_manager() + + set_folder = False + + # go back to root folder + if self.pm.GotoRootFolder(): + log.info(f"Testing existing folder: {folder_name}") + folders = convert_resolve_list_type( + self.pm.GetFoldersInCurrentFolder()) + log.info(f"Testing existing folders: {folders}") + # get me first available folder object + # with the same name as in `folder_name` else return False + if next((f for f in folders if f in folder_name), False): + log.info(f"Found existing folder: {folder_name}") + set_folder = self.pm.OpenFolder(folder_name) + + if set_folder: + return True + + # if folder by name is not existent then create one + # go back to root folder + log.info(f"Folder `{folder_name}` not found and will be created") + if self.pm.GotoRootFolder(): + try: + # create folder by given name + self.pm.CreateFolder(folder_name) + self.pm.OpenFolder(folder_name) + return True + except NameError as e: + log.error((f"Folder with name `{folder_name}` cannot be created!" + f"Error: {e}")) + return False + + +def convert_resolve_list_type(resolve_list): + """ Resolve is using indexed dictionary as list type. + `{1.0: 'vaule'}` + This will convert it to normal list class + """ + assert isinstance(resolve_list, dict), ( + "Input argument should be dict() type") + + return [resolve_list[i] for i in sorted(resolve_list.keys())] diff --git a/pype/resolve/workio.py b/pype/resolve/workio.py index 8e6e50a1ed..e1e30a8734 100644 --- a/pype/resolve/workio.py +++ b/pype/resolve/workio.py @@ -2,7 +2,10 @@ import os from pypeapp import Logger -from .lib import get_project_manager +from .lib import ( + get_project_manager, + set_project_manager_to_folder_name +) log = Logger().get_logger(__name__, "resolve") @@ -42,6 +45,7 @@ def open_file(filepath): pm = get_project_manager() file = os.path.basename(filepath) fname, _ = os.path.splitext(file) + dname, _ = fname.split("_v") # deal with current project project = pm.GetCurrentProject() @@ -49,6 +53,9 @@ def open_file(filepath): pm.SaveProject() try: + log.info(f"Test `dname`: {dname}") + if not set_project_manager_to_folder_name(dname): + raise # load project from input path project = pm.LoadProject(fname) log.info(f"Project {project.GetName()} opened...") From 13f681341090b65b7bd60c105a69987cfe572b4f Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Sun, 31 May 2020 16:22:11 +0200 Subject: [PATCH 12/40] Support for unmerged AOVs in Redshift multipart EXRs --- pype/plugins/maya/publish/collect_render.py | 86 ++++++++++++++------- 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/pype/plugins/maya/publish/collect_render.py b/pype/plugins/maya/publish/collect_render.py index dbc0594c7c..e517165dbb 100644 --- a/pype/plugins/maya/publish/collect_render.py +++ b/pype/plugins/maya/publish/collect_render.py @@ -57,11 +57,12 @@ R_SINGLE_FRAME = re.compile(r"^(-?)\d+$") R_FRAME_RANGE = re.compile(r"^(?P(-?)\d+)-(?P(-?)\d+)$") R_FRAME_NUMBER = re.compile(r".+\.(?P[0-9]+)\..+") R_LAYER_TOKEN = re.compile( - r".*%l.*|.*.*|.*.*", re.IGNORECASE + r".*((?:%l)|(?:)|(?:)).*", re.IGNORECASE ) R_AOV_TOKEN = re.compile(r".*%a.*|.*.*|.*.*", re.IGNORECASE) R_SUBSTITUTE_AOV_TOKEN = re.compile(r"%a||", re.IGNORECASE) -R_REMOVE_AOV_TOKEN = re.compile(r"_%a|_|_", re.IGNORECASE) +R_REMOVE_AOV_TOKEN = re.compile(r"(?:_|\.)((?:%a)|(?:)|(?:))", + re.IGNORECASE) # to remove unused renderman tokens R_CLEAN_FRAME_TOKEN = re.compile(r"\.?\.?", re.IGNORECASE) R_CLEAN_EXT_TOKEN = re.compile(r"\.?\.?", re.IGNORECASE) @@ -514,20 +515,23 @@ class AExpectedFiles: } return scene_data - def _generate_single_file_sequence(self, layer_data): + def _generate_single_file_sequence(self, layer_data, aov_name=None): expected_files = [] file_prefix = layer_data["filePrefix"] for cam in layer_data["cameras"]: - mappings = ( + mappings = [ (R_SUBSTITUTE_SCENE_TOKEN, layer_data["sceneName"]), (R_SUBSTITUTE_LAYER_TOKEN, layer_data["layerName"]), (R_SUBSTITUTE_CAMERA_TOKEN, cam), - # this is required to remove unfilled aov token, for example - # in Redshift - (R_REMOVE_AOV_TOKEN, ""), (R_CLEAN_FRAME_TOKEN, ""), (R_CLEAN_EXT_TOKEN, ""), - ) + ] + # this is required to remove unfilled aov token, for example + # in Redshift + if aov_name: + mappings.append((R_SUBSTITUTE_AOV_TOKEN, aov_name)) + else: + mappings.append((R_REMOVE_AOV_TOKEN, "")) for regex, value in mappings: file_prefix = re.sub(regex, value, file_prefix) @@ -837,13 +841,17 @@ class ExpectedFilesRedshift(AExpectedFiles): # mapping redshift extension dropdown values to strings ext_mapping = ["iff", "exr", "tif", "png", "tga", "jpg"] + # name of aovs that are not merged into resulting exr and we need + # them specified in expectedFiles output. + unmerged_aovs = ["Cryptomatte"] + def __init__(self, layer): super(ExpectedFilesRedshift, self).__init__(layer) self.renderer = "redshift" def get_renderer_prefix(self): prefix = super(ExpectedFilesRedshift, self).get_renderer_prefix() - prefix = "{}_".format(prefix) + prefix = "{}.".format(prefix) return prefix def get_files(self): @@ -856,7 +864,22 @@ class ExpectedFilesRedshift(AExpectedFiles): if layer_data.get("enabledAOVs"): expected_files[0][u"beauty"] = self._generate_single_file_sequence( layer_data - ) # noqa: E501 + ) + + # Redshift doesn't merge Cryptomatte AOV to final exr. We need to check + # for such condition and add it to list of expected files. + + print("*" * 80) + print(layer_data.get("enabledAOVs")) + for aov in layer_data.get("enabledAOVs"): + print("-" * 80) + print(aov) + print("-" * 80) + if aov[0].lower() == "cryptomatte": + aov_name = aov[0] + expected_files.append( + {aov_name: self._generate_single_file_sequence( + layer_data, aov_name=aov_name)}) return expected_files @@ -864,23 +887,15 @@ class ExpectedFilesRedshift(AExpectedFiles): enabled_aovs = [] try: - if self.maya_is_true( - cmds.getAttr("redshiftOptions.exrForceMultilayer") - ): - # AOVs are merged in mutli-channel file - self.multipart = True - return enabled_aovs + default_ext = self.ext_mapping[ + cmds.getAttr("redshiftOptions.imageFormat") + ] except ValueError: # this occurs when Render Setting windows was not opened yet. In - # such case there are no Arnold options created so query for AOVs - # will fail. We terminate here as there are no AOVs specified then. - # This state will most probably fail later on some Validator - # anyway. - return enabled_aovs + # such case there are no Redshift options created so query + # will fail. + raise ValueError("Render settings are not initialized") - default_ext = self.ext_mapping[ - cmds.getAttr("redshiftOptions.imageFormat") - ] rs_aovs = [n for n in cmds.ls(type="RedshiftAOV")] # todo: find out how to detect multichannel exr for redshift @@ -892,9 +907,26 @@ class ExpectedFilesRedshift(AExpectedFiles): enabled = self.maya_is_true(override) if enabled: - enabled_aovs.append( - (cmds.getAttr("%s.name" % aov), default_ext) - ) + # If AOVs are merged into multipart exr, append AOV only if it + # is in the list of AOVs that renderer cannot (or will not) + # merge into final exr. + if self.maya_is_true( + cmds.getAttr("redshiftOptions.exrForceMultilayer") + ): + if cmds.getAttr("%s.name" % aov) in self.unmerged_aovs: + enabled_aovs.append( + (cmds.getAttr("%s.name" % aov), default_ext) + ) + else: + enabled_aovs.append( + (cmds.getAttr("%s.name" % aov), default_ext) + ) + + if self.maya_is_true( + cmds.getAttr("redshiftOptions.exrForceMultilayer") + ): + # AOVs are merged in mutli-channel file + self.multipart = True return enabled_aovs From 5f09521bd701c38a11bcff7f4d3850c7f53eb0d9 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Sun, 31 May 2020 17:10:16 +0200 Subject: [PATCH 13/40] stop processing multipart exrs --- pype/plugins/global/publish/extract_jpeg.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/plugins/global/publish/extract_jpeg.py b/pype/plugins/global/publish/extract_jpeg.py index 40e086db99..ea2a5a3e64 100644 --- a/pype/plugins/global/publish/extract_jpeg.py +++ b/pype/plugins/global/publish/extract_jpeg.py @@ -26,6 +26,10 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): # filter out mov and img sequences representations_new = representations[:] + if instance.data.get("multipartExr"): + # ffmpeg doesn't support multipart exrs + return + for repre in representations: tags = repre.get("tags", []) self.log.debug(repre) @@ -36,10 +40,6 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): if not isinstance(repre['files'], list): continue - if "multipartExr" in tags: - # ffmpeg doesn't support multipart exrs - continue - stagingdir = os.path.normpath(repre.get("stagingDir")) input_file = repre['files'][0] From ad3463447b5bc733340d982da83e7904a13bf2b6 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Sun, 31 May 2020 18:00:45 +0200 Subject: [PATCH 14/40] removed debug prints --- pype/plugins/maya/publish/collect_render.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pype/plugins/maya/publish/collect_render.py b/pype/plugins/maya/publish/collect_render.py index e517165dbb..b7099b168c 100644 --- a/pype/plugins/maya/publish/collect_render.py +++ b/pype/plugins/maya/publish/collect_render.py @@ -869,12 +869,7 @@ class ExpectedFilesRedshift(AExpectedFiles): # Redshift doesn't merge Cryptomatte AOV to final exr. We need to check # for such condition and add it to list of expected files. - print("*" * 80) - print(layer_data.get("enabledAOVs")) for aov in layer_data.get("enabledAOVs"): - print("-" * 80) - print(aov) - print("-" * 80) if aov[0].lower() == "cryptomatte": aov_name = aov[0] expected_files.append( From 48a8964995630bf5750215a197137c216b05bd6b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 09:57:06 +0200 Subject: [PATCH 15/40] removed harmovy because should be in hosts where already is --- pype/harmony/__init__.py | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 pype/harmony/__init__.py diff --git a/pype/harmony/__init__.py b/pype/harmony/__init__.py deleted file mode 100644 index b3edca7d15..0000000000 --- a/pype/harmony/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -import os - -from avalon import api, harmony -import pyblish.api - - -def install(): - print("Installing Pype config...") - - plugins_directory = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "plugins", "harmony" - ) - - pyblish.api.register_plugin_path( - os.path.join(plugins_directory, "publish") - ) - api.register_plugin_path( - api.Loader, os.path.join(plugins_directory, "load") - ) - api.register_plugin_path( - api.Creator, os.path.join(plugins_directory, "create") - ) - - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled - ) - - -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle node enabling on instance toggles.""" - func = """function func(args) - { - node.setEnable(args[0], args[1]) - } - func - """ - harmony.send( - {"function": func, "args": [instance[0], new_value]} - ) From f2df4d602e9f87b74396ffd616ef9cf17402ae10 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 2 Jun 2020 11:29:55 +0200 Subject: [PATCH 16/40] feat(resolve): compoud clip dev --- .../utility_scripts/__dev_compound_clip.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 pype/resolve/utility_scripts/__dev_compound_clip.py diff --git a/pype/resolve/utility_scripts/__dev_compound_clip.py b/pype/resolve/utility_scripts/__dev_compound_clip.py new file mode 100644 index 0000000000..fe47008c70 --- /dev/null +++ b/pype/resolve/utility_scripts/__dev_compound_clip.py @@ -0,0 +1,65 @@ +#! python3 +# -*- coding: utf-8 -*- + + +# convert clip def +def convert_clip(timeline=None): + """Convert timeline item (clip) into compound clip pype container + + Args: + timeline (MediaPool.Timeline): Object of timeline + + Returns: + bool: `True` if success + + Raises: + Exception: description + + """ + pass + + +# decorator function create_current_timeline_media_bin() +def create_current_timeline_media_bin(timeline=None): + """Convert timeline item (clip) into compound clip pype container + + Args: + timeline (MediaPool.Timeline): Object of timeline + + Returns: + bool: `True` if success + + Raises: + Exception: description + + """ + pass + + +# decorator function get_selected_track_items() +def get_selected_track_items(): + """Convert timeline item (clip) into compound clip pype container + + Args: + timeline (MediaPool.Timeline): Object of timeline + + Returns: + bool: `True` if success + + Raises: + Exception: description + + """ + print("testText") + + +# PypeCompoundClip() class +class PypeCompoundClip(object): + """docstring for .""" + + def __init__(self, arg): + super(self).__init__() + self.arg = arg + + def create_compound_clip(self): + pass From 3722155c4845d0782de03e67bfa535824b9b7d5f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 2 Jun 2020 11:30:51 +0200 Subject: [PATCH 17/40] fix(resolve): removing project preload --- pype/resolve/preload_console.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/resolve/preload_console.py b/pype/resolve/preload_console.py index c1b70de11d..4f783fffbe 100644 --- a/pype/resolve/preload_console.py +++ b/pype/resolve/preload_console.py @@ -13,8 +13,7 @@ while True: # Create project and set parameters: resolve = get_resolve_module() pm = resolve.GetProjectManager() - p = pm.GetCurrentProject() - if p.GetName() == "Untitled Project": + if pm: ready = None else: ready = True @@ -23,10 +22,10 @@ while True: if ready is None: time.sleep(wait_delay) - log.info(f"Waiting {wait}s for Resolve to be open in project") + log.info(f"Waiting {wait}s for Resolve to have opened Project Manager") wait += wait_delay else: print(f"Preloaded variables: \n\n\tResolve module: " f"`resolve` > {type(resolve)} \n\tProject manager: " - f"`pm` > {type(pm)} \n\tCurrent project: `p` > {type(p)}") + f"`pm` > {type(pm)}") break From 1570ab0bca987e59ada820e70545164d58c22e97 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 2 Jun 2020 14:58:44 +0200 Subject: [PATCH 18/40] feat(resolve): new hosts structure --- pype/{ => hosts}/resolve/README.markdown | 0 pype/{ => hosts}/resolve/RESOLVE_API_README.txt | 0 pype/{ => hosts}/resolve/__init__.py | 0 pype/{ => hosts}/resolve/action.py | 4 ++-- pype/{ => hosts}/resolve/lib.py | 0 pype/{ => hosts}/resolve/menu.py | 0 pype/{ => hosts}/resolve/menu_style.qss | 0 pype/{ => hosts}/resolve/pipeline.py | 2 +- pype/{ => hosts}/resolve/plugin.py | 2 +- pype/{ => hosts}/resolve/preload_console.py | 2 +- pype/{ => hosts}/resolve/utility_scripts/Pype_menu.py | 2 +- pype/{ => hosts}/resolve/utility_scripts/README.markdown | 0 .../resolve/utility_scripts/__dev_compound_clip.py | 0 pype/{ => hosts}/resolve/utility_scripts/__test_pyblish.py | 0 pype/{ => hosts}/resolve/utility_scripts/__test_subprocess.py | 2 +- pype/{ => hosts}/resolve/utils.py | 0 pype/{ => hosts}/resolve/workio.py | 0 pype/plugins/resolve/publish/collect_host.py | 2 +- 18 files changed, 8 insertions(+), 8 deletions(-) rename pype/{ => hosts}/resolve/README.markdown (100%) rename pype/{ => hosts}/resolve/RESOLVE_API_README.txt (100%) rename pype/{ => hosts}/resolve/__init__.py (100%) rename pype/{ => hosts}/resolve/action.py (93%) rename pype/{ => hosts}/resolve/lib.py (100%) rename pype/{ => hosts}/resolve/menu.py (100%) rename pype/{ => hosts}/resolve/menu_style.qss (100%) rename pype/{ => hosts}/resolve/pipeline.py (98%) rename pype/{ => hosts}/resolve/plugin.py (97%) rename pype/{ => hosts}/resolve/preload_console.py (93%) rename pype/{ => hosts}/resolve/utility_scripts/Pype_menu.py (92%) rename pype/{ => hosts}/resolve/utility_scripts/README.markdown (100%) rename pype/{ => hosts}/resolve/utility_scripts/__dev_compound_clip.py (100%) rename pype/{ => hosts}/resolve/utility_scripts/__test_pyblish.py (100%) rename pype/{ => hosts}/resolve/utility_scripts/__test_subprocess.py (93%) rename pype/{ => hosts}/resolve/utils.py (100%) rename pype/{ => hosts}/resolve/workio.py (100%) diff --git a/pype/resolve/README.markdown b/pype/hosts/resolve/README.markdown similarity index 100% rename from pype/resolve/README.markdown rename to pype/hosts/resolve/README.markdown diff --git a/pype/resolve/RESOLVE_API_README.txt b/pype/hosts/resolve/RESOLVE_API_README.txt similarity index 100% rename from pype/resolve/RESOLVE_API_README.txt rename to pype/hosts/resolve/RESOLVE_API_README.txt diff --git a/pype/resolve/__init__.py b/pype/hosts/resolve/__init__.py similarity index 100% rename from pype/resolve/__init__.py rename to pype/hosts/resolve/__init__.py diff --git a/pype/resolve/action.py b/pype/hosts/resolve/action.py similarity index 93% rename from pype/resolve/action.py rename to pype/hosts/resolve/action.py index dfbe23087c..31830937c1 100644 --- a/pype/resolve/action.py +++ b/pype/hosts/resolve/action.py @@ -4,7 +4,7 @@ from __future__ import absolute_import import pyblish.api -from ..action import get_errored_instances_from_context +from ...action import get_errored_instances_from_context class SelectInvalidAction(pyblish.api.Action): @@ -21,7 +21,7 @@ class SelectInvalidAction(pyblish.api.Action): def process(self, context, plugin): try: - from pype.resolve.utils import get_resolve_module + from pype.hosts.resolve.utils import get_resolve_module resolve = get_resolve_module() self.log.debug(resolve) except ImportError: diff --git a/pype/resolve/lib.py b/pype/hosts/resolve/lib.py similarity index 100% rename from pype/resolve/lib.py rename to pype/hosts/resolve/lib.py diff --git a/pype/resolve/menu.py b/pype/hosts/resolve/menu.py similarity index 100% rename from pype/resolve/menu.py rename to pype/hosts/resolve/menu.py diff --git a/pype/resolve/menu_style.qss b/pype/hosts/resolve/menu_style.qss similarity index 100% rename from pype/resolve/menu_style.qss rename to pype/hosts/resolve/menu_style.qss diff --git a/pype/resolve/pipeline.py b/pype/hosts/resolve/pipeline.py similarity index 98% rename from pype/resolve/pipeline.py rename to pype/hosts/resolve/pipeline.py index 7b7829a8a8..967aed1436 100644 --- a/pype/resolve/pipeline.py +++ b/pype/hosts/resolve/pipeline.py @@ -49,7 +49,7 @@ def install(): avalon.data["familiesStateDefault"] = False avalon.data["familiesStateToggled"] = family_states - log.info("pype.resolve installed") + log.info("pype.hosts.resolve installed") pyblish.register_host("resolve") pyblish.register_plugin_path(PUBLISH_PATH) diff --git a/pype/resolve/plugin.py b/pype/hosts/resolve/plugin.py similarity index 97% rename from pype/resolve/plugin.py rename to pype/hosts/resolve/plugin.py index 610fc6bcfe..628d4bdb26 100644 --- a/pype/resolve/plugin.py +++ b/pype/hosts/resolve/plugin.py @@ -1,5 +1,5 @@ from avalon import api -# from pype.resolve import lib as drlib +# from pype.hosts.resolve import lib as drlib from avalon.vendor import qargparse diff --git a/pype/resolve/preload_console.py b/pype/hosts/resolve/preload_console.py similarity index 93% rename from pype/resolve/preload_console.py rename to pype/hosts/resolve/preload_console.py index 4f783fffbe..ea1bd4f180 100644 --- a/pype/resolve/preload_console.py +++ b/pype/hosts/resolve/preload_console.py @@ -1,6 +1,6 @@ #!/usr/bin/env python import time -from pype.resolve.utils import get_resolve_module +from pype.hosts.resolve.utils import get_resolve_module from pypeapp import Logger log = Logger().get_logger(__name__, "resolve") diff --git a/pype/resolve/utility_scripts/Pype_menu.py b/pype/hosts/resolve/utility_scripts/Pype_menu.py similarity index 92% rename from pype/resolve/utility_scripts/Pype_menu.py rename to pype/hosts/resolve/utility_scripts/Pype_menu.py index 5c68fb431b..1f5cd36277 100644 --- a/pype/resolve/utility_scripts/Pype_menu.py +++ b/pype/hosts/resolve/utility_scripts/Pype_menu.py @@ -9,7 +9,7 @@ log = Logger().get_logger(__name__) def main(env): - import pype.resolve as bmdvr + import pype.hosts.resolve as bmdvr # Registers pype's Global pyblish plugins pype.install() diff --git a/pype/resolve/utility_scripts/README.markdown b/pype/hosts/resolve/utility_scripts/README.markdown similarity index 100% rename from pype/resolve/utility_scripts/README.markdown rename to pype/hosts/resolve/utility_scripts/README.markdown diff --git a/pype/resolve/utility_scripts/__dev_compound_clip.py b/pype/hosts/resolve/utility_scripts/__dev_compound_clip.py similarity index 100% rename from pype/resolve/utility_scripts/__dev_compound_clip.py rename to pype/hosts/resolve/utility_scripts/__dev_compound_clip.py diff --git a/pype/resolve/utility_scripts/__test_pyblish.py b/pype/hosts/resolve/utility_scripts/__test_pyblish.py similarity index 100% rename from pype/resolve/utility_scripts/__test_pyblish.py rename to pype/hosts/resolve/utility_scripts/__test_pyblish.py diff --git a/pype/resolve/utility_scripts/__test_subprocess.py b/pype/hosts/resolve/utility_scripts/__test_subprocess.py similarity index 93% rename from pype/resolve/utility_scripts/__test_subprocess.py rename to pype/hosts/resolve/utility_scripts/__test_subprocess.py index 30613feb22..bdc57bbf00 100644 --- a/pype/resolve/utility_scripts/__test_subprocess.py +++ b/pype/hosts/resolve/utility_scripts/__test_subprocess.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import os from pypeapp import execute, Logger -from pype.resolve.utils import get_resolve_module +from pype.hosts.resolve.utils import get_resolve_module log = Logger().get_logger("Resolve") diff --git a/pype/resolve/utils.py b/pype/hosts/resolve/utils.py similarity index 100% rename from pype/resolve/utils.py rename to pype/hosts/resolve/utils.py diff --git a/pype/resolve/workio.py b/pype/hosts/resolve/workio.py similarity index 100% rename from pype/resolve/workio.py rename to pype/hosts/resolve/workio.py diff --git a/pype/plugins/resolve/publish/collect_host.py b/pype/plugins/resolve/publish/collect_host.py index 7579be487c..a5c4b0936c 100644 --- a/pype/plugins/resolve/publish/collect_host.py +++ b/pype/plugins/resolve/publish/collect_host.py @@ -1,5 +1,5 @@ import pyblish.api -from pype.resolve.utils import get_resolve_module +from pype.hosts.resolve.utils import get_resolve_module class CollectProject(pyblish.api.ContextPlugin): From 81a05634bd146c27b48c397e4a5c6d5a6d982789 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 16:05:38 +0200 Subject: [PATCH 19/40] moved resources from pype-setup to pype --- pype/resources/__init__.py | 16 ++++++++++++++++ pype/resources/circle_green.png | Bin 0 -> 35899 bytes pype/resources/circle_orange.png | Bin 0 -> 37564 bytes pype/resources/circle_red.png | Bin 0 -> 36200 bytes pype/resources/icon.png | Bin 0 -> 3793 bytes pype/resources/icon_dev.png | Bin 0 -> 6890 bytes pype/resources/splash.png | Bin 0 -> 3793 bytes pype/resources/splash_dev.png | Bin 0 -> 6890 bytes pype/resources/working.svg | 17 +++++++++++++++++ 9 files changed, 33 insertions(+) create mode 100644 pype/resources/__init__.py create mode 100644 pype/resources/circle_green.png create mode 100644 pype/resources/circle_orange.png create mode 100644 pype/resources/circle_red.png create mode 100644 pype/resources/icon.png create mode 100644 pype/resources/icon_dev.png create mode 100644 pype/resources/splash.png create mode 100644 pype/resources/splash_dev.png create mode 100644 pype/resources/working.svg diff --git a/pype/resources/__init__.py b/pype/resources/__init__.py new file mode 100644 index 0000000000..30012366ce --- /dev/null +++ b/pype/resources/__init__.py @@ -0,0 +1,16 @@ +import os + + +def get_resource(*args): + """ Serves to simple resources access + + :param \*args: should contain *subfolder* names and *filename* of + resource from resources folder + :type \*args: list + """ + return os.path.normpath( + os.path.join( + os.path.dirname(__file__), + *args + ) + ) diff --git a/pype/resources/circle_green.png b/pype/resources/circle_green.png new file mode 100644 index 0000000000000000000000000000000000000000..b83369a9e341520d4eb8481ee501b2874f2ce356 GIT binary patch literal 35899 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 literal 0 HcmV?d00001 diff --git a/pype/resources/circle_orange.png b/pype/resources/circle_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..656f318e0c9b4eadc4f6f54def39ab4e01521f5e GIT binary patch literal 37564 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 b;3u>qRjE!lxug$XMKJrL$8D;P_+R@UX<7IA literal 0 HcmV?d00001 diff --git a/pype/resources/icon_dev.png b/pype/resources/icon_dev.png new file mode 100644 index 0000000000000000000000000000000000000000..b452eb28120438711058702fd87e4c26a7cb7f62 GIT binary patch literal 6890 zcmbt(cQjmI)b?O7`slrj5uy{LGl<@zMnbfN5M4xcg3%`;MD&uV(R&M{j25Cq)L?X? zj4mSaUB7p|YkmK}Yu)?DJ^P$}@7ZVX{XBc$SR(^X3Q`tQ5C}w}t)+e+1j56+xgkWr zi2pA1F9^g^qphxL>Yufj{VM3)R7-zoO4J=bJ{6i^P5n9!l z#VsNltmex~rUDu!1U;)5G?I53CU)o%s=^VLDr1nST3$T0u(y5b(6@RLvy$gjB<#^2 z)~rWm4}2D1eaS`XzWs2lxT&~#wbA|yMBXFzf4-a(`nO5Jl6(|i+t$>ZR2SLAVN@laAANK zuTq`s7N(#_KN@4l>xGRudVBl0q(z8IV#QU0 z@2JRc%QPlyf!Z!;OpCy)Tp6>bo8-O6HkUd>e?Pqt41!x4h3m^3E*CcW*&qM7f00%G zYz^W5a=A{{-_8`b56XX1!$3))SmEX@Sc!2$e(BcCW$)3fa_>9i;k4R&|J9cW8Rmk@ zoZ}gvoQc?3O`WN~*8LpnB;$R30Qy4bVF#iNufsyQwx7AG4JYe-{^`$DC49kjz*&i? zd*tAV?guj+slS4zWJhbyK1=uglPa+EAo5B1`ReJW5?ZPF*9K8RR%IABB6wl|UirCu zwWu-jNXw6}mnZnE#>MZtlAz#3#Att6& z4Y$&I-8)XT-`m4R^kYm09Px}ZsP>yeIj*@>m{ftp`psFkt~jcvi{%8-wXfne*k!)q znT-7JS%of}y@o*=Dt}bs**wDA<;71P5>a>%#Q74YF)2@Wk0gK_I%C}$I@DS!T&95E z^Z;>Z!kszVf>J3)m?{Co75J%z5ttH_e8tf4M+FUhe#sG&=ZQgI`eu>sbWt1bD~`N( z{&VWDJVyMd#7Q5ba0Uk~etw?B8+CS@``Flzjh48CFVJ(3i`$J0;^e`? zQ-c~?)cAr)T_!lshhJr%2S}KRc^{6VQJ_ec6dqGx=jO z=O$uZjYRbx`pEpS@!`JDXE}%v1*@ZJBXiU~^%wk#*iXl8&euG_JQ;Xv#QS!P46p8W zI1HkQ)IotQ0%$}6?F8>Gh=HD^{rX6Kg5Y9PP~DO>4KQuJQaM*A_upn{S1x0uA$)H@ z8Nl83pH9tB<+O%RWfFpXh!(fsukFJ;$I0-Lq0D-7@SAnd{Y4CVPKEY+g%H2g$OE`- zpMadj(zX86$@ePy9P^c;4)?C({uc0+a)@K}$A$cf!ija2YrO%CgOGdA^Kc@GF>*Xc zD*oG)sT`>y_J1W`Kp2EG*1qT_3`T|ZQ%zIx3o8g(XPlsjV_JRqY&xHDNko2+g{&dE zJc?JPne{#bQjx9PUJF7cW*0I*S5HKxa?zS^==Lz7*^9)eK$SS_iLJtV*W$ zKvb9P{Jj2a?S^<*o3Ca)vGr3FdJ^9?pUsMpe^U4AN1RAts>GPDk?e-ix|hjAgTNxn zzLW^vRLTx$UI;<5AXSrwuHikJXrLm`JuLtmKF z5!b?#I)0sTUNF-=UZV5v`orMlU0=n7ZtgCzh}gt?)3Oe@;No9)bd-3}$z3xc>Fd7i z{|RZfrYJ0wq!`q)E0NT2U^R`5P4owYX*2|I!|&8q^u^_-uY47RH;UYfs)Y%@^*e^& z(s^wI8Nd*%7Dq6h=T~2wtay!QmA|RLJY@$QO*(PJ_s;3@)dIs`#bWkp@~)T9XWprZ zf8VAmRT(rkQn}qIwgL?~BcBFVYjQ=DFD!9)*WocaR-e*zg*3m=NF+6sP=| z(#F-{$~HmM##Q0OLxj1B!{eZRZxB^nW6*gZ1{+oikd{kBpSAG z|9ft~KUq88f=Y~DfhvHk*M|}#j`YFkg-1fS3WF62q z;^NtC&4P*yw?AtPn`BlKbWwst$@SG1{>rAyDY4dx==Fj9@e_bGZ7cT4az1boe>cV? zU9q|7MR7c1DwYP5B6^g86SKG9xJ4GXw9dFOeTG2d^8Q+z$1v|Y5`mQnxAGv~O?3&I53qI+Lm zE7zUW|8?1TJ$WF9RLUTP-bB~6`sYa|uWc>z*f(Bt>7%n?hyPswYAPT~We01{a;AwJ zgskFqQ>dahqA|;Z97zIH_Ep38TB|Q1kxwBpaw4|9K-3&bcFB<)Rfn!(#g;l5(J39g zM2=j;A-7lZnepFw!0xtvv{?5F>sRXX8L23tw<;my4}@!)lS&Y#iI8V-Lm>^5{?q|w zVs!I5Sb586v$VzCl|hctLRq^Pn+0Y?YCwCqzdnW)m`#uKfzpLm$4 zuS+o~mJH)p8;tK>uA9ELx-gcRG?MMl47bYQ)>+ zZ6Tcr>)EU@`TXGJ@9J5w(;Cn4l4eWY`w#tZ+0rpK-nR&cXi zN-!~)=B5KOHs_3&!tBWVs&ro+1!=t|m(1!NK?CmsSabJU#*kOT8DCEG9-H@%G zcPr%tb$uC5+6xi`!v_w8Dme-i?PPcKfpZ~%0?B1)O?yCT35$RQ!UgVt_t|50FHgxY z;wp?%X|l})+1@HNBm!FRl~AywQ?ez_lX|WMsL-O-+;L6G7WkvfMS})UI6+-k2ln=U z0mS_Tri=1+bn++%YS)tIf71o_W~+pf%PJ{( zx&+hYy%S8re(ZqKrUsVi%a-AiC*#h5pVkSTg#)VVeiXpSN1-#!wYi+Id0uof4eB!^ z%;A3Ect}vNvg#iSOQ#S3FqKNPF|8Yh<^$jG#W*r0ME0duJaXQC zlzY&pfONk1y&&Zr5XYjSBdY-Ncs=xEbf}nou>}c6fIQs?x9(Ck^=0)$_aA7^4+UE~ zwJ4E}!N3c?@ACk_?DI1Gz$kCQiHKUi6bQ3{IM2-{1vCpgDiRMnACQ9R)KsM0Sxgrg zT64rI4N+JE68@X`2q}RyMb-94mIDWqwl=OL2{IxNAN8EfTWK6Sg?O?H^u^IC)svQ^ z__m_MGKuJ$qAE2DT-R;dpI3pUf%Om0DRJQZO`~n&?IVK60X3^1MrLj|JKhFFZS39u z%h><`CG^***1sX&0{=_$^a3)hjE<4Q{<@yRA61pX{t;t7B_}1mBuBd%(Jd4T?QP{p)*XsFQb2l6%awihP zs>i1&Xw7nF=pbpJcubws_=uAj;MqLmo?^25#@pV;*PoRWmi|?MQtfrk2s)tE6S5*K zdJ3~7^4VE4`{Xbk}hQD3v=*_x#Lr26=}et;8=F}t(ql>xFS*~P`E+4!bHmAn!0|Bfofh0)NjH0fvG z#S*7*e=gyVE@Qwlqg3?9dpvMetw1n*$hGDm=g|W1MJ7RnBnS-epz(H3 z{_L<FJrMD)9S#_=#HB|44e=N}qLih8$W11(KP>N~P$hAFdADMa5XypzNYp`G0mS$qhRFB*Cn+&2WS2v}coKwoQfQQ15 z1J9)3nxQRZGWNq3`p!PB266~_upCQ$frne_ z9=37j>>~V!x9AzCNdF}T;XtrEZR6BYxY9gOI??~R4kyry0#e$X$#lX*f#7p_Z<>ea z?`?nW5X>ZR)^7eW4toko?@(SE%B%OTk~KqN+)6z#gJl71r6>8-?F>T(-8U>aL+utgKmP0zhN+2dGNno&5O?LV@XgaG0xIo_)3L! z?8kTf$7*CdEE%2u`ll0GFP~oQWEfe@$F%MceK(sbto%&$f)IukI?6Z0K6OCky@WJx z*XIv5zWZVO?ZVmz>|1Ypj zhamqO^yco;>_|j6jfxj=G2)Z=ltleE91PSGmlh{qUXL8qHLYX+a$&fEFpP`cT627l zwPRx43KsHmifkja#5h`Dw+H%|_+^Q5K3FVI)ck!jDM|gHGaNoA0le41l{OFIlZ(21oI1V;5s%{tY@O3~i%WiL+6xtuP+> z1y{+pVtlyGOe8+)F*4%sC(DKwXgOnO#J9MepT}Z!Kq8@5m}O4k)9jH9mH4-smY+VY zNKNoL4d^_?_n-BM-rP;LusdawP9&~xoy)|9y$$pdAmCUrA&waMqJB;=|8gJ;3 zUmrh?M}=m;7P>Qy#v1_I0L%Zcg6mc1 z#-d{_rGv!+9^BEFT|=l`@{POIB7Jb~_#j&?mKBDDu+%}Xt>974*PX%-7*umU!X1U1 z@j^Qk2o7l~x^Hq|^+dS2sNCB<`G%qtt4 zmye>HQVO3{tpn~Y{Nda>sLJEz+KixjS1EdQDm(`>AzS}UqYhI^EDyJVCG*glV3 zVI4_Hd`}FlyV(^iGNgqu0-ZG_CQgPvReWYGesR+z$&iOvqanTtzfd)Iby5JXj~lj`D{uBrs8#csXyq}%n}ufqSEUWLh!iV}~|zl*ki{UbkEpD#`bEtcbc$cB%BzN*$dH+*hZ&X%a< zo~yMtuXg61tYWCsp6JA`6$!xP&zZO1ezEwK9I0=KhuL1a6?2|eV1=<2A@wmr`fLFA zaic}SnvGmojO@!n#JT3{ZuJjdY6F`v`*Rv}rJ`HLYUHvN1?JSZu=c3lj{~?z*hD;> z?Pbi7I;42#wUR!G!I@{)(VP)|=9O|mO>6DS)f9;;rJgSA>1jU@Z_Idnkd_^{*=!@Zyckj#{GT(I5*<4y% zz1|x>JJJcWi>xjNmq#+X9Lp2SIe3tm#|s;?vEgUX3?iw2aCEz1g^G<>P4iX@)d0xl zO;G+v@cWkZjG!40F5U~Mga4+w!MTd04m}}abH?+e*SUVn`PHIaelF)D?EYi(I_D)+ zNKoM|ALZT+(V@eT0c9GwhKEMs(o_|Nugvq<0oQtHGuqP=qC6MLAc*_?h7%_`*wb^S zlYFyGnC#focG&nUG1n$t`AD0_agsgOC)Yl=`cex3?D35G#a>TXcEb0jNh*o?tlN33n zs!I4n@0#|W@M02v&8=Z1&~WR%m73|K!hj z>u*SiGFC(HK`8l@y^a~sVu7A^5Qu!(ov;>Ji=?WcwdvzMujtLYs;a*KV>*#tu;=l? z<0!POF3vMqRDIbQALynL8~S1RLT94Y2pE@(ihnqq#G2gARfCRMz{;xEw@;aTwh?;4 zc0xyP=96CbS(RO~C0V=qL+_+-ay=~J_+sgBb~RLU^z*RS_?l|EgcO;~nSLJ}MLce| zL^tLXlDDT$-w4q7vd-Y7m+!A=qg-4niM+XuHu{na1cUIe+BoI@RHanC7_zo1yoSAT zN!#xo|0I8?5Vi?(D%?CLve&bskqG4Dk(9>!@N;Ech%~0mMa9cZQAaRX;C7Y9V5{1| n!(f5lZOv#qrvLl3`8%|{bk<)wd^R2UhXvBsFi@{V*hc(6{$xodrEz3*Bxd-m+vduBh+o{4ukPEgpO zz5xbD!#x!nHCEY!;)_rS{8J6d7GObJpmL-tP0Zl4m(l^NyV<{AlB#8n@>Oo3}NptV#uE zJ|o&Vn3{fQzV*eT>weC;f2IfKUk*oieHjXWt$u9R&iap152)_*D{Q9Z=F!{JIe)SO z%hR$_iz|#7@mk8$pHYcwq2D{bGrQIE=_ z%HJG!GSG{;`1R9ojdwK+=dxS9yRD=@oIg!qCpD2PwV&R3%+AYq-B-Rk#EpqRn42$e zH>EOb!%a~%M3rp~*r<3t>D^S3rWvB9_(;Q~?$xZM(Ovs0MtPn)j$hk-{6skM;4UMb zKV5Cp+5JBoWB+s3dgcu6mFk83jh`Q>2K%`5nIv^tH|c2{{two-)KQXy*m^}ZwzhO} z%KAMn&oAq#2$dI#=U!LuIbuc3tlO`0ov#$=N&j&1zR#|usfdEl(Xv&o9)7Q9wlB0w z%Em%{ivvE5@OL~0hayL@^9qN-46y4z6nW3;4;XCYqP@*w*T}r-!K)%N&5!#{x9*){ zhzXWASaS!qGo?GY?l$su#|0v%Q0;A5E;A>?*mVC%wJDSL=4$tivf}O;AJ@fXsLA== zEOKfsx|h|o`;*Y?jJ=BV+1DNTEg$G>Jk1H*o>$A!jmun%;blqQN=!%I)jzUkms>fp zv0Vq3qr0T+)3yK0Cug|}C!j?6ZI{>BHdqu8$!bfOwI$r&7OTOiU<}94bfcG`6vVJv zxW95=t({(PROyoy zmEu2x|DjmG9bO;u*B6;_lEHeI0b@M^LB{T+rwkh{HhHXD-M&0Q%aJluxD^0*=x^lZ zVPe>A3EYyi#IYPY@i|(&iE@>cojpdA3M=0G+f)}(&^0+{ILA7mgDX?ifc8`jm%MZrr3+I7ne?oFo!pC3p>e4AQQ5%$dRX0Q zDvz@Blmiu6I)2b38^H%lO$qNl8<(~FIZO1vNXqU?M0q(f=?llI@4fV|+krdx$Q<62 zwoi~4<(Iz|Q=_5*1+h;uw#~B+?7)>?WYVA3IC0A7SQ-m{FELP1jafHaF6c2(qJ_3j z&N-K0StGJ`?9SV4d}r^ z4_ldzCUok@j0sxQ32JjCkonCfpzda3wVq8Tu?^;habD(d;>s0$oWBZ_-rL|f&suE| z#sygbVLpOwfji?3#K|vgWsbF@Q(0l|r0f72!ZBczHJ>G<2Z6~E263pnx3F5YiF;rV zH)Ect6YyU@7~05Gz6DxivUZL$t89amWaiyw(5JyEm#EF!z-WCz3hM4TKPr8ENm;lJZOUK(TQ+b6EU1GWUTb_^}rU5-W?M%i0#!NwN<)U4-ZBIhkHHZDu zyl@@67el~bUu@(-@uDwu>B&+d-6m3}@bzV6S*;lGtAU`i zJ$cHm=J3u&RwC<;#gRU6lZnG?|zw#X3(val5R>Nk@EOgPg9i1=CLe{XNtf z1j&QkVpeSZ5s+-fin_=c1Rsz3at*8Hw6v*HjRO$q2X-@a&8%}j{V;n=-DUz_efD%N zRA>2%VX39loVUG~luQA8{aL1nnDFrWMxnm*_EN=YEjDLxEFV^i13^C=sojV0C6bTM zS{<&FKZNP7S<%g%_~~c?6Xejd_B`C?uoCzaF;({R_HYr`qoOi$@4jHbxL;WEVqa?WX%sA)p^LJ7yVkG78CtK> zrC*~p7}VI8Z3&$`v_nCok=`B)0^a*FILT3PIIZ9m)5DRazfS;K{Rf?zl?O_~|F7T^ z|BMO{wjt7jvi&jSdG#G6>fXWK?!S$)>=H^Imkr!GN|Wr?k{Lq!BJ=irs&2g8Q84%y ze@sPC%L%b&sU=_w4{uxR{rS7VLC`DJ(3=8X-HU6;<&T{geBY6WiFCqW&*YC;a2k6C zaw5|p^MRcl8fS@Z&=vA+^42o4vyS0G38778fA+jBw z&f&JAlMDspaO52}+u)SVyxK-xn-?%H!pGLxF|A8c&8G~mSXQ`oxS#3b^9SyudzAYp+{&24XX|s-CR!gj&4W0 zJiL-Nu7Hn?Kv53=DqQKt-&?=u3z=%{@~!{`lTM`Sh!TWxYI&&OB&H`wlP!K*Fnezg znOedfcz+cm#=HMLPr%!Q>%u*b8V?g5d6blGn8;iw?h7Og<}p3I81Xg?c_&wUxXQAp z{SN~E!Iv>akVAcN1Q3!ArIz*npD=A1=b45r>@AI{n2r5K_zs=cJV;(heg&ilG=MqM zbFi?J;nm#Z53;9$d-MKO4t(iX<G)L3gY|#He!w|;Fp?XY~aoINns|b10Kzw&Kh|%eN&b ziL-@qNbT4S>P2k{D-1=L=DW!`nZQGQ%GwTYVo+7abkR#q!7>xD$ik;F!hd;6fVT#2 b;3u>qRjE!lxug$XMKJrL$8D;P_+R@UX<7IA literal 0 HcmV?d00001 diff --git a/pype/resources/splash_dev.png b/pype/resources/splash_dev.png new file mode 100644 index 0000000000000000000000000000000000000000..b452eb28120438711058702fd87e4c26a7cb7f62 GIT binary patch literal 6890 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 + + + + + Working... + From acd355c6179cc7a62fb919afa5a69f54bfd0640d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 16:11:11 +0200 Subject: [PATCH 20/40] tray is in pype/tools now --- pype/tools/tray/__main__.py | 4 + pype/tools/tray/pype_tray/__init__.py | 4 + pype/tools/tray/pype_tray/tray.py | 507 ++++++++++++++++++++++++++ 3 files changed, 515 insertions(+) create mode 100644 pype/tools/tray/__main__.py create mode 100644 pype/tools/tray/pype_tray/__init__.py create mode 100644 pype/tools/tray/pype_tray/tray.py diff --git a/pype/tools/tray/__main__.py b/pype/tools/tray/__main__.py new file mode 100644 index 0000000000..d0006c0afe --- /dev/null +++ b/pype/tools/tray/__main__.py @@ -0,0 +1,4 @@ +import sys +import pype_tray + +sys.exit(pype_tray.PypeTrayApplication().exec_()) diff --git a/pype/tools/tray/pype_tray/__init__.py b/pype/tools/tray/pype_tray/__init__.py new file mode 100644 index 0000000000..317c7ab209 --- /dev/null +++ b/pype/tools/tray/pype_tray/__init__.py @@ -0,0 +1,4 @@ +from .tray import PypeTrayApplication + + +__all__ = ("main") diff --git a/pype/tools/tray/pype_tray/tray.py b/pype/tools/tray/pype_tray/tray.py new file mode 100644 index 0000000000..6c943b6423 --- /dev/null +++ b/pype/tools/tray/pype_tray/tray.py @@ -0,0 +1,507 @@ +import os +import sys +import platform +from avalon import style +from Qt import QtCore, QtGui, QtWidgets, QtSvg +from pype.resources import get_resource +from pype.api import config, Logger + + +class TrayManager: + """Cares about context of application. + + Load submenus, actions, separators and modules into tray's context. + """ + modules = {} + services = {} + services_submenu = None + + errors = [] + items = ( + config.get_presets(first_run=True) + .get('tray', {}) + .get('menu_items', []) + ) + available_sourcetypes = ['python', 'file'] + + def __init__(self, tray_widget, main_window): + self.tray_widget = tray_widget + self.main_window = main_window + self.log = Logger().get_logger(self.__class__.__name__) + + self.icon_run = QtGui.QIcon(get_resource('circle_green.png')) + self.icon_stay = QtGui.QIcon(get_resource('circle_orange.png')) + self.icon_failed = QtGui.QIcon(get_resource('circle_red.png')) + + self.services_thread = None + + def process_presets(self): + """Add modules to tray by presets. + + This is start up method for TrayManager. Loads presets and import + modules described in "menu_items.json". In `item_usage` key you can + specify by item's title or import path if you want to import it. + Example of "menu_items.json" file: + { + "item_usage": { + "Statics Server": false + } + }, { + "item_import": [{ + "title": "Ftrack", + "type": "module", + "import_path": "pype.ftrack.tray", + "fromlist": ["pype", "ftrack"] + }, { + "title": "Statics Server", + "type": "module", + "import_path": "pype.services.statics_server", + "fromlist": ["pype","services"] + }] + } + In this case `Statics Server` won't be used. + """ + # Backwards compatible presets loading + if isinstance(self.items, list): + items = self.items + else: + items = [] + # Get booleans is module should be used + usages = self.items.get("item_usage") or {} + for item in self.items.get("item_import", []): + import_path = item.get("import_path") + title = item.get("title") + + item_usage = usages.get(title) + if item_usage is None: + item_usage = usages.get(import_path, True) + + if item_usage: + items.append(item) + else: + if not title: + title = import_path + self.log.debug("{} - Module ignored".format(title)) + + if items: + self.process_items(items, self.tray_widget.menu) + + # Add services if they are + if self.services_submenu is not None: + self.tray_widget.menu.addMenu(self.services_submenu) + + # Add separator + if items and self.services_submenu is not None: + self.add_separator(self.tray_widget.menu) + + # Add Exit action to menu + aExit = QtWidgets.QAction("&Exit", self.tray_widget) + aExit.triggered.connect(self.tray_widget.exit) + self.tray_widget.menu.addAction(aExit) + + # Tell each module which modules were imported + self.connect_modules() + self.start_modules() + + def process_items(self, items, parent_menu): + """ Loop through items and add them to parent_menu. + + :param items: contains dictionary objects representing each item + :type items: list + :param parent_menu: menu where items will be add + :type parent_menu: QtWidgets.QMenu + """ + for item in items: + i_type = item.get('type', None) + result = False + if i_type is None: + continue + elif i_type == 'module': + result = self.add_module(item, parent_menu) + elif i_type == 'action': + result = self.add_action(item, parent_menu) + elif i_type == 'menu': + result = self.add_menu(item, parent_menu) + elif i_type == 'separator': + result = self.add_separator(parent_menu) + + if result is False: + self.errors.append(item) + + def add_module(self, item, parent_menu): + """Inicialize object of module and add it to context. + + :param item: item from presets containing information about module + :type item: dict + :param parent_menu: menu where module's submenus/actions will be add + :type parent_menu: QtWidgets.QMenu + :returns: success of module implementation + :rtype: bool + + REQUIRED KEYS (item): + :import_path (*str*): + - full import path as python's import + - e.g. *"path.to.module"* + :fromlist (*list*): + - subparts of import_path (as from is used) + - e.g. *["path", "to"]* + OPTIONAL KEYS (item): + :title (*str*): + - represents label shown in services menu + - import_path is used if title is not set + - title is not used at all if module is not a service + + .. note:: + Module is added as **service** if object does not have + *tray_menu* method. + """ + import_path = item.get('import_path', None) + title = item.get('title', import_path) + fromlist = item.get('fromlist', []) + try: + module = __import__( + "{}".format(import_path), + fromlist=fromlist + ) + obj = module.tray_init(self.tray_widget, self.main_window) + name = obj.__class__.__name__ + if hasattr(obj, 'tray_menu'): + obj.tray_menu(parent_menu) + else: + if self.services_submenu is None: + self.services_submenu = QtWidgets.QMenu( + 'Services', self.tray_widget.menu + ) + action = QtWidgets.QAction(title, self.services_submenu) + action.setIcon(self.icon_run) + self.services_submenu.addAction(action) + if hasattr(obj, 'set_qaction'): + obj.set_qaction(action, self.icon_failed) + self.modules[name] = obj + self.log.info("{} - Module imported".format(title)) + except ImportError as ie: + if self.services_submenu is None: + self.services_submenu = QtWidgets.QMenu( + 'Services', self.tray_widget.menu + ) + action = QtWidgets.QAction(title, self.services_submenu) + action.setIcon(self.icon_failed) + self.services_submenu.addAction(action) + self.log.warning( + "{} - Module import Error: {}".format(title, str(ie)), + exc_info=True + ) + return False + return True + + def add_action(self, item, parent_menu): + """Adds action to parent_menu. + + :param item: item from presets containing information about action + :type item: dictionary + :param parent_menu: menu where action will be added + :type parent_menu: QtWidgets.QMenu + :returns: success of adding item to parent_menu + :rtype: bool + + REQUIRED KEYS (item): + :title (*str*): + - represents label shown in menu + :sourcetype (*str*): + - type of action *enum["file", "python"]* + :command (*str*): + - filepath to script *(sourcetype=="file")* + - python code as string *(sourcetype=="python")* + OPTIONAL KEYS (item): + :tooltip (*str*): + - will be shown when hover over action + """ + sourcetype = item.get('sourcetype', None) + command = item.get('command', None) + title = item.get('title', '*ERROR*') + tooltip = item.get('tooltip', None) + + if sourcetype not in self.available_sourcetypes: + self.log.error('item "{}" has invalid sourcetype'.format(title)) + return False + if command is None or command.strip() == '': + self.log.error('item "{}" has invalid command'.format(title)) + return False + + new_action = QtWidgets.QAction(title, parent_menu) + if tooltip is not None and tooltip.strip() != '': + new_action.setToolTip(tooltip) + + if sourcetype == 'python': + new_action.triggered.connect( + lambda: exec(command) + ) + elif sourcetype == 'file': + command = os.path.normpath(command) + if '$' in command: + command_items = command.split(os.path.sep) + for i in range(len(command_items)): + if command_items[i].startswith('$'): + # TODO: raise error if environment was not found? + command_items[i] = os.environ.get( + command_items[i].replace('$', ''), command_items[i] + ) + command = os.path.sep.join(command_items) + + new_action.triggered.connect( + lambda: exec(open(command).read(), globals()) + ) + + parent_menu.addAction(new_action) + + def add_menu(self, item, parent_menu): + """ Adds submenu to parent_menu. + + :param item: item from presets containing information about menu + :type item: dictionary + :param parent_menu: menu where submenu will be added + :type parent_menu: QtWidgets.QMenu + :returns: success of adding item to parent_menu + :rtype: bool + + REQUIRED KEYS (item): + :title (*str*): + - represents label shown in menu + :items (*list*): + - list of submenus / actions / separators / modules *(dict)* + """ + try: + title = item.get('title', None) + if title is None or title.strip() == '': + self.log.error('Missing title in menu from presets') + return False + new_menu = QtWidgets.QMenu(title, parent_menu) + new_menu.setProperty('submenu', 'on') + parent_menu.addMenu(new_menu) + + self.process_items(item.get('items', []), new_menu) + return True + except Exception: + return False + + def add_separator(self, parent_menu): + """ Adds separator to parent_menu. + + :param parent_menu: menu where submenu will be added + :type parent_menu: QtWidgets.QMenu + :returns: success of adding item to parent_menu + :rtype: bool + """ + try: + parent_menu.addSeparator() + return True + except Exception: + return False + + def connect_modules(self): + """Sends all imported modules to imported modules + which have process_modules method. + """ + for obj in self.modules.values(): + if hasattr(obj, 'process_modules'): + obj.process_modules(self.modules) + + def start_modules(self): + """Modules which can be modified by another modules and + must be launched after *connect_modules* should have tray_start + to start their process afterwards. (e.g. Ftrack actions) + """ + for obj in self.modules.values(): + if hasattr(obj, 'tray_start'): + obj.tray_start() + + def on_exit(self): + for obj in self.modules.values(): + if hasattr(obj, 'tray_exit'): + try: + obj.tray_exit() + except Exception: + self.log.error("Failed to exit module {}".format( + obj.__class__.__name__ + )) + + +class SystemTrayIcon(QtWidgets.QSystemTrayIcon): + """Tray widget. + + :param parent: Main widget that cares about all GUIs + :type parent: QtWidgets.QMainWindow + """ + def __init__(self, parent): + if os.getenv("PYPE_DEV"): + icon_file_name = "icon_dev.png" + else: + icon_file_name = "icon.png" + + self.icon = QtGui.QIcon(get_resource(icon_file_name)) + + QtWidgets.QSystemTrayIcon.__init__(self, self.icon, parent) + + # Store parent - QtWidgets.QMainWindow() + self.parent = parent + + # Setup menu in Tray + self.menu = QtWidgets.QMenu() + self.menu.setStyleSheet(style.load_stylesheet()) + + # Set modules + self.tray_man = TrayManager(self, self.parent) + self.tray_man.process_presets() + + # Catch activate event + self.activated.connect(self.on_systray_activated) + # Add menu to Context of SystemTrayIcon + self.setContextMenu(self.menu) + + def on_systray_activated(self, reason): + # show contextMenu if left click + if platform.system().lower() == "darwin": + return + if reason == QtWidgets.QSystemTrayIcon.Trigger: + position = QtGui.QCursor().pos() + self.contextMenu().popup(position) + + def exit(self): + """ Exit whole application. + + - Icon won't stay in tray after exit. + """ + self.hide() + self.tray_man.on_exit() + QtCore.QCoreApplication.exit() + + +class TrayMainWindow(QtWidgets.QMainWindow): + """ TrayMainWindow is base of Pype application. + + Every widget should have set this window as parent because + QSystemTrayIcon widget is not allowed to be a parent of any widget. + + :param app: Qt application manages application's control flow + :type app: QtWidgets.QApplication + + .. note:: + *TrayMainWindow* has ability to show **working** widget. + Calling methods: + - ``show_working()`` + - ``hide_working()`` + .. todo:: Hide working widget if idle is too long + """ + def __init__(self, app): + super().__init__() + self.app = app + + self.set_working_widget() + + self.trayIcon = SystemTrayIcon(self) + self.trayIcon.show() + + def set_working_widget(self): + image_file = get_resource('working.svg') + img_pix = QtGui.QPixmap(image_file) + if image_file.endswith('.svg'): + widget = QtSvg.QSvgWidget(image_file) + else: + widget = QtWidgets.QLabel() + widget.setPixmap(img_pix) + + # Set widget properties + widget.setGeometry(img_pix.rect()) + widget.setMask(img_pix.mask()) + widget.setWindowFlags( + QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint + ) + widget.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) + + self.center_widget(widget) + self._working_widget = widget + self.helper = DragAndDropHelper(self._working_widget) + + def center_widget(self, widget): + frame_geo = widget.frameGeometry() + screen = self.app.desktop().cursor().pos() + center_point = self.app.desktop().screenGeometry( + self.app.desktop().screenNumber(screen) + ).center() + frame_geo.moveCenter(center_point) + widget.move(frame_geo.topLeft()) + + def show_working(self): + self._working_widget.show() + + def hide_working(self): + self.center_widget(self._working_widget) + self._working_widget.hide() + + +class DragAndDropHelper: + """ Helper adds to widget drag and drop ability + + :param widget: Qt Widget where drag and drop ability will be added + """ + def __init__(self, widget): + self.widget = widget + self.widget.mousePressEvent = self.mousePressEvent + self.widget.mouseMoveEvent = self.mouseMoveEvent + self.widget.mouseReleaseEvent = self.mouseReleaseEvent + + def mousePressEvent(self, event): + self.__mousePressPos = None + self.__mouseMovePos = None + if event.button() == QtCore.Qt.LeftButton: + self.__mousePressPos = event.globalPos() + self.__mouseMovePos = event.globalPos() + + def mouseMoveEvent(self, event): + if event.buttons() == QtCore.Qt.LeftButton: + # adjust offset from clicked point to origin of widget + currPos = self.widget.mapToGlobal( + self.widget.pos() + ) + globalPos = event.globalPos() + diff = globalPos - self.__mouseMovePos + newPos = self.widget.mapFromGlobal(currPos + diff) + self.widget.move(newPos) + self.__mouseMovePos = globalPos + + def mouseReleaseEvent(self, event): + if self.__mousePressPos is not None: + moved = event.globalPos() - self.__mousePressPos + if moved.manhattanLength() > 3: + event.ignore() + return + + +class PypeTrayApplication(QtWidgets.QApplication): + """Qt application manages application's control flow. + """ + def __init__(self): + super(self.__class__, self).__init__(sys.argv) + # Allows to close widgets without exiting app + self.setQuitOnLastWindowClosed(False) + # Sets up splash + splash_widget = self.set_splash() + + splash_widget.show() + self.processEvents() + self.main_window = TrayMainWindow(self) + splash_widget.hide() + + def set_splash(self): + if os.getenv("PYPE_DEV"): + splash_file_name = "splash_dev.png" + else: + splash_file_name = "splash.png" + splash_pix = QtGui.QPixmap(get_resource(splash_file_name)) + splash = QtWidgets.QSplashScreen(splash_pix) + splash.setMask(splash_pix.mask()) + splash.setEnabled(False) + splash.setWindowFlags( + QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint + ) + return splash From ee8e3e6c63f74ebf3b47c6935a3cad21f3d81e19 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 16:13:31 +0200 Subject: [PATCH 21/40] changes style imports because pype style is actually avalon style so was removed --- pype/modules/clockify/clockify.py | 2 +- pype/modules/clockify/widget_message.py | 2 +- pype/modules/clockify/widget_settings.py | 2 +- pype/modules/ftrack/tray/login_dialog.py | 2 +- pype/modules/logging/gui/app.py | 2 +- pype/modules/muster/muster.py | 2 +- pype/modules/muster/widget_login.py | 2 +- .../standalonepublish/widgets/widget_component_item.py | 2 +- pype/modules/timers_manager/widget_user_idle.py | 2 +- pype/modules/user/widget_user.py | 6 +++--- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pype/modules/clockify/clockify.py b/pype/modules/clockify/clockify.py index 6d5dc9213c..2ab22702c1 100644 --- a/pype/modules/clockify/clockify.py +++ b/pype/modules/clockify/clockify.py @@ -1,7 +1,7 @@ import os import threading from pype.api import Logger -from pypeapp import style +from avalon import style from Qt import QtWidgets from . import ClockifySettings, ClockifyAPI, MessageWidget diff --git a/pype/modules/clockify/widget_message.py b/pype/modules/clockify/widget_message.py index 349875b9e5..f919c3f819 100644 --- a/pype/modules/clockify/widget_message.py +++ b/pype/modules/clockify/widget_message.py @@ -1,5 +1,5 @@ from Qt import QtCore, QtGui, QtWidgets -from pypeapp import style +from avalon import style class MessageWidget(QtWidgets.QWidget): diff --git a/pype/modules/clockify/widget_settings.py b/pype/modules/clockify/widget_settings.py index 027268834c..956bdb1916 100644 --- a/pype/modules/clockify/widget_settings.py +++ b/pype/modules/clockify/widget_settings.py @@ -1,6 +1,6 @@ import os from Qt import QtCore, QtGui, QtWidgets -from pypeapp import style +from avalon import style class ClockifySettings(QtWidgets.QWidget): diff --git a/pype/modules/ftrack/tray/login_dialog.py b/pype/modules/ftrack/tray/login_dialog.py index 0bfa1cc481..3b8a366209 100644 --- a/pype/modules/ftrack/tray/login_dialog.py +++ b/pype/modules/ftrack/tray/login_dialog.py @@ -1,6 +1,6 @@ import os import requests -from pypeapp import style +from avalon import style from pype.modules.ftrack import credentials from . import login_tools from Qt import QtCore, QtGui, QtWidgets diff --git a/pype/modules/logging/gui/app.py b/pype/modules/logging/gui/app.py index 9767077f80..74849b23bc 100644 --- a/pype/modules/logging/gui/app.py +++ b/pype/modules/logging/gui/app.py @@ -1,6 +1,6 @@ from Qt import QtWidgets, QtCore from .widgets import LogsWidget, LogDetailWidget -from pypeapp import style +from avalon import style class LogsWindow(QtWidgets.QWidget): diff --git a/pype/modules/muster/muster.py b/pype/modules/muster/muster.py index 1f92e57e83..629fb12635 100644 --- a/pype/modules/muster/muster.py +++ b/pype/modules/muster/muster.py @@ -1,5 +1,5 @@ import appdirs -from pypeapp import style +from avalon import style from Qt import QtWidgets import os import json diff --git a/pype/modules/muster/widget_login.py b/pype/modules/muster/widget_login.py index 88d769ef93..8de0d3136a 100644 --- a/pype/modules/muster/widget_login.py +++ b/pype/modules/muster/widget_login.py @@ -1,6 +1,6 @@ import os from Qt import QtCore, QtGui, QtWidgets -from pypeapp import style +from avalon import style class MusterLogin(QtWidgets.QWidget): diff --git a/pype/modules/standalonepublish/widgets/widget_component_item.py b/pype/modules/standalonepublish/widgets/widget_component_item.py index 6275238412..40298520b1 100644 --- a/pype/modules/standalonepublish/widgets/widget_component_item.py +++ b/pype/modules/standalonepublish/widgets/widget_component_item.py @@ -1,7 +1,7 @@ import os from . import QtCore, QtGui, QtWidgets from . import get_resource -from pypeapp import style +from avalon import style class ComponentItem(QtWidgets.QFrame): diff --git a/pype/modules/timers_manager/widget_user_idle.py b/pype/modules/timers_manager/widget_user_idle.py index f5efcec9bb..697c0a04d9 100644 --- a/pype/modules/timers_manager/widget_user_idle.py +++ b/pype/modules/timers_manager/widget_user_idle.py @@ -1,5 +1,5 @@ from pype.api import Logger -from pypeapp import style +from avalon import style from Qt import QtCore, QtGui, QtWidgets diff --git a/pype/modules/user/widget_user.py b/pype/modules/user/widget_user.py index 27faa857f5..1d43941345 100644 --- a/pype/modules/user/widget_user.py +++ b/pype/modules/user/widget_user.py @@ -1,6 +1,6 @@ -import os from Qt import QtCore, QtGui, QtWidgets -from pypeapp import style, resources +from pype.resources import get_resource +from avalon import style class UserWidget(QtWidgets.QWidget): @@ -14,7 +14,7 @@ class UserWidget(QtWidgets.QWidget): self.module = module # Style - icon = QtGui.QIcon(resources.get_resource("icon.png")) + icon = QtGui.QIcon(get_resource("icon.png")) self.setWindowIcon(icon) self.setWindowTitle("Username Settings") self.setMinimumWidth(self.MIN_WIDTH) From 4fab9dadda55b72f25eaf98eb17a01a94c739743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:20:47 +0200 Subject: [PATCH 22/40] skip invalid attributes --- pype/plugins/maya/publish/collect_look.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/plugins/maya/publish/collect_look.py b/pype/plugins/maya/publish/collect_look.py index 6dc66711da..7df85e4ba7 100644 --- a/pype/plugins/maya/publish/collect_look.py +++ b/pype/plugins/maya/publish/collect_look.py @@ -277,7 +277,13 @@ class CollectLook(pyblish.api.InstancePlugin): if looksets: for look in looksets: for at in shaderAttrs: - con = cmds.listConnections("{}.{}".format(look, at)) + try: + con = cmds.listConnections("{}.{}".format(look, at)) + except ValueError: + # skip attributes that are invalid in current + # context. For example in the case where + # Arnold is not enabled. + continue if con: materials.extend(con) From 02cf1eff7fb134af0e0b6a21000216655a72e214 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 17:28:43 +0200 Subject: [PATCH 23/40] pype_tray folder changed to single file --- pype/tools/tray/{pype_tray/tray.py => pype_tray.py} | 0 pype/tools/tray/pype_tray/__init__.py | 4 ---- 2 files changed, 4 deletions(-) rename pype/tools/tray/{pype_tray/tray.py => pype_tray.py} (100%) delete mode 100644 pype/tools/tray/pype_tray/__init__.py diff --git a/pype/tools/tray/pype_tray/tray.py b/pype/tools/tray/pype_tray.py similarity index 100% rename from pype/tools/tray/pype_tray/tray.py rename to pype/tools/tray/pype_tray.py diff --git a/pype/tools/tray/pype_tray/__init__.py b/pype/tools/tray/pype_tray/__init__.py deleted file mode 100644 index 317c7ab209..0000000000 --- a/pype/tools/tray/pype_tray/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .tray import PypeTrayApplication - - -__all__ = ("main") From 852eaba5f04057cb1f5041cc6beaed66fc9352f3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 17:30:30 +0200 Subject: [PATCH 24/40] format changes --- pype/tools/tray/pype_tray.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pype/tools/tray/pype_tray.py b/pype/tools/tray/pype_tray.py index 6c943b6423..eec8f61cc4 100644 --- a/pype/tools/tray/pype_tray.py +++ b/pype/tools/tray/pype_tray.py @@ -478,8 +478,7 @@ class DragAndDropHelper: class PypeTrayApplication(QtWidgets.QApplication): - """Qt application manages application's control flow. - """ + """Qt application manages application's control flow.""" def __init__(self): super(self.__class__, self).__init__(sys.argv) # Allows to close widgets without exiting app From a50c7996c8cc5f32504ce1154834d2dbbf61e457 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Tue, 2 Jun 2020 16:39:50 +0100 Subject: [PATCH 25/40] Storyboard Pro icon --- res/app_icons/storyboardpro.png | Bin 0 -> 27353 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/app_icons/storyboardpro.png diff --git a/res/app_icons/storyboardpro.png b/res/app_icons/storyboardpro.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9526f1632ac247b3761fc6eb8b94dad761313d GIT binary patch literal 27353 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

RZyIAuK-(}hkmE{M9D$Q}y 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 R3~c~VlvR@{mooeDe*lfE5zPPq literal 0 HcmV?d00001 From 6c2907c1dea4970b89da98307a701484e6b1af99 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 2 Jun 2020 18:02:09 +0200 Subject: [PATCH 26/40] fixed unsuported escape of * in docstring --- pype/resources/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/resources/__init__.py b/pype/resources/__init__.py index 30012366ce..248614ae9d 100644 --- a/pype/resources/__init__.py +++ b/pype/resources/__init__.py @@ -4,9 +4,9 @@ import os def get_resource(*args): """ Serves to simple resources access - :param \*args: should contain *subfolder* names and *filename* of + :param *args: should contain *subfolder* names and *filename* of resource from resources folder - :type \*args: list + :type *args: list """ return os.path.normpath( os.path.join( From a63aebcfbdc5cade56d37be2e5b711fe9bd2c32b Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 3 Jun 2020 11:23:39 +0200 Subject: [PATCH 27/40] fix(resolve): missing hosts path bit in import --- pype/hooks/resolve/prelaunch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hooks/resolve/prelaunch.py b/pype/hooks/resolve/prelaunch.py index 6f5c22a7d0..bddeccf4a3 100644 --- a/pype/hooks/resolve/prelaunch.py +++ b/pype/hooks/resolve/prelaunch.py @@ -3,7 +3,7 @@ import traceback import importlib from pype.lib import PypeHook from pypeapp import Logger -from pype.resolve import utils +from pype.hosts.resolve import utils class ResolvePrelaunch(PypeHook): From de502e11efcd9252664788dfe6f1d37022e36135 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 3 Jun 2020 14:09:02 +0200 Subject: [PATCH 28/40] feat(blender): adding plugin for increment version --- .../publish/increment_workfile_version.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 pype/plugins/blender/publish/increment_workfile_version.py diff --git a/pype/plugins/blender/publish/increment_workfile_version.py b/pype/plugins/blender/publish/increment_workfile_version.py new file mode 100644 index 0000000000..5addca6392 --- /dev/null +++ b/pype/plugins/blender/publish/increment_workfile_version.py @@ -0,0 +1,25 @@ +import pyblish.api +import avalon.blender.workio + + +class IncrementWorkfileVersion(pyblish.api.ContextPlugin): + """Increment current workfile version.""" + + order = pyblish.api.IntegratorOrder + 0.9 + label = "Increment Workfile Version" + optional = True + hosts = ["blender"] + families = ["animation", "model", "rig", "action"] + + def process(self, context): + + assert all(result["success"] for result in context.data["results"]), ( + "Publishing not succesfull so version is not increased.") + + from pype.lib import version_up + path = context.data["currentFile"] + filepath = version_up(path) + + avalon.blender.workio.save_file(filepath, copy=False) + + self.log.info('Incrementing script version') From 367f78c220f447d9c18721f7e40693d4eb3f9933 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 3 Jun 2020 18:49:27 +0200 Subject: [PATCH 29/40] extract thumbnail in standalne publisher has presetable ffmpeg_args attribute --- .../publish/extract_thumbnail.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py index daa3936359..276d56d536 100644 --- a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py +++ b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py @@ -18,6 +18,9 @@ class ExtractThumbnailSP(pyblish.api.InstancePlugin): hosts = ["standalonepublisher"] order = pyblish.api.ExtractorOrder + # Presetable attribute + ffmpeg_args = None + def process(self, instance): repres = instance.data.get('representations') if not repres: @@ -66,27 +69,23 @@ class ExtractThumbnailSP(pyblish.api.InstancePlugin): full_thumbnail_path = tempfile.mkstemp(suffix=".jpg")[1] self.log.info("output {}".format(full_thumbnail_path)) - config_data = instance.context.data.get("output_repre_config", {}) - - proj_name = os.environ.get("AVALON_PROJECT", "__default__") - profile = config_data.get( - proj_name, - config_data.get("__default__", {}) - ) - ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg") + ffmpeg_args = self.ffmpeg_args or {} + jpeg_items = [] jpeg_items.append(ffmpeg_path) # override file if already exists jpeg_items.append("-y") # add input filters from peresets - if profile: - jpeg_items.extend(profile.get('input', [])) + jpeg_items.extend(self.ffmpeg_args.get("input") or []) # input file jpeg_items.append("-i {}".format(full_input_path)) # extract only single file jpeg_items.append("-vframes 1") + + jpeg_items.extend(self.ffmpeg_args.get("output") or []) + # output file jpeg_items.append(full_thumbnail_path) From 9fe0c3055e249cab9f903d63dd620655a8f1b168 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 3 Jun 2020 18:50:18 +0200 Subject: [PATCH 30/40] moved multipartExr check much earlier in extract_jpeg plugin --- pype/plugins/global/publish/extract_jpeg.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/plugins/global/publish/extract_jpeg.py b/pype/plugins/global/publish/extract_jpeg.py index 2931bb5835..e377ba2a0d 100644 --- a/pype/plugins/global/publish/extract_jpeg.py +++ b/pype/plugins/global/publish/extract_jpeg.py @@ -20,6 +20,10 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): if 'crypto' in instance.data['subset']: return + # ffmpeg doesn't support multipart exrs + if instance.data.get("multipartExr") is True: + return + # get representation and loop them representations = instance.data["representations"] @@ -36,10 +40,6 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): if not isinstance(repre['files'], list): continue - if instance.data.get("multipartExr") is True: - # ffmpeg doesn't support multipart exrs - continue - stagingdir = os.path.normpath(repre.get("stagingDir")) input_file = repre['files'][0] From 818abdaa822b5304c7a75d9863751a6a598bbd3f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 3 Jun 2020 18:51:44 +0200 Subject: [PATCH 31/40] extract_jpeg has presetable attribute ffmpeg_args --- pype/plugins/global/publish/extract_jpeg.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pype/plugins/global/publish/extract_jpeg.py b/pype/plugins/global/publish/extract_jpeg.py index e377ba2a0d..2ef2ecdd01 100644 --- a/pype/plugins/global/publish/extract_jpeg.py +++ b/pype/plugins/global/publish/extract_jpeg.py @@ -14,8 +14,10 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): families = ["imagesequence", "render", "render2d", "source"] enabled = False - def process(self, instance): + # presetable attribute + ffmpeg_args = None + def process(self, instance): self.log.info("subset {}".format(instance.data['subset'])) if 'crypto' in instance.data['subset']: return @@ -37,7 +39,7 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): if not valid: continue - if not isinstance(repre['files'], list): + if not isinstance(repre['files'], (list, tuple)): continue stagingdir = os.path.normpath(repre.get("stagingDir")) @@ -57,21 +59,19 @@ class ExtractJpegEXR(pyblish.api.InstancePlugin): self.log.info("output {}".format(full_output_path)) - config_data = instance.context.data['output_repre_config'] - - proj_name = os.environ.get('AVALON_PROJECT', '__default__') - profile = config_data.get(proj_name, config_data['__default__']) - ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg") + ffmpeg_args = self.ffmpeg_args or {} jpeg_items = [] jpeg_items.append(ffmpeg_path) # override file if already exists jpeg_items.append("-y") # use same input args like with mov - jpeg_items.extend(profile.get('input', [])) + jpeg_items.extend(ffmpeg_args.get("input") or []) # input file jpeg_items.append("-i {}".format(full_input_path)) + # output arguments from presets + jpeg_items.extend(ffmpeg_args.get("output") or []) # output file jpeg_items.append(full_output_path) From e1ea7a7dafe61075b8fee5b38c5aff27c0c8a0bc Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 3 Jun 2020 18:55:51 +0200 Subject: [PATCH 32/40] variable usage fix --- pype/plugins/standalonepublisher/publish/extract_thumbnail.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py index 276d56d536..cddc9c3a82 100644 --- a/pype/plugins/standalonepublisher/publish/extract_thumbnail.py +++ b/pype/plugins/standalonepublisher/publish/extract_thumbnail.py @@ -78,13 +78,13 @@ class ExtractThumbnailSP(pyblish.api.InstancePlugin): # override file if already exists jpeg_items.append("-y") # add input filters from peresets - jpeg_items.extend(self.ffmpeg_args.get("input") or []) + jpeg_items.extend(ffmpeg_args.get("input") or []) # input file jpeg_items.append("-i {}".format(full_input_path)) # extract only single file jpeg_items.append("-vframes 1") - jpeg_items.extend(self.ffmpeg_args.get("output") or []) + jpeg_items.extend(ffmpeg_args.get("output") or []) # output file jpeg_items.append(full_thumbnail_path) From f32fc2dfe270dcc3b6f0cbbb3f75df2d3e49db1e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 16:59:21 +0200 Subject: [PATCH 33/40] removed deprecated doctor actions --- .../actions/action_attributes_remapper.py | 284 --------------- .../ftrack/actions/action_cust_attr_doctor.py | 336 ------------------ .../actions/action_update_from_v2-2-0.py | 189 ---------- 3 files changed, 809 deletions(-) delete mode 100644 pype/modules/ftrack/actions/action_attributes_remapper.py delete mode 100644 pype/modules/ftrack/actions/action_cust_attr_doctor.py delete mode 100644 pype/modules/ftrack/actions/action_update_from_v2-2-0.py diff --git a/pype/modules/ftrack/actions/action_attributes_remapper.py b/pype/modules/ftrack/actions/action_attributes_remapper.py deleted file mode 100644 index b5fad7dc45..0000000000 --- a/pype/modules/ftrack/actions/action_attributes_remapper.py +++ /dev/null @@ -1,284 +0,0 @@ -import os - -import ftrack_api -from pype.modules.ftrack import BaseAction -from pype.modules.ftrack.lib.io_nonsingleton import DbConnector - - -class AttributesRemapper(BaseAction): - '''Edit meta data action.''' - - ignore_me = True - #: Action identifier. - identifier = 'attributes.remapper' - #: Action label. - label = "Pype Doctor" - variant = '- Attributes Remapper' - #: Action description. - description = 'Remaps attributes in avalon DB' - - #: roles that are allowed to register this action - role_list = ["Pypeclub", "Administrator"] - icon = '{}/ftrack/action_icons/PypeDoctor.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) - - db_con = DbConnector() - keys_to_change = { - "fstart": "frameStart", - "startFrame": "frameStart", - "edit_in": "frameStart", - - "fend": "frameEnd", - "endFrame": "frameEnd", - "edit_out": "frameEnd", - - "handle_start": "handleStart", - "handle_end": "handleEnd", - "handles": ["handleEnd", "handleStart"], - - "frameRate": "fps", - "framerate": "fps", - "resolution_width": "resolutionWidth", - "resolution_height": "resolutionHeight", - "pixel_aspect": "pixelAspect" - } - - def discover(self, session, entities, event): - ''' Validation ''' - - return True - - def interface(self, session, entities, event): - if event['data'].get('values', {}): - return - - title = 'Select Projects where attributes should be remapped' - - items = [] - - selection_enum = { - 'label': 'Process type', - 'type': 'enumerator', - 'name': 'process_type', - 'data': [ - { - 'label': 'Selection', - 'value': 'selection' - }, { - 'label': 'Inverted selection', - 'value': 'except' - } - ], - 'value': 'selection' - } - selection_label = { - 'type': 'label', - 'value': ( - 'Selection based variants:
' - '- `Selection` - ' - 'NOTHING is processed when nothing is selected
' - '- `Inverted selection` - ' - 'ALL Projects are processed when nothing is selected' - ) - } - - items.append(selection_enum) - items.append(selection_label) - - item_splitter = {'type': 'label', 'value': '---'} - - all_projects = session.query('Project').all() - for project in all_projects: - item_label = { - 'type': 'label', - 'value': '{} ({})'.format( - project['full_name'], project['name'] - ) - } - item = { - 'name': project['id'], - 'type': 'boolean', - 'value': False - } - if len(items) > 0: - items.append(item_splitter) - items.append(item_label) - items.append(item) - - if len(items) == 0: - return { - 'success': False, - 'message': 'Didn\'t found any projects' - } - else: - return { - 'items': items, - 'title': title - } - - def launch(self, session, entities, event): - if 'values' not in event['data']: - return - - values = event['data']['values'] - process_type = values.pop('process_type') - - selection = True - if process_type == 'except': - selection = False - - interface_messages = {} - - projects_to_update = [] - for project_id, update_bool in values.items(): - if not update_bool and selection: - continue - - if update_bool and not selection: - continue - - project = session.query( - 'Project where id is "{}"'.format(project_id) - ).one() - projects_to_update.append(project) - - if not projects_to_update: - self.log.debug('Nothing to update') - return { - 'success': True, - 'message': 'Nothing to update' - } - - - self.db_con.install() - - relevant_types = ["project", "asset", "version"] - - for ft_project in projects_to_update: - self.log.debug( - "Processing project \"{}\"".format(ft_project["full_name"]) - ) - - self.db_con.Session["AVALON_PROJECT"] = ft_project["full_name"] - project = self.db_con.find_one({'type': 'project'}) - if not project: - key = "Projects not synchronized to db" - if key not in interface_messages: - interface_messages[key] = [] - interface_messages[key].append(ft_project["full_name"]) - continue - - # Get all entities in project collection from MongoDB - _entities = self.db_con.find({}) - for _entity in _entities: - ent_t = _entity.get("type", "*unknown type") - name = _entity.get("name", "*unknown name") - - self.log.debug( - "- {} ({})".format(name, ent_t) - ) - - # Skip types that do not store keys to change - if ent_t.lower() not in relevant_types: - self.log.debug("-- skipping - type is not relevant") - continue - - # Get data which will change - updating_data = {} - source_data = _entity["data"] - - for key_from, key_to in self.keys_to_change.items(): - # continue if final key already exists - if type(key_to) == list: - for key in key_to: - # continue if final key was set in update_data - if key in updating_data: - continue - - # continue if source key not exist or value is None - value = source_data.get(key_from) - if value is None: - continue - - self.log.debug( - "-- changing key {} to {}".format( - key_from, - key - ) - ) - - updating_data[key] = value - else: - if key_to in source_data: - continue - - # continue if final key was set in update_data - if key_to in updating_data: - continue - - # continue if source key not exist or value is None - value = source_data.get(key_from) - if value is None: - continue - - self.log.debug( - "-- changing key {} to {}".format(key_from, key_to) - ) - updating_data[key_to] = value - - # Pop out old keys from entity - is_obsolete = False - for key in self.keys_to_change: - if key not in source_data: - continue - is_obsolete = True - source_data.pop(key) - - # continue if there is nothing to change - if not is_obsolete and not updating_data: - self.log.debug("-- nothing to change") - continue - - source_data.update(updating_data) - - self.db_con.update_many( - {"_id": _entity["_id"]}, - {"$set": {"data": source_data}} - ) - - self.db_con.uninstall() - - if interface_messages: - self.show_interface_from_dict( - messages=interface_messages, - title="Errors during remapping attributes", - event=event - ) - - return True - - def show_interface_from_dict(self, event, messages, title=""): - items = [] - - for key, value in messages.items(): - if not value: - continue - subtitle = {'type': 'label', 'value': '# {}'.format(key)} - items.append(subtitle) - if isinstance(value, list): - for item in value: - message = { - 'type': 'label', 'value': '

{}

'.format(item) - } - items.append(message) - else: - message = {'type': 'label', 'value': '

{}

'.format(value)} - items.append(message) - - self.show_interface(items=items, title=title, event=event) - -def register(session, plugins_presets={}): - '''Register plugin. Called when used as an plugin.''' - - AttributesRemapper(session, plugins_presets).register() diff --git a/pype/modules/ftrack/actions/action_cust_attr_doctor.py b/pype/modules/ftrack/actions/action_cust_attr_doctor.py deleted file mode 100644 index e67ce4e5bf..0000000000 --- a/pype/modules/ftrack/actions/action_cust_attr_doctor.py +++ /dev/null @@ -1,336 +0,0 @@ -import os -import sys -import json -import argparse -import logging - -import ftrack_api -from pype.modules.ftrack import BaseAction - - -class CustomAttributeDoctor(BaseAction): - - ignore_me = True - #: Action identifier. - identifier = 'custom.attributes.doctor' - #: Action label. - label = "Pype Doctor" - variant = '- Custom Attributes Doctor' - #: Action description. - description = ( - 'Fix hierarchical custom attributes mainly handles, fstart' - ' and fend' - ) - - icon = '{}/ftrack/action_icons/PypeDoctor.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) - hierarchical_ca = ['handleStart', 'handleEnd', 'frameStart', 'frameEnd'] - hierarchical_alternatives = { - 'handleStart': 'handles', - 'handleEnd': 'handles', - "frameStart": "fstart", - "frameEnd": "fend" - } - - # Roles for new custom attributes - read_roles = ['ALL',] - write_roles = ['ALL',] - - data_ca = { - 'handleStart': { - 'label': 'Frame handles start', - 'type': 'number', - 'config': json.dumps({'isdecimal': False}) - }, - 'handleEnd': { - 'label': 'Frame handles end', - 'type': 'number', - 'config': json.dumps({'isdecimal': False}) - }, - 'frameStart': { - 'label': 'Frame start', - 'type': 'number', - 'config': json.dumps({'isdecimal': False}) - }, - 'frameEnd': { - 'label': 'Frame end', - 'type': 'number', - 'config': json.dumps({'isdecimal': False}) - } - } - - def discover(self, session, entities, event): - ''' Validation ''' - - return True - - def interface(self, session, entities, event): - if event['data'].get('values', {}): - return - - title = 'Select Project to fix Custom attributes' - - items = [] - item_splitter = {'type': 'label', 'value': '---'} - - all_projects = session.query('Project').all() - for project in all_projects: - item_label = { - 'type': 'label', - 'value': '{} ({})'.format( - project['full_name'], project['name'] - ) - } - item = { - 'name': project['id'], - 'type': 'boolean', - 'value': False - } - if len(items) > 0: - items.append(item_splitter) - items.append(item_label) - items.append(item) - - if len(items) == 0: - return { - 'success': False, - 'message': 'Didn\'t found any projects' - } - else: - return { - 'items': items, - 'title': title - } - - def launch(self, session, entities, event): - if 'values' not in event['data']: - return - - values = event['data']['values'] - projects_to_update = [] - for project_id, update_bool in values.items(): - if not update_bool: - continue - - project = session.query( - 'Project where id is "{}"'.format(project_id) - ).one() - projects_to_update.append(project) - - if not projects_to_update: - self.log.debug('Nothing to update') - return { - 'success': True, - 'message': 'Nothing to update' - } - - self.security_roles = {} - self.to_process = {} - # self.curent_default_values = {} - existing_attrs = session.query('CustomAttributeConfiguration').all() - self.prepare_custom_attributes(existing_attrs) - - self.projects_data = {} - for project in projects_to_update: - self.process_data(project) - - return True - - def process_data(self, entity): - cust_attrs = entity.get('custom_attributes') - if not cust_attrs: - return - for dst_key, src_key in self.to_process.items(): - if src_key in cust_attrs: - value = cust_attrs[src_key] - entity['custom_attributes'][dst_key] = value - self.session.commit() - - for child in entity.get('children', []): - self.process_data(child) - - def prepare_custom_attributes(self, existing_attrs): - to_process = {} - to_create = [] - all_keys = {attr['key']: attr for attr in existing_attrs} - for key in self.hierarchical_ca: - if key not in all_keys: - self.log.debug( - 'Custom attribute "{}" does not exist at all'.format(key) - ) - to_create.append(key) - if key in self.hierarchical_alternatives: - alt_key = self.hierarchical_alternatives[key] - if alt_key in all_keys: - self.log.debug(( - 'Custom attribute "{}" will use values from "{}"' - ).format(key, alt_key)) - - to_process[key] = alt_key - - obj = all_keys[alt_key] - # if alt_key not in self.curent_default_values: - # self.curent_default_values[alt_key] = obj['default'] - obj['default'] = None - self.session.commit() - - else: - obj = all_keys[key] - new_key = key + '_old' - - if obj['is_hierarchical']: - if new_key not in all_keys: - self.log.info(( - 'Custom attribute "{}" is already hierarchical' - ' and can\'t find old one' - ).format(key) - ) - continue - - to_process[key] = new_key - continue - - # default_value = obj['default'] - # if new_key not in self.curent_default_values: - # self.curent_default_values[new_key] = default_value - - obj['key'] = new_key - obj['label'] = obj['label'] + '(old)' - obj['default'] = None - - self.session.commit() - - to_create.append(key) - to_process[key] = new_key - - self.to_process = to_process - for key in to_create: - data = { - 'key': key, - 'entity_type': 'show', - 'is_hierarchical': True, - 'default': None - } - for _key, _value in self.data_ca.get(key, {}).items(): - if _key == 'type': - _value = self.session.query(( - 'CustomAttributeType where name is "{}"' - ).format(_value)).first() - - data[_key] = _value - - avalon_group = self.session.query( - 'CustomAttributeGroup where name is "avalon"' - ).first() - if avalon_group: - data['group'] = avalon_group - - read_roles = self.get_security_role(self.read_roles) - write_roles = self.get_security_role(self.write_roles) - data['read_security_roles'] = read_roles - data['write_security_roles'] = write_roles - - self.session.create('CustomAttributeConfiguration', data) - self.session.commit() - - # def return_back_defaults(self): - # existing_attrs = self.session.query( - # 'CustomAttributeConfiguration' - # ).all() - # - # for attr_key, default in self.curent_default_values.items(): - # for attr in existing_attrs: - # if attr['key'] != attr_key: - # continue - # attr['default'] = default - # self.session.commit() - # break - - def get_security_role(self, security_roles): - roles = [] - if len(security_roles) == 0 or security_roles[0] == 'ALL': - roles = self.get_role_ALL() - elif security_roles[0] == 'except': - excepts = security_roles[1:] - all = self.get_role_ALL() - for role in all: - if role['name'] not in excepts: - roles.append(role) - if role['name'] not in self.security_roles: - self.security_roles[role['name']] = role - else: - for role_name in security_roles: - if role_name in self.security_roles: - roles.append(self.security_roles[role_name]) - continue - - try: - query = 'SecurityRole where name is "{}"'.format(role_name) - role = self.session.query(query).one() - self.security_roles[role_name] = role - roles.append(role) - except Exception: - self.log.warning( - 'Securit role "{}" does not exist'.format(role_name) - ) - continue - - return roles - - def get_role_ALL(self): - role_name = 'ALL' - if role_name in self.security_roles: - all_roles = self.security_roles[role_name] - else: - all_roles = self.session.query('SecurityRole').all() - self.security_roles[role_name] = all_roles - for role in all_roles: - if role['name'] not in self.security_roles: - self.security_roles[role['name']] = role - return all_roles - - -def register(session, plugins_presets={}): - '''Register plugin. Called when used as an plugin.''' - - CustomAttributeDoctor(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_update_from_v2-2-0.py b/pype/modules/ftrack/actions/action_update_from_v2-2-0.py deleted file mode 100644 index 805072ce5d..0000000000 --- a/pype/modules/ftrack/actions/action_update_from_v2-2-0.py +++ /dev/null @@ -1,189 +0,0 @@ -import os - -from pype.modules.ftrack import BaseAction -from pype.modules.ftrack.lib.io_nonsingleton import DbConnector - - -class PypeUpdateFromV2_2_0(BaseAction): - """This action is to remove silo field from database and changes asset - schema to newer version - - WARNING: it is NOT for situations when you want to switch from avalon-core - to Pype's avalon-core!!! - - """ - #: Action identifier. - identifier = "silos.doctor" - #: Action label. - label = "Pype Update" - variant = "- v2.2.0 to v2.3.0 or higher" - #: Action description. - description = "Use when Pype was updated from v2.2.0 to v2.3.0 or higher" - - #: roles that are allowed to register this action - role_list = ["Pypeclub", "Administrator"] - icon = "{}/ftrack/action_icons/PypeUpdate.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) - # connector to MongoDB (Avalon mongo) - db_con = DbConnector() - - def discover(self, session, entities, event): - """ Validation """ - if len(entities) != 1: - return False - - if entities[0].entity_type.lower() != "project": - return False - - return True - - def interface(self, session, entities, event): - if event['data'].get('values', {}): - return - - items = [] - item_splitter = {'type': 'label', 'value': '---'} - title = "Updated Pype from v 2.2.0 to v2.3.0 or higher" - - items.append({ - "type": "label", - "value": ( - "NOTE: This doctor action should be used ONLY when Pype" - " was updated from v2.2.0 to v2.3.0 or higher.


" - ) - }) - - items.append({ - "type": "label", - "value": ( - "Select if want to process all synchronized projects" - " or selection." - ) - }) - - items.append({ - "type": "enumerator", - "name": "__process_all__", - "data": [{ - "label": "All synchronized projects", - "value": True - }, { - "label": "Selection", - "value": False - }], - "value": False - }) - - items.append({ - "type": "label", - "value": ( - "

Synchronized projects:

" - "(ignore if \"ALL projects\" selected)" - ) - }) - - self.log.debug("Getting all Ftrack projects") - # Get all Ftrack projects - all_ftrack_projects = [ - project["full_name"] for project in session.query("Project").all() - ] - - self.log.debug("Getting Avalon projects that are also in the Ftrack") - # Get Avalon projects that are in Ftrack - self.db_con.install() - possible_projects = [ - project["name"] for project in self.db_con.projects() - if project["name"] in all_ftrack_projects - ] - - for project in possible_projects: - item_label = { - "type": "label", - "value": project - } - item = { - "label": "- process", - "name": project, - "type": 'boolean', - "value": False - } - items.append(item_splitter) - items.append(item_label) - items.append(item) - - if len(possible_projects) == 0: - return { - "success": False, - "message": ( - "Nothing to process." - " There are not projects synchronized to avalon." - ) - } - else: - return { - "items": items, - "title": title - } - - def launch(self, session, entities, event): - if 'values' not in event['data']: - return - - projects_selection = { - True: [], - False: [] - } - process_all = None - - values = event['data']['values'] - for key, value in values.items(): - if key == "__process_all__": - process_all = value - continue - - projects_selection[value].append(key) - - # Skip if process_all value is not boolean - # - may happen when user delete string line in combobox - if not isinstance(process_all, bool): - self.log.warning( - "Nothing was processed. User didn't select if want to process" - " selection or all projects!" - ) - return { - "success": False, - "message": ( - "Nothing was processed. You must select if want to process" - " \"selection\" or \"all projects\"!" - ) - } - - projects_to_process = projects_selection[True] - if process_all: - projects_to_process.extend(projects_selection[False]) - - self.db_con.install() - for project in projects_to_process: - self.log.debug("Processing project \"{}\"".format(project)) - self.db_con.Session["AVALON_PROJECT"] = project - - self.log.debug("- Unsetting silos on assets") - self.db_con.update_many( - {"type": "asset"}, - {"$unset": {"silo": ""}} - ) - - self.log.debug("- setting schema of assets to v.3") - self.db_con.update_many( - {"type": "asset"}, - {"$set": {"schema": "avalon-core:asset-3.0"}} - ) - - return True - - -def register(session, plugins_presets={}): - """Register plugin. Called when used as an plugin.""" - - PypeUpdateFromV2_2_0(session, plugins_presets).register() From 7a1b4ef35875992dc9ed6bfd576b554acd93c766 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 18:34:32 +0200 Subject: [PATCH 34/40] added statics_icon function for easier getting icon path for actions --- pype/modules/ftrack/lib/__init__.py | 3 ++- pype/modules/ftrack/lib/ftrack_action_handler.py | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pype/modules/ftrack/lib/__init__.py b/pype/modules/ftrack/lib/__init__.py index e58804440a..df546ab725 100644 --- a/pype/modules/ftrack/lib/__init__.py +++ b/pype/modules/ftrack/lib/__init__.py @@ -2,7 +2,7 @@ from . import avalon_sync from . import credentials from .ftrack_base_handler import BaseHandler from .ftrack_event_handler import BaseEvent -from .ftrack_action_handler import BaseAction +from .ftrack_action_handler import BaseAction, statics_icon from .ftrack_app_handler import AppAction __all__ = [ @@ -11,5 +11,6 @@ __all__ = [ "BaseHandler", "BaseEvent", "BaseAction", + "statics_icon", "AppAction" ] diff --git a/pype/modules/ftrack/lib/ftrack_action_handler.py b/pype/modules/ftrack/lib/ftrack_action_handler.py index 66d321316f..6629a8316b 100644 --- a/pype/modules/ftrack/lib/ftrack_action_handler.py +++ b/pype/modules/ftrack/lib/ftrack_action_handler.py @@ -1,6 +1,14 @@ +import os from .ftrack_base_handler import BaseHandler +def statics_icon(*icon_statics_file_parts): + statics_server = os.environ.get("PYPE_STATICS_SERVER") + if not statics_server: + return None + return "/".join((statics_server, *icon_statics_file_parts)) + + class BaseAction(BaseHandler): '''Custom Action base class From c7c5dfaa61a58175971b01d3a04ed89374f77e87 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 18:38:50 +0200 Subject: [PATCH 35/40] removed unsused imports or parts (most) of code --- .../actions/action_application_loader.py | 2 +- .../ftrack/actions/action_component_open.py | 42 ------------- .../modules/ftrack/actions/action_delivery.py | 1 + pype/modules/ftrack/actions/action_djvview.py | 1 - .../ftrack/actions/action_job_killer.py | 45 -------------- .../ftrack/actions/action_multiple_notes.py | 43 ------------- pype/modules/ftrack/actions/action_rv.py | 50 +--------------- pype/modules/ftrack/actions/action_seed.py | 1 + .../ftrack/actions/action_start_timer.py | 1 - pype/modules/ftrack/actions/action_test.py | 60 +------------------ .../actions/action_thumbnail_to_childern.py | 44 -------------- .../actions/action_thumbnail_to_parent.py | 43 ------------- 12 files changed, 8 insertions(+), 325 deletions(-) diff --git a/pype/modules/ftrack/actions/action_application_loader.py b/pype/modules/ftrack/actions/action_application_loader.py index 11aac28615..f578ef185f 100644 --- a/pype/modules/ftrack/actions/action_application_loader.py +++ b/pype/modules/ftrack/actions/action_application_loader.py @@ -72,7 +72,7 @@ def register(session, plugins_presets={}): for app in apps: try: registerApp(app, session, plugins_presets) - if app_counter%5 == 0: + if app_counter % 5 == 0: time.sleep(0.1) app_counter += 1 except Exception as exc: diff --git a/pype/modules/ftrack/actions/action_component_open.py b/pype/modules/ftrack/actions/action_component_open.py index aebd543769..2fe229e448 100644 --- a/pype/modules/ftrack/actions/action_component_open.py +++ b/pype/modules/ftrack/actions/action_component_open.py @@ -1,9 +1,6 @@ import os import sys -import argparse -import logging import subprocess -import ftrack_api from pype.modules.ftrack import BaseAction @@ -69,42 +66,3 @@ def register(session, plugins_presets={}): '''Register action. Called when used as an event plugin.''' ComponentOpen(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_delivery.py b/pype/modules/ftrack/actions/action_delivery.py index 1dfd3dd5d5..33cf780287 100644 --- a/pype/modules/ftrack/actions/action_delivery.py +++ b/pype/modules/ftrack/actions/action_delivery.py @@ -508,6 +508,7 @@ class Delivery(BaseAction): "message": "Delivery Finished" } + def register(session, plugins_presets={}): '''Register plugin. Called when used as an plugin.''' diff --git a/pype/modules/ftrack/actions/action_djvview.py b/pype/modules/ftrack/actions/action_djvview.py index 32c5824e0f..cf5ed61010 100644 --- a/pype/modules/ftrack/actions/action_djvview.py +++ b/pype/modules/ftrack/actions/action_djvview.py @@ -1,6 +1,5 @@ import os import sys -import json import logging import subprocess from operator import itemgetter diff --git a/pype/modules/ftrack/actions/action_job_killer.py b/pype/modules/ftrack/actions/action_job_killer.py index 064d7ed209..409a14f297 100644 --- a/pype/modules/ftrack/actions/action_job_killer.py +++ b/pype/modules/ftrack/actions/action_job_killer.py @@ -1,10 +1,5 @@ import os -import sys -import argparse -import logging import json - -import ftrack_api from pype.modules.ftrack import BaseAction @@ -124,43 +119,3 @@ def register(session, plugins_presets={}): '''Register plugin. Called when used as an plugin.''' JobKiller(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_multiple_notes.py b/pype/modules/ftrack/actions/action_multiple_notes.py index dcdb4c5dc9..52e619cb20 100644 --- a/pype/modules/ftrack/actions/action_multiple_notes.py +++ b/pype/modules/ftrack/actions/action_multiple_notes.py @@ -1,8 +1,4 @@ import os -import sys -import argparse -import logging -import ftrack_api from pype.modules.ftrack import BaseAction @@ -116,42 +112,3 @@ def register(session, plugins_presets={}): '''Register plugin. Called when used as an plugin.''' MultipleNotes(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_rv.py b/pype/modules/ftrack/actions/action_rv.py index ce2371b5b8..9b03ca7f0d 100644 --- a/pype/modules/ftrack/actions/action_rv.py +++ b/pype/modules/ftrack/actions/action_rv.py @@ -1,7 +1,5 @@ import os -import sys import subprocess -import logging import traceback import json @@ -10,8 +8,6 @@ from pype.modules.ftrack import BaseAction import ftrack_api from avalon import io, api -log = Logger().get_logger(__name__) - class RVAction(BaseAction): """ Launch RV action """ @@ -144,7 +140,7 @@ class RVAction(BaseAction): try: items = self.get_interface_items(session, entities) except Exception: - log.error(traceback.format_exc()) + self.log.error(traceback.format_exc()) job["status"] = "failed" else: job["status"] = "done" @@ -238,7 +234,7 @@ class RVAction(BaseAction): try: paths = self.get_file_paths(session, event) except Exception: - log.error(traceback.format_exc()) + self.log.error(traceback.format_exc()) job["status"] = "failed" else: job["status"] = "done" @@ -254,7 +250,7 @@ class RVAction(BaseAction): args.extend(paths) - log.info("Running rv: {}".format(args)) + self.log.info("Running rv: {}".format(args)) subprocess.Popen(args) @@ -332,43 +328,3 @@ def register(session, plugins_presets={}): """Register hooks.""" RVAction(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - import argparse - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_seed.py b/pype/modules/ftrack/actions/action_seed.py index 72625c13e4..e0fbdde375 100644 --- a/pype/modules/ftrack/actions/action_seed.py +++ b/pype/modules/ftrack/actions/action_seed.py @@ -429,6 +429,7 @@ class SeedDebugProject(BaseAction): self.session.commit() return True + def register(session, plugins_presets={}): '''Register plugin. Called when used as an plugin.''' diff --git a/pype/modules/ftrack/actions/action_start_timer.py b/pype/modules/ftrack/actions/action_start_timer.py index 3e5cf0d4c1..0ef6d8b111 100644 --- a/pype/modules/ftrack/actions/action_start_timer.py +++ b/pype/modules/ftrack/actions/action_start_timer.py @@ -1,4 +1,3 @@ -import ftrack_api from pype.modules.ftrack import BaseAction diff --git a/pype/modules/ftrack/actions/action_test.py b/pype/modules/ftrack/actions/action_test.py index 784bf80944..8651e059d8 100644 --- a/pype/modules/ftrack/actions/action_test.py +++ b/pype/modules/ftrack/actions/action_test.py @@ -1,37 +1,22 @@ import os -import sys -import argparse -import logging -import collections -import json -import re - -import ftrack_api -from avalon import io, inventory, schema from pype.modules.ftrack import BaseAction class TestAction(BaseAction): - '''Edit meta data action.''' + """Action for testing purpose or as base for new actions.""" ignore_me = True - #: Action identifier. + identifier = 'test.action' - #: Action label. label = 'Test action' - #: Action description. description = 'Test action' - #: priority priority = 10000 - #: roles that are allowed to register this action role_list = ['Pypeclub'] icon = '{}/ftrack/action_icons/TestAction.svg'.format( os.environ.get('PYPE_STATICS_SERVER', '') ) def discover(self, session, entities, event): - ''' Validation ''' - return True def launch(self, session, entities, event): @@ -41,45 +26,4 @@ class TestAction(BaseAction): def register(session, plugins_presets={}): - '''Register plugin. Called when used as an plugin.''' - TestAction(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_thumbnail_to_childern.py b/pype/modules/ftrack/actions/action_thumbnail_to_childern.py index e194134694..7bcd0074ff 100644 --- a/pype/modules/ftrack/actions/action_thumbnail_to_childern.py +++ b/pype/modules/ftrack/actions/action_thumbnail_to_childern.py @@ -1,10 +1,5 @@ import os -import sys -import argparse -import logging import json - -import ftrack_api from pype.modules.ftrack import BaseAction @@ -71,42 +66,3 @@ def register(session, plugins_presets={}): '''Register action. Called when used as an event plugin.''' ThumbToChildren(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) diff --git a/pype/modules/ftrack/actions/action_thumbnail_to_parent.py b/pype/modules/ftrack/actions/action_thumbnail_to_parent.py index 86ada64e5a..5c3d557814 100644 --- a/pype/modules/ftrack/actions/action_thumbnail_to_parent.py +++ b/pype/modules/ftrack/actions/action_thumbnail_to_parent.py @@ -1,9 +1,5 @@ import os -import sys -import argparse -import logging import json -import ftrack_api from pype.modules.ftrack import BaseAction @@ -93,42 +89,3 @@ def register(session, plugins_presets={}): '''Register action. Called when used as an event plugin.''' ThumbToParent(session, plugins_presets).register() - - -def main(arguments=None): - '''Set up logging and register action.''' - if arguments is None: - arguments = [] - - parser = argparse.ArgumentParser() - # Allow setting of logging level from arguments. - loggingLevels = {} - for level in ( - logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING, - logging.ERROR, logging.CRITICAL - ): - loggingLevels[logging.getLevelName(level).lower()] = level - - parser.add_argument( - '-v', '--verbosity', - help='Set the logging output verbosity.', - choices=loggingLevels.keys(), - default='info' - ) - namespace = parser.parse_args(arguments) - - # Set up basic logging - logging.basicConfig(level=loggingLevels[namespace.verbosity]) - - session = ftrack_api.Session() - register(session) - - # Wait for events - logging.info( - 'Registered actions and listening for events. Use Ctrl-C to abort.' - ) - session.event_hub.wait() - - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:])) From 57f4dbe3fcfc180ce32bc97a1b65be13ebbe192c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 18:45:05 +0200 Subject: [PATCH 36/40] using statics_icon for icons from statics server and imports from ftrack.lib are explicit now --- pype/modules/ftrack/actions/action_application_loader.py | 2 +- .../actions/action_clean_hierarchical_attributes.py | 7 ++----- pype/modules/ftrack/actions/action_client_review_sort.py | 2 +- pype/modules/ftrack/actions/action_component_open.py | 6 ++---- pype/modules/ftrack/actions/action_create_cust_attrs.py | 7 ++----- pype/modules/ftrack/actions/action_create_folders.py | 6 ++---- .../ftrack/actions/action_create_project_structure.py | 6 ++---- pype/modules/ftrack/actions/action_delete_asset.py | 7 ++----- .../modules/ftrack/actions/action_delete_old_versions.py | 6 ++---- pype/modules/ftrack/actions/action_delivery.py | 6 ++---- pype/modules/ftrack/actions/action_djvview.py | 7 +++---- pype/modules/ftrack/actions/action_job_killer.py | 7 ++----- pype/modules/ftrack/actions/action_multiple_notes.py | 8 ++------ pype/modules/ftrack/actions/action_prepare_project.py | 6 ++---- pype/modules/ftrack/actions/action_rv.py | 9 ++++----- pype/modules/ftrack/actions/action_seed.py | 6 ++---- pype/modules/ftrack/actions/action_start_timer.py | 2 +- .../ftrack/actions/action_store_thumbnails_to_avalon.py | 7 ++----- pype/modules/ftrack/actions/action_sync_to_avalon.py | 7 ++----- pype/modules/ftrack/actions/action_test.py | 7 ++----- .../ftrack/actions/action_thumbnail_to_childern.py | 7 ++----- .../modules/ftrack/actions/action_thumbnail_to_parent.py | 7 ++----- pype/modules/ftrack/actions/action_where_run_ask.py | 7 ++----- pype/modules/ftrack/actions/action_where_run_show.py | 3 +-- 24 files changed, 47 insertions(+), 98 deletions(-) diff --git a/pype/modules/ftrack/actions/action_application_loader.py b/pype/modules/ftrack/actions/action_application_loader.py index f578ef185f..ec7fc53fb6 100644 --- a/pype/modules/ftrack/actions/action_application_loader.py +++ b/pype/modules/ftrack/actions/action_application_loader.py @@ -1,7 +1,7 @@ import os import toml import time -from pype.modules.ftrack import AppAction +from pype.modules.ftrack.lib import AppAction from avalon import lib from pype.api import Logger from pype.lib import get_all_avalon_projects diff --git a/pype/modules/ftrack/actions/action_clean_hierarchical_attributes.py b/pype/modules/ftrack/actions/action_clean_hierarchical_attributes.py index 0319528319..86503ff5bc 100644 --- a/pype/modules/ftrack/actions/action_clean_hierarchical_attributes.py +++ b/pype/modules/ftrack/actions/action_clean_hierarchical_attributes.py @@ -1,7 +1,6 @@ -import os import collections import ftrack_api -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.avalon_sync import get_avalon_attr @@ -11,9 +10,7 @@ class CleanHierarchicalAttrsAction(BaseAction): variant = "- Clean hierarchical custom attributes" description = "Unset empty hierarchical attribute values." role_list = ["Pypeclub", "Administrator", "Project Manager"] - icon = "{}/ftrack/action_icons/PypeAdmin.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg") all_project_entities_query = ( "select id, name, parent_id, link" diff --git a/pype/modules/ftrack/actions/action_client_review_sort.py b/pype/modules/ftrack/actions/action_client_review_sort.py index 1909c31759..72387fe695 100644 --- a/pype/modules/ftrack/actions/action_client_review_sort.py +++ b/pype/modules/ftrack/actions/action_client_review_sort.py @@ -1,4 +1,4 @@ -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction try: from functools import cmp_to_key except Exception: diff --git a/pype/modules/ftrack/actions/action_component_open.py b/pype/modules/ftrack/actions/action_component_open.py index 2fe229e448..5fe8fe831b 100644 --- a/pype/modules/ftrack/actions/action_component_open.py +++ b/pype/modules/ftrack/actions/action_component_open.py @@ -1,7 +1,7 @@ import os import sys import subprocess -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class ComponentOpen(BaseAction): @@ -12,9 +12,7 @@ class ComponentOpen(BaseAction): # Action label label = 'Open File' # Action icon - icon = '{}/ftrack/action_icons/ComponentOpen.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "ComponentOpen.svg") def discover(self, session, entities, event): ''' Validation ''' diff --git a/pype/modules/ftrack/actions/action_create_cust_attrs.py b/pype/modules/ftrack/actions/action_create_cust_attrs.py index 6e9827a231..9845cc8876 100644 --- a/pype/modules/ftrack/actions/action_create_cust_attrs.py +++ b/pype/modules/ftrack/actions/action_create_cust_attrs.py @@ -1,9 +1,8 @@ -import os import collections import json import arrow import ftrack_api -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.avalon_sync import CustAttrIdKey from pype.api import config @@ -114,9 +113,7 @@ class CustomAttributes(BaseAction): description = 'Creates Avalon/Mongo ID for double check' #: roles that are allowed to register this action role_list = ['Pypeclub', 'Administrator'] - icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg") required_keys = ['key', 'label', 'type'] type_posibilities = [ diff --git a/pype/modules/ftrack/actions/action_create_folders.py b/pype/modules/ftrack/actions/action_create_folders.py index 9146c54fad..e689e0260c 100644 --- a/pype/modules/ftrack/actions/action_create_folders.py +++ b/pype/modules/ftrack/actions/action_create_folders.py @@ -1,5 +1,5 @@ import os -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from avalon import lib as avalonlib from pype.api import config, Anatomy @@ -7,9 +7,7 @@ from pype.api import config, Anatomy class CreateFolders(BaseAction): identifier = "create.folders" label = "Create Folders" - icon = "{}/ftrack/action_icons/CreateFolders.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "CreateFolders.svg") def discover(self, session, entities, event): if len(entities) != 1: diff --git a/pype/modules/ftrack/actions/action_create_project_structure.py b/pype/modules/ftrack/actions/action_create_project_structure.py index 526cf172bf..22190c16db 100644 --- a/pype/modules/ftrack/actions/action_create_project_structure.py +++ b/pype/modules/ftrack/actions/action_create_project_structure.py @@ -1,7 +1,7 @@ import os import re -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.api import config, Anatomy @@ -52,9 +52,7 @@ class CreateProjectFolders(BaseAction): label = "Create Project Structure" description = "Creates folder structure" role_list = ["Pypeclub", "Administrator", "Project Manager"] - icon = "{}/ftrack/action_icons/CreateProjectFolders.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "CreateProjectFolders.svg") pattern_array = re.compile(r"\[.*\]") pattern_ftrack = re.compile(r".*\[[.]*ftrack[.]*") diff --git a/pype/modules/ftrack/actions/action_delete_asset.py b/pype/modules/ftrack/actions/action_delete_asset.py index d4f6eb6594..1074efee3b 100644 --- a/pype/modules/ftrack/actions/action_delete_asset.py +++ b/pype/modules/ftrack/actions/action_delete_asset.py @@ -1,11 +1,10 @@ -import os import collections import uuid from datetime import datetime from queue import Queue from bson.objectid import ObjectId -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.io_nonsingleton import DbConnector @@ -18,9 +17,7 @@ class DeleteAssetSubset(BaseAction): label = "Delete Asset/Subsets" #: Action description. description = "Removes from Avalon with all childs and asset from Ftrack" - icon = "{}/ftrack/action_icons/DeleteAsset.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "DeleteAsset.svg") #: roles that are allowed to register this action role_list = ["Pypeclub", "Administrator", "Project Manager"] #: Db connection diff --git a/pype/modules/ftrack/actions/action_delete_old_versions.py b/pype/modules/ftrack/actions/action_delete_old_versions.py index 00432d5c3f..46652b136a 100644 --- a/pype/modules/ftrack/actions/action_delete_old_versions.py +++ b/pype/modules/ftrack/actions/action_delete_old_versions.py @@ -5,7 +5,7 @@ import uuid import clique from pymongo import UpdateOne -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.io_nonsingleton import DbConnector from pype.api import Anatomy @@ -22,9 +22,7 @@ class DeleteOldVersions(BaseAction): " archived with only lates versions." ) role_list = ["Pypeclub", "Project Manager", "Administrator"] - icon = "{}/ftrack/action_icons/PypeAdmin.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg") dbcon = DbConnector() diff --git a/pype/modules/ftrack/actions/action_delivery.py b/pype/modules/ftrack/actions/action_delivery.py index 33cf780287..23c79cfc39 100644 --- a/pype/modules/ftrack/actions/action_delivery.py +++ b/pype/modules/ftrack/actions/action_delivery.py @@ -11,7 +11,7 @@ from avalon.vendor import filelink from avalon.tools.libraryloader.io_nonsingleton import DbConnector from pype.api import Anatomy -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.avalon_sync import CustAttrIdKey @@ -21,9 +21,7 @@ class Delivery(BaseAction): label = "Delivery" description = "Deliver data to client" role_list = ["Pypeclub", "Administrator", "Project manager"] - icon = "{}/ftrack/action_icons/Delivery.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "Delivery.svg") db_con = DbConnector() diff --git a/pype/modules/ftrack/actions/action_djvview.py b/pype/modules/ftrack/actions/action_djvview.py index cf5ed61010..9708503ad1 100644 --- a/pype/modules/ftrack/actions/action_djvview.py +++ b/pype/modules/ftrack/actions/action_djvview.py @@ -4,7 +4,7 @@ import logging import subprocess from operator import itemgetter import ftrack_api -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.api import Logger, config log = Logger().get_logger(__name__) @@ -15,9 +15,8 @@ class DJVViewAction(BaseAction): identifier = "djvview-launch-action" label = "DJV View" description = "DJV View Launcher" - icon = '{}/app_icons/djvView.png'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("app_icons", "djvView.png") + type = 'Application' def __init__(self, session, plugins_presets): diff --git a/pype/modules/ftrack/actions/action_job_killer.py b/pype/modules/ftrack/actions/action_job_killer.py index 409a14f297..ff23da2a54 100644 --- a/pype/modules/ftrack/actions/action_job_killer.py +++ b/pype/modules/ftrack/actions/action_job_killer.py @@ -1,6 +1,5 @@ -import os import json -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class JobKiller(BaseAction): @@ -15,9 +14,7 @@ class JobKiller(BaseAction): description = 'Killing selected running jobs' #: roles that are allowed to register this action role_list = ['Pypeclub', 'Administrator'] - icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg") def discover(self, session, entities, event): ''' Validation ''' diff --git a/pype/modules/ftrack/actions/action_multiple_notes.py b/pype/modules/ftrack/actions/action_multiple_notes.py index 52e619cb20..c1a5cc6ce0 100644 --- a/pype/modules/ftrack/actions/action_multiple_notes.py +++ b/pype/modules/ftrack/actions/action_multiple_notes.py @@ -1,6 +1,4 @@ -import os - -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class MultipleNotes(BaseAction): @@ -12,9 +10,7 @@ class MultipleNotes(BaseAction): label = 'Multiple Notes' #: Action description. description = 'Add same note to multiple Asset Versions' - icon = '{}/ftrack/action_icons/MultipleNotes.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "MultipleNotes.svg") def discover(self, session, entities, event): ''' Validation ''' diff --git a/pype/modules/ftrack/actions/action_prepare_project.py b/pype/modules/ftrack/actions/action_prepare_project.py index 31cc802109..f51a9eb9a6 100644 --- a/pype/modules/ftrack/actions/action_prepare_project.py +++ b/pype/modules/ftrack/actions/action_prepare_project.py @@ -1,7 +1,7 @@ import os import json -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.api import config, Anatomy, project_overrides_dir_path from pype.modules.ftrack.lib.avalon_sync import get_avalon_attr @@ -17,9 +17,7 @@ class PrepareProject(BaseAction): description = 'Set basic attributes on the project' #: roles that are allowed to register this action role_list = ["Pypeclub", "Administrator", "Project manager"] - icon = '{}/ftrack/action_icons/PrepareProject.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "PrepareProject.svg") # Key to store info about trigerring create folder structure create_project_structure_key = "create_folder_structure" diff --git a/pype/modules/ftrack/actions/action_rv.py b/pype/modules/ftrack/actions/action_rv.py index 9b03ca7f0d..528eeeee07 100644 --- a/pype/modules/ftrack/actions/action_rv.py +++ b/pype/modules/ftrack/actions/action_rv.py @@ -3,8 +3,8 @@ import subprocess import traceback import json -from pype.api import Logger, config -from pype.modules.ftrack import BaseAction +from pype.api import config +from pype.modules.ftrack.lib import BaseAction, statics_icon import ftrack_api from avalon import io, api @@ -15,9 +15,8 @@ class RVAction(BaseAction): identifier = "rv.launch.action" label = "rv" description = "rv Launcher" - icon = '{}/ftrack/action_icons/RV.png'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "RV.png") + type = 'Application' def __init__(self, session, plugins_presets): diff --git a/pype/modules/ftrack/actions/action_seed.py b/pype/modules/ftrack/actions/action_seed.py index e0fbdde375..d6288a03aa 100644 --- a/pype/modules/ftrack/actions/action_seed.py +++ b/pype/modules/ftrack/actions/action_seed.py @@ -1,6 +1,6 @@ import os from operator import itemgetter -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class SeedDebugProject(BaseAction): @@ -16,9 +16,7 @@ class SeedDebugProject(BaseAction): priority = 100 #: roles that are allowed to register this action role_list = ["Pypeclub"] - icon = "{}/ftrack/action_icons/SeedProject.svg".format( - os.environ.get("PYPE_STATICS_SERVER", "") - ) + icon = statics_icon("ftrack", "action_icons", "SeedProject.svg") # Asset names which will be created in `Assets` entity assets = [ diff --git a/pype/modules/ftrack/actions/action_start_timer.py b/pype/modules/ftrack/actions/action_start_timer.py index 0ef6d8b111..6e8fcb29e2 100644 --- a/pype/modules/ftrack/actions/action_start_timer.py +++ b/pype/modules/ftrack/actions/action_start_timer.py @@ -1,4 +1,4 @@ -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction class StartTimer(BaseAction): diff --git a/pype/modules/ftrack/actions/action_store_thumbnails_to_avalon.py b/pype/modules/ftrack/actions/action_store_thumbnails_to_avalon.py index 180d6ae03c..b399dab7ce 100644 --- a/pype/modules/ftrack/actions/action_store_thumbnails_to_avalon.py +++ b/pype/modules/ftrack/actions/action_store_thumbnails_to_avalon.py @@ -4,7 +4,7 @@ import errno import json from bson.objectid import ObjectId -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.api import Anatomy from pype.modules.ftrack.lib.io_nonsingleton import DbConnector @@ -22,10 +22,7 @@ class StoreThumbnailsToAvalon(BaseAction): 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', '') - ) + icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg") thumbnail_key = "AVALON_THUMBNAIL_ROOT" db_con = DbConnector() diff --git a/pype/modules/ftrack/actions/action_sync_to_avalon.py b/pype/modules/ftrack/actions/action_sync_to_avalon.py index 8c6519e4dc..dfe1f2c464 100644 --- a/pype/modules/ftrack/actions/action_sync_to_avalon.py +++ b/pype/modules/ftrack/actions/action_sync_to_avalon.py @@ -1,8 +1,7 @@ -import os import time import traceback -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.avalon_sync import SyncEntitiesFactory @@ -43,9 +42,7 @@ class SyncToAvalonLocal(BaseAction): priority = 200 #: roles that are allowed to register this action role_list = ["Pypeclub"] - icon = '{}/ftrack/action_icons/PypeAdmin.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "PypeAdmin.svg") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/pype/modules/ftrack/actions/action_test.py b/pype/modules/ftrack/actions/action_test.py index 8651e059d8..e4936274b3 100644 --- a/pype/modules/ftrack/actions/action_test.py +++ b/pype/modules/ftrack/actions/action_test.py @@ -1,5 +1,4 @@ -import os -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class TestAction(BaseAction): @@ -12,9 +11,7 @@ class TestAction(BaseAction): description = 'Test action' priority = 10000 role_list = ['Pypeclub'] - icon = '{}/ftrack/action_icons/TestAction.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "TestAction.svg") def discover(self, session, entities, event): return True diff --git a/pype/modules/ftrack/actions/action_thumbnail_to_childern.py b/pype/modules/ftrack/actions/action_thumbnail_to_childern.py index 7bcd0074ff..3c6af10b43 100644 --- a/pype/modules/ftrack/actions/action_thumbnail_to_childern.py +++ b/pype/modules/ftrack/actions/action_thumbnail_to_childern.py @@ -1,6 +1,5 @@ -import os import json -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class ThumbToChildren(BaseAction): @@ -13,9 +12,7 @@ class ThumbToChildren(BaseAction): # Action variant variant = " to Children" # Action icon - icon = '{}/ftrack/action_icons/Thumbnail.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "Thumbnail.svg") def discover(self, session, entities, event): ''' Validation ''' diff --git a/pype/modules/ftrack/actions/action_thumbnail_to_parent.py b/pype/modules/ftrack/actions/action_thumbnail_to_parent.py index 5c3d557814..8710fa9dcf 100644 --- a/pype/modules/ftrack/actions/action_thumbnail_to_parent.py +++ b/pype/modules/ftrack/actions/action_thumbnail_to_parent.py @@ -1,6 +1,5 @@ -import os import json -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class ThumbToParent(BaseAction): @@ -13,9 +12,7 @@ class ThumbToParent(BaseAction): # Action variant variant = " to Parent" # Action icon - icon = '{}/ftrack/action_icons/Thumbnail.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "Thumbnail.svg") def discover(self, session, entities, event): '''Return action config if triggered on asset versions.''' diff --git a/pype/modules/ftrack/actions/action_where_run_ask.py b/pype/modules/ftrack/actions/action_where_run_ask.py index d7bc8b11f9..ddc893856d 100644 --- a/pype/modules/ftrack/actions/action_where_run_ask.py +++ b/pype/modules/ftrack/actions/action_where_run_ask.py @@ -1,5 +1,4 @@ -import os -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction, statics_icon class ActionAskWhereIRun(BaseAction): @@ -15,9 +14,7 @@ class ActionAskWhereIRun(BaseAction): #: Action description. description = 'Triggers PC info where user have running Pype' #: Action icon - icon = '{}/ftrack/action_icons/ActionAskWhereIRun.svg'.format( - os.environ.get('PYPE_STATICS_SERVER', '') - ) + icon = statics_icon("ftrack", "action_icons", "ActionAskWhereIRun.svg") def discover(self, session, entities, event): """ Hide by default - Should be enabled only if you want to run. diff --git a/pype/modules/ftrack/actions/action_where_run_show.py b/pype/modules/ftrack/actions/action_where_run_show.py index c7abccb8c9..a084547a45 100644 --- a/pype/modules/ftrack/actions/action_where_run_show.py +++ b/pype/modules/ftrack/actions/action_where_run_show.py @@ -1,8 +1,7 @@ import platform import socket import getpass -import ftrack_api -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack.lib import BaseAction class ActionShowWhereIRun(BaseAction): From d72b8b4ce2d8ed9bc27c0b2de3fbf95f28584f29 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 18:45:37 +0200 Subject: [PATCH 37/40] io_nonsingleton is imported from ftrack lib instead of from library loader --- pype/modules/ftrack/actions/action_delivery.py | 2 +- pype/modules/ftrack/actions/action_where_run_ask.py | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/pype/modules/ftrack/actions/action_delivery.py b/pype/modules/ftrack/actions/action_delivery.py index 23c79cfc39..a2048222e5 100644 --- a/pype/modules/ftrack/actions/action_delivery.py +++ b/pype/modules/ftrack/actions/action_delivery.py @@ -8,11 +8,11 @@ from bson.objectid import ObjectId from avalon import pipeline from avalon.vendor import filelink -from avalon.tools.libraryloader.io_nonsingleton import DbConnector from pype.api import Anatomy from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.avalon_sync import CustAttrIdKey +from pype.modules.ftrack.lib.io_nonsingleton import DbConnector class Delivery(BaseAction): diff --git a/pype/modules/ftrack/actions/action_where_run_ask.py b/pype/modules/ftrack/actions/action_where_run_ask.py index ddc893856d..42640fb506 100644 --- a/pype/modules/ftrack/actions/action_where_run_ask.py +++ b/pype/modules/ftrack/actions/action_where_run_ask.py @@ -5,15 +5,10 @@ class ActionAskWhereIRun(BaseAction): """ Sometimes user forget where pipeline with his credentials is running. - this action triggers `ActionShowWhereIRun` """ - # Action is ignored by default ignore_me = True - #: Action identifier. identifier = 'ask.where.i.run' - #: Action label. label = 'Ask where I run' - #: Action description. description = 'Triggers PC info where user have running Pype' - #: Action icon icon = statics_icon("ftrack", "action_icons", "ActionAskWhereIRun.svg") def discover(self, session, entities, event): From 5789edfd7c6ff65a05b0b126442da3c2937b3f1b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 18:45:53 +0200 Subject: [PATCH 38/40] fix formatting --- pype/modules/ftrack/lib/ftrack_action_handler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/modules/ftrack/lib/ftrack_action_handler.py b/pype/modules/ftrack/lib/ftrack_action_handler.py index 6629a8316b..76c8e41411 100644 --- a/pype/modules/ftrack/lib/ftrack_action_handler.py +++ b/pype/modules/ftrack/lib/ftrack_action_handler.py @@ -185,7 +185,9 @@ class BaseAction(BaseHandler): else: for key in ('success', 'message'): if key not in result: - raise KeyError('Missing required key: {0}.'.format(key)) + raise KeyError( + "Missing required key: {0}.".format(key) + ) return result self.log.warning(( From 2b4ddef412caab3cbac91900b00d390109bb2323 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 4 Jun 2020 18:48:25 +0200 Subject: [PATCH 39/40] fix custom db connector --- pype/modules/ftrack/lib/custom_db_connector.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/pype/modules/ftrack/lib/custom_db_connector.py b/pype/modules/ftrack/lib/custom_db_connector.py index 8e8eab8740..b307117127 100644 --- a/pype/modules/ftrack/lib/custom_db_connector.py +++ b/pype/modules/ftrack/lib/custom_db_connector.py @@ -5,27 +5,20 @@ Copy of io module in avalon-core. - In this case not working as singleton with api.Session! """ -import os import time -import errno -import shutil import logging -import tempfile import functools -import contextlib import atexit -import requests - # Third-party dependencies import pymongo -from pymongo.client_session import ClientSession + class NotActiveTable(Exception): def __init__(self, *args, **kwargs): msg = "Active table is not set. (This is bug)" if not (args or kwargs): - args = (default_message,) + args = [msg] super().__init__(*args, **kwargs) @@ -120,7 +113,7 @@ class DbConnector: else: raise IOError( "ERROR: Couldn't connect to %s in " - "less than %.3f ms" % (self._mongo_url, timeout) + "less than %.3f ms" % (self._mongo_url, self.timeout) ) self.log.info("Connected to %s, delay %.3f s" % ( From d8e21118509c2004249d21fd99a9a69732d2b029 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 5 Jun 2020 14:43:02 +0100 Subject: [PATCH 40/40] Implementation of layout asset for Blender --- pype/plugins/blender/create/create_layout.py | 52 ++++ pype/plugins/blender/load/load_layout.py | 259 ++++++++++++++++++ pype/plugins/blender/publish/extract_blend.py | 2 +- 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 pype/plugins/blender/create/create_layout.py create mode 100644 pype/plugins/blender/load/load_layout.py diff --git a/pype/plugins/blender/create/create_layout.py b/pype/plugins/blender/create/create_layout.py new file mode 100644 index 0000000000..2d2b0e72ca --- /dev/null +++ b/pype/plugins/blender/create/create_layout.py @@ -0,0 +1,52 @@ +"""Create a layout asset.""" + +import bpy + +from avalon import api +from avalon.blender import Creator, lib +import pype.hosts.blender.plugin + + +class CreateLayout(Creator): + """Layout output for character rigs""" + + name = "layoutMain" + label = "Layout" + family = "layout" + icon = "cubes" + + def process(self): + + asset = self.data["asset"] + subset = self.data["subset"] + name = pype.hosts.blender.plugin.asset_name(asset, subset) + collection = bpy.data.collections.new(name=name) + bpy.context.scene.collection.children.link(collection) + self.data['task'] = api.Session.get('AVALON_TASK') + lib.imprint(collection, self.data) + + # Add the rig object and all the children meshes to + # a set and link them all at the end to avoid duplicates. + # Blender crashes if trying to link an object that is already linked. + # This links automatically the children meshes if they were not + # selected, and doesn't link them twice if they, insted, + # were manually selected by the user. + objects_to_link = set() + + if (self.options or {}).get("useSelection"): + + for obj in lib.get_selection(): + + objects_to_link.add(obj) + + if obj.type == 'ARMATURE': + + for subobj in obj.children: + + objects_to_link.add(subobj) + + for obj in objects_to_link: + + collection.objects.link(obj) + + return collection diff --git a/pype/plugins/blender/load/load_layout.py b/pype/plugins/blender/load/load_layout.py new file mode 100644 index 0000000000..9158f71c75 --- /dev/null +++ b/pype/plugins/blender/load/load_layout.py @@ -0,0 +1,259 @@ +"""Load a layout in Blender.""" + +import logging +from pathlib import Path +from pprint import pformat +from typing import Dict, List, Optional + +from avalon import api, blender +import bpy +import pype.hosts.blender.plugin + + +logger = logging.getLogger("pype").getChild( + "blender").getChild("load_layout") + + +class BlendLayoutLoader(pype.hosts.blender.plugin.AssetLoader): + """Load animations from a .blend file. + + Warning: + Loading the same asset more then once is not properly supported at the + moment. + """ + + families = ["layout"] + representations = ["blend"] + + label = "Link Layout" + icon = "code-fork" + color = "orange" + + @staticmethod + def _remove(self, objects, lib_container): + + for obj in objects: + + if obj.type == 'ARMATURE': + bpy.data.armatures.remove(obj.data) + elif obj.type == 'MESH': + bpy.data.meshes.remove(obj.data) + + bpy.data.collections.remove(bpy.data.collections[lib_container]) + + @staticmethod + def _process(self, libpath, lib_container, container_name, actions): + + relative = bpy.context.preferences.filepaths.use_relative_paths + with bpy.data.libraries.load( + libpath, link=True, relative=relative + ) as (_, data_to): + data_to.collections = [lib_container] + + scene = bpy.context.scene + + scene.collection.children.link(bpy.data.collections[lib_container]) + + layout_container = scene.collection.children[lib_container].make_local() + + meshes = [ + obj for obj in layout_container.objects if obj.type == 'MESH'] + armatures = [ + obj for obj in layout_container.objects if obj.type == 'ARMATURE'] + + objects_list = [] + + # Link meshes first, then armatures. + # The armature is unparented for all the non-local meshes, + # when it is made local. + for obj in meshes + armatures: + + obj = obj.make_local() + + obj.data.make_local() + + if not obj.get(blender.pipeline.AVALON_PROPERTY): + + obj[blender.pipeline.AVALON_PROPERTY] = dict() + + avalon_info = obj[blender.pipeline.AVALON_PROPERTY] + avalon_info.update({"container_name": container_name}) + + action = actions.get( obj.name, None ) + + if obj.type == 'ARMATURE' and action is not None: + + obj.animation_data.action = action + + objects_list.append(obj) + + layout_container.pop(blender.pipeline.AVALON_PROPERTY) + + bpy.ops.object.select_all(action='DESELECT') + + return objects_list + + def process_asset( + self, context: dict, name: str, namespace: Optional[str] = None, + options: Optional[Dict] = None + ) -> Optional[List]: + """ + Arguments: + name: Use pre-defined name + namespace: Use pre-defined namespace + context: Full parenthood of representation to load + options: Additional settings dictionary + """ + + libpath = self.fname + asset = context["asset"]["name"] + subset = context["subset"]["name"] + lib_container = pype.hosts.blender.plugin.asset_name(asset, subset) + container_name = pype.hosts.blender.plugin.asset_name( + asset, subset, namespace + ) + + container = bpy.data.collections.new(lib_container) + container.name = container_name + blender.pipeline.containerise_existing( + container, + name, + namespace, + context, + self.__class__.__name__, + ) + + container_metadata = container.get( + blender.pipeline.AVALON_PROPERTY) + + container_metadata["libpath"] = libpath + container_metadata["lib_container"] = lib_container + + objects_list = self._process( + self, libpath, lib_container, container_name, {}) + + # Save the list of objects in the metadata container + container_metadata["objects"] = objects_list + + nodes = list(container.objects) + nodes.append(container) + self[:] = nodes + return nodes + + def update(self, container: Dict, representation: Dict): + """Update the loaded asset. + + This will remove all objects of the current collection, load the new + ones and add them to the collection. + If the objects of the collection are used in another collection they + will not be removed, only unlinked. Normally this should not be the + case though. + + Warning: + No nested collections are supported at the moment! + """ + + collection = bpy.data.collections.get( + container["objectName"] + ) + + libpath = Path(api.get_representation_path(representation)) + extension = libpath.suffix.lower() + + logger.info( + "Container: %s\nRepresentation: %s", + pformat(container, indent=2), + pformat(representation, indent=2), + ) + + assert collection, ( + f"The asset is not loaded: {container['objectName']}" + ) + assert not (collection.children), ( + "Nested collections are not supported." + ) + assert libpath, ( + "No existing library file found for {container['objectName']}" + ) + assert libpath.is_file(), ( + f"The file doesn't exist: {libpath}" + ) + assert extension in pype.hosts.blender.plugin.VALID_EXTENSIONS, ( + f"Unsupported file: {libpath}" + ) + + collection_metadata = collection.get( + blender.pipeline.AVALON_PROPERTY) + + collection_libpath = collection_metadata["libpath"] + normalized_collection_libpath = ( + str(Path(bpy.path.abspath(collection_libpath)).resolve()) + ) + normalized_libpath = ( + str(Path(bpy.path.abspath(str(libpath))).resolve()) + ) + logger.debug( + "normalized_collection_libpath:\n %s\nnormalized_libpath:\n %s", + normalized_collection_libpath, + normalized_libpath, + ) + if normalized_collection_libpath == normalized_libpath: + logger.info("Library already loaded, not updating...") + return + + objects = collection_metadata["objects"] + lib_container = collection_metadata["lib_container"] + + actions = {} + + for obj in objects: + + if obj.type == 'ARMATURE': + + actions[obj.name] = obj.animation_data.action + + self._remove(self, objects, lib_container) + + objects_list = self._process( + self, str(libpath), lib_container, collection.name, actions) + + # Save the list of objects in the metadata container + collection_metadata["objects"] = objects_list + collection_metadata["libpath"] = str(libpath) + collection_metadata["representation"] = str(representation["_id"]) + + bpy.ops.object.select_all(action='DESELECT') + + def remove(self, container: Dict) -> bool: + """Remove an existing container from a Blender scene. + + Arguments: + container (avalon-core:container-1.0): Container to remove, + from `host.ls()`. + + Returns: + bool: Whether the container was deleted. + + Warning: + No nested collections are supported at the moment! + """ + + collection = bpy.data.collections.get( + container["objectName"] + ) + if not collection: + return False + assert not (collection.children), ( + "Nested collections are not supported." + ) + + collection_metadata = collection.get( + blender.pipeline.AVALON_PROPERTY) + objects = collection_metadata["objects"] + lib_container = collection_metadata["lib_container"] + + self._remove(self, objects, lib_container) + + bpy.data.collections.remove(collection) + + return True diff --git a/pype/plugins/blender/publish/extract_blend.py b/pype/plugins/blender/publish/extract_blend.py index 5f3fdac293..0924763f12 100644 --- a/pype/plugins/blender/publish/extract_blend.py +++ b/pype/plugins/blender/publish/extract_blend.py @@ -9,7 +9,7 @@ class ExtractBlend(pype.api.Extractor): label = "Extract Blend" hosts = ["blender"] - families = ["animation", "model", "rig", "action"] + families = ["animation", "model", "rig", "action", "layout"] optional = True def process(self, instance):

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