Merge pull request #4916 from movalex/enhancement/resolve-prelaunch-code-refactoring

@movalex thanks for the contribution!
This commit is contained in:
Jakub Ježek 2023-05-23 13:58:54 +02:00 committed by GitHub
commit d55211c337
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 61 deletions

View file

@ -1,4 +1,5 @@
import os import os
from pathlib import Path
import platform import platform
from openpype.lib import PreLaunchHook from openpype.lib import PreLaunchHook
from openpype.hosts.resolve.utils import setup from openpype.hosts.resolve.utils import setup
@ -6,33 +7,57 @@ from openpype.hosts.resolve.utils import setup
class ResolvePrelaunch(PreLaunchHook): class ResolvePrelaunch(PreLaunchHook):
""" """
This hook will check if current workfile path has Resolve This hook will set up the Resolve scripting environment as described in
project inside. IF not, it initialize it and finally it pass Resolve's documentation found with the installed application at
path to the project by environment variable to Premiere launcher {resolve}/Support/Developer/Scripting/README.txt
shell script.
Prepares the following environment variables:
- `RESOLVE_SCRIPT_API`
- `RESOLVE_SCRIPT_LIB`
It adds $RESOLVE_SCRIPT_API/Modules to PYTHONPATH.
Additionally it sets up the Python home for Python 3 based on the
RESOLVE_PYTHON3_HOME in the environment (usually defined in OpenPype's
Application environment for Resolve by the admin). For this it sets
PYTHONHOME and PATH variables.
It also defines:
- `RESOLVE_UTILITY_SCRIPTS_DIR`: Destination directory for OpenPype
Fusion scripts to be copied to for Resolve to pick them up.
- `OPENPYPE_LOG_NO_COLORS` to True to ensure OP doesn't try to
use logging with terminal colors as it fails in Resolve.
""" """
app_groups = ["resolve"] app_groups = ["resolve"]
def execute(self): def execute(self):
current_platform = platform.system().lower() current_platform = platform.system().lower()
PROGRAMDATA = self.launch_context.env.get("PROGRAMDATA", "") programdata = self.launch_context.env.get("PROGRAMDATA", "")
RESOLVE_SCRIPT_API_ = { resolve_script_api_locations = {
"windows": ( "windows": (
f"{PROGRAMDATA}/Blackmagic Design/" f"{programdata}/Blackmagic Design/"
"DaVinci Resolve/Support/Developer/Scripting" "DaVinci Resolve/Support/Developer/Scripting"
), ),
"darwin": ( "darwin": (
"/Library/Application Support/Blackmagic Design" "/Library/Application Support/Blackmagic Design"
"/DaVinci Resolve/Developer/Scripting" "/DaVinci Resolve/Developer/Scripting"
), ),
"linux": "/opt/resolve/Developer/Scripting" "linux": "/opt/resolve/Developer/Scripting",
} }
RESOLVE_SCRIPT_API = os.path.normpath( resolve_script_api = Path(
RESOLVE_SCRIPT_API_[current_platform]) resolve_script_api_locations[current_platform]
self.launch_context.env["RESOLVE_SCRIPT_API"] = RESOLVE_SCRIPT_API )
self.log.info(
f"setting RESOLVE_SCRIPT_API variable to {resolve_script_api}"
)
self.launch_context.env[
"RESOLVE_SCRIPT_API"
] = resolve_script_api.as_posix()
RESOLVE_SCRIPT_LIB_ = { resolve_script_lib_dirs = {
"windows": ( "windows": (
"C:/Program Files/Blackmagic Design" "C:/Program Files/Blackmagic Design"
"/DaVinci Resolve/fusionscript.dll" "/DaVinci Resolve/fusionscript.dll"
@ -41,61 +66,69 @@ class ResolvePrelaunch(PreLaunchHook):
"/Applications/DaVinci Resolve/DaVinci Resolve.app" "/Applications/DaVinci Resolve/DaVinci Resolve.app"
"/Contents/Libraries/Fusion/fusionscript.so" "/Contents/Libraries/Fusion/fusionscript.so"
), ),
"linux": "/opt/resolve/libs/Fusion/fusionscript.so" "linux": "/opt/resolve/libs/Fusion/fusionscript.so",
} }
RESOLVE_SCRIPT_LIB = os.path.normpath( resolve_script_lib = Path(resolve_script_lib_dirs[current_platform])
RESOLVE_SCRIPT_LIB_[current_platform]) self.launch_context.env[
self.launch_context.env["RESOLVE_SCRIPT_LIB"] = RESOLVE_SCRIPT_LIB "RESOLVE_SCRIPT_LIB"
] = resolve_script_lib.as_posix()
self.log.info(
f"setting RESOLVE_SCRIPT_LIB variable to {resolve_script_lib}"
)
# TODO: add OTIO installation from `openpype/requirements.py` # TODO: add OTIO installation from `openpype/requirements.py`
# making sure python <3.9.* is installed at provided path # making sure python <3.9.* is installed at provided path
python3_home = os.path.normpath( python3_home = Path(
self.launch_context.env.get("RESOLVE_PYTHON3_HOME", "")) self.launch_context.env.get("RESOLVE_PYTHON3_HOME", "")
)
assert os.path.isdir(python3_home), ( assert python3_home.is_dir(), (
"Python 3 is not installed at the provided folder path. Either " "Python 3 is not installed at the provided folder path. Either "
"make sure the `environments\resolve.json` is having correctly " "make sure the `environments\resolve.json` is having correctly "
"set `RESOLVE_PYTHON3_HOME` or make sure Python 3 is installed " "set `RESOLVE_PYTHON3_HOME` or make sure Python 3 is installed "
f"in given path. \nRESOLVE_PYTHON3_HOME: `{python3_home}`" f"in given path. \nRESOLVE_PYTHON3_HOME: `{python3_home}`"
) )
self.launch_context.env["PYTHONHOME"] = python3_home python3_home_str = python3_home.as_posix()
self.log.info(f"Path to Resolve Python folder: `{python3_home}`...") self.launch_context.env["PYTHONHOME"] = python3_home_str
self.log.info(f"Path to Resolve Python folder: `{python3_home_str}`")
# add to the python path to path
env_path = self.launch_context.env["PATH"]
self.launch_context.env["PATH"] = os.pathsep.join([
python3_home,
os.path.join(python3_home, "Scripts")
] + env_path.split(os.pathsep))
self.log.debug(f"PATH: {self.launch_context.env['PATH']}")
# add to the PYTHONPATH # add to the PYTHONPATH
env_pythonpath = self.launch_context.env["PYTHONPATH"] env_pythonpath = self.launch_context.env["PYTHONPATH"]
self.launch_context.env["PYTHONPATH"] = os.pathsep.join([ modules_path = Path(resolve_script_api, "Modules").as_posix()
os.path.join(python3_home, "Lib", "site-packages"), self.launch_context.env[
os.path.join(RESOLVE_SCRIPT_API, "Modules"), "PYTHONPATH"
] + env_pythonpath.split(os.pathsep)) ] = f"{modules_path}{os.pathsep}{env_pythonpath}"
self.log.debug(f"PYTHONPATH: {self.launch_context.env['PYTHONPATH']}") self.log.debug(f"PYTHONPATH: {self.launch_context.env['PYTHONPATH']}")
RESOLVE_UTILITY_SCRIPTS_DIR_ = { # add the pythonhome folder to PATH because on Windows
# this is needed for Py3 to be correctly detected within Resolve
env_path = self.launch_context.env["PATH"]
self.log.info(f"Adding `{python3_home_str}` to the PATH variable")
self.launch_context.env[
"PATH"
] = f"{python3_home_str}{os.pathsep}{env_path}"
self.log.debug(f"PATH: {self.launch_context.env['PATH']}")
resolve_utility_scripts_dirs = {
"windows": ( "windows": (
f"{PROGRAMDATA}/Blackmagic Design" f"{programdata}/Blackmagic Design"
"/DaVinci Resolve/Fusion/Scripts/Comp" "/DaVinci Resolve/Fusion/Scripts/Comp"
), ),
"darwin": ( "darwin": (
"/Library/Application Support/Blackmagic Design" "/Library/Application Support/Blackmagic Design"
"/DaVinci Resolve/Fusion/Scripts/Comp" "/DaVinci Resolve/Fusion/Scripts/Comp"
), ),
"linux": "/opt/resolve/Fusion/Scripts/Comp" "linux": "/opt/resolve/Fusion/Scripts/Comp",
} }
RESOLVE_UTILITY_SCRIPTS_DIR = os.path.normpath( resolve_utility_scripts_dir = Path(
RESOLVE_UTILITY_SCRIPTS_DIR_[current_platform] resolve_utility_scripts_dirs[current_platform]
) )
# setting utility scripts dir for scripts syncing # setting utility scripts dir for scripts syncing
self.launch_context.env["RESOLVE_UTILITY_SCRIPTS_DIR"] = ( self.launch_context.env[
RESOLVE_UTILITY_SCRIPTS_DIR) "RESOLVE_UTILITY_SCRIPTS_DIR"
] = resolve_utility_scripts_dir.as_posix()
# remove terminal coloring tags # remove terminal coloring tags
self.launch_context.env["OPENPYPE_LOG_NO_COLORS"] = "True" self.launch_context.env["OPENPYPE_LOG_NO_COLORS"] = "True"

View file

@ -8,30 +8,30 @@ RESOLVE_ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
def setup(env): def setup(env):
log = Logger.get_logger("ResolveSetup") log = Logger.get_logger("ResolveSetup")
scripts = {} scripts = {}
us_env = env.get("RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR") util_scripts_env = env.get("RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR")
us_dir = env["RESOLVE_UTILITY_SCRIPTS_DIR"] util_scripts_dir = env["RESOLVE_UTILITY_SCRIPTS_DIR"]
us_paths = [os.path.join( util_scripts_paths = [os.path.join(
RESOLVE_ROOT_DIR, RESOLVE_ROOT_DIR,
"utility_scripts" "utility_scripts"
)] )]
# collect script dirs # collect script dirs
if us_env: if util_scripts_env:
log.info("Utility Scripts Env: `{}`".format(us_env)) log.info("Utility Scripts Env: `{}`".format(util_scripts_env))
us_paths = us_env.split( util_scripts_paths = util_scripts_env.split(
os.pathsep) + us_paths os.pathsep) + util_scripts_paths
# collect scripts from dirs # collect scripts from dirs
for path in us_paths: for path in util_scripts_paths:
scripts.update({path: os.listdir(path)}) scripts.update({path: os.listdir(path)})
log.info("Utility Scripts Dir: `{}`".format(us_paths)) log.info("Utility Scripts Dir: `{}`".format(util_scripts_paths))
log.info("Utility Scripts: `{}`".format(scripts)) log.info("Utility Scripts: `{}`".format(scripts))
# make sure no script file is in folder # make sure no script file is in folder
for s in os.listdir(us_dir): for script in os.listdir(util_scripts_dir):
path = os.path.join(us_dir, s) path = os.path.join(util_scripts_dir, script)
log.info("Removing `{}`...".format(path)) log.info("Removing `{}`...".format(path))
if os.path.isdir(path): if os.path.isdir(path):
shutil.rmtree(path, onerror=None) shutil.rmtree(path, onerror=None)
@ -39,12 +39,10 @@ def setup(env):
os.remove(path) os.remove(path)
# copy scripts into Resolve's utility scripts dir # copy scripts into Resolve's utility scripts dir
for d, sl in scripts.items(): for directory, scripts in scripts.items():
# directory and scripts list for script in scripts:
for s in sl: src = os.path.join(directory, script)
# script in script list dst = os.path.join(util_scripts_dir, script)
src = os.path.join(d, s)
dst = os.path.join(us_dir, s)
log.info("Copying `{}` to `{}`...".format(src, dst)) log.info("Copying `{}` to `{}`...".format(src, dst))
if os.path.isdir(src): if os.path.isdir(src):
shutil.copytree( shutil.copytree(

View file

@ -1069,8 +1069,8 @@
"RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR": [], "RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR": [],
"RESOLVE_PYTHON3_HOME": { "RESOLVE_PYTHON3_HOME": {
"windows": "{LOCALAPPDATA}/Programs/Python/Python36", "windows": "{LOCALAPPDATA}/Programs/Python/Python36",
"darwin": "~/Library/Python/3.6/bin", "darwin": "/Library/Frameworks/Python.framework/Versions/3.6",
"linux": "/opt/Python/3.6/bin" "linux": "/opt/Python/3.6"
} }
}, },
"variants": { "variants": {