WIP get fusion host version (the wrong way)

This commit is contained in:
Alexey Bogomolov 2023-03-09 23:57:12 +03:00
parent a5e0e057db
commit b7ac37701b
4 changed files with 87 additions and 50 deletions

View file

@ -1,12 +1,12 @@
from .addon import (
get_fusion_profile_number,
FusionAddon,
FUSION_HOST_DIR,
FUSION_PROFILE_VERSION
)
__all__ = (
"get_fusion_profile_number",
"FusionAddon",
"FUSION_HOST_DIR",
"FUSION_PROFILE_VERSION"
)

View file

@ -1,16 +1,35 @@
import os
import re
from openpype.modules import OpenPypeModule, IHostAddon
from openpype.lib import Logger
FUSION_HOST_DIR = os.path.dirname(os.path.abspath(__file__))
FUSION_PROFILE_VERSION = 16
# FUSION_PROFILE_VERSION variable is used by the pre-launch hooks.
# Since Fusion v16, the profile folder became project-specific,
# but then it was abandoned by BlackmagicDesign devs, and now, despite it is
# already Fusion version 18, still FUSION16_PROFILE_DIR is used.
# The variable is added in case the version number will be
# updated or deleted so we could easily change the version or disable it.
def get_fusion_profile_number(module: str, app_data: str) -> int:
"""
FUSION_PROFILE_VERSION variable is used by the pre-launch hooks.
Since Fusion v16, the profile folder variable became version-specific,
but then it was abandoned by BlackmagicDesign devs, and now, despite it is
already Fusion version 18, still FUSION16_PROFILE_DIR is used.
The variable is added in case the version number will be
updated or deleted so we could easily change the version or disable it.
"""
log = Logger.get_logger(__name__)
if not app_data:
return
fusion16_profile_versions = ("16", "17", "18")
try:
app_version = re.search(r"fusion/(\d+)", app_data).group(1)
log.info(f"{module} found Fusion profile version: {app_version}")
if app_version in fusion16_profile_versions:
return 16
elif app_version == "9":
return 9
except AttributeError:
log.info("Fusion version was not found in the app data")
class FusionAddon(OpenPypeModule, IHostAddon):

View file

@ -2,8 +2,9 @@ import os
import shutil
import platform
from pathlib import Path
from pprint import pprint
from openpype.lib import PreLaunchHook
from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION
from openpype.hosts.fusion import get_fusion_profile_number
class FusionCopyPrefsPrelaunch(PreLaunchHook):
@ -11,40 +12,49 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook):
"""
app_groups = ["fusion"]
order = 2
def get_fusion_profile_name(self, app_version) -> str:
# Returns 'Default', unless FUSION16_PROFILE is set
return os.getenv(f"FUSION{app_version}_PROFILE", "Default")
def get_fusion_profile_name(self) -> str:
"""usually set to 'Default', unless FUSION16_PROFILE is set"""
return os.getenv(f"FUSION{VERSION}_PROFILE", "Default")
def check_profile_variable(self, app_version) -> Path:
# Get FUSION_PROFILE_DIR variable
fusion_profile = self.get_fusion_profile_name(app_version)
fusion_var_prefs_dir = os.getenv(f"FUSION{app_version}_PROFILE_DIR")
def get_profile_source(self) -> Path:
"""Get the Fusion preferences (profile) location.
Check Per-User_Preferences_and_Paths on VFXpedia for reference.
"""
fusion_profile = self.get_fusion_profile_name()
fusion_var_prefs_dir = os.getenv(f"FUSION{VERSION}_PROFILE_DIR")
# if FUSION16_PROFILE_DIR variable exists
# Check if FUSION_PROFILE_DIR exists
if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir():
fusion_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile)
fu_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile)
self.log.info(
f"Local Fusion prefs environment is set to {fusion_prefs_dir}"
f"{fusion_var_prefs_dir} is set to {fu_prefs_dir}"
)
return fusion_prefs_dir
# otherwise get the profile folder from default location
fusion_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" # noqa
return fu_prefs_dir
def get_profile_source(self, app_version) -> Path:
"""Get Fusion preferences profile location.
See Per-User_Preferences_and_Paths on VFXpedia for reference.
"""
fusion_profile = self.get_fusion_profile_name(app_version)
profile_source = self.check_profile_variable(app_version)
if profile_source:
return profile_source
# otherwise get default location of the profile folder
fu_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}"
if platform.system() == "Windows":
prefs_source = Path(os.getenv("AppData"), fusion_prefs_dir)
profile_source = Path(os.getenv("AppData"), fu_prefs_dir)
elif platform.system() == "Darwin":
prefs_source = Path(
"~/Library/Application Support/", fusion_prefs_dir
profile_source = Path(
"~/Library/Application Support/", fu_prefs_dir
).expanduser()
elif platform.system() == "Linux":
prefs_source = Path("~/.fusion", fusion_prefs_dir).expanduser()
self.log.info(f"Got Fusion prefs file: {prefs_source}")
return prefs_source
profile_source = Path("~/.fusion", fu_prefs_dir).expanduser()
self.log.info(f"Got Fusion prefs file: {profile_source}")
return profile_source
def get_copy_fusion_prefs_settings(self):
"""Get copy preferences options from the global application settings"""
# Get copy preferences options from the global application settings
copy_fusion_settings = self.data["project_settings"]["fusion"].get(
"copy_fusion_settings", {}
)
@ -57,14 +67,14 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook):
copy_path = Path(copy_path).expanduser()
return copy_status, copy_path, force_sync
def copy_existing_prefs(
def copy_fusion_profile(
self, copy_from: Path, copy_to: Path, force_sync: bool
) -> None:
"""On the first Fusion launch copy the contents of Fusion profile
directory to the working predefined location. If the Openpype profile
folder exists, skip copying, unless re-sync is checked.
If the prefs were not copied on the first launch,
clean Fusion profile will be created in fusion_profile_dir.
clean Fusion profile will be created in fu_profile_dir.
"""
if copy_to.exists() and not force_sync:
self.log.info(
@ -73,11 +83,10 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook):
return
self.log.info(f"Starting copying Fusion preferences")
self.log.info(f"force_sync option is set to {force_sync}")
dest_folder = copy_to / self.get_fusion_profile_name()
try:
dest_folder.mkdir(exist_ok=True, parents=True)
copy_to.mkdir(exist_ok=True, parents=True)
except Exception:
self.log.warn(f"Could not create folder at {dest_folder}")
self.log.warn(f"Could not create folder at {copy_to}")
return
if not copy_from.exists():
self.log.warning(f"Fusion preferences not found in {copy_from}")
@ -85,25 +94,31 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook):
for file in copy_from.iterdir():
if file.suffix in (".prefs", ".def", ".blocklist", ".fu"):
# convert Path to str to be compatible with Python 3.6+
shutil.copy(str(file), str(dest_folder))
shutil.copy(str(file), str(copy_to))
self.log.info(
f"successfully copied preferences:\n {copy_from} to {dest_folder}"
f"successfully copied preferences:\n {copy_from} to {copy_to}"
)
def execute(self):
(
copy_status,
fusion_profile_dir,
fu_profile_dir,
force_sync,
) = self.get_copy_fusion_prefs_settings()
# Get launched application context and return correct app version
app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18")
app_version = get_fusion_profile_number(__name__, app_data)
fu_profile = self.get_fusion_profile_name(app_version)
# do a copy of Fusion profile if copy_status toggle is enabled
if copy_status and fusion_profile_dir is not None:
prefs_source = self.get_profile_source()
self.copy_existing_prefs(prefs_source, fusion_profile_dir, force_sync) # noqa
if copy_status and fu_profile_dir is not None:
profile_source = self.get_profile_source(app_version)
dest_folder = Path(fu_profile_dir, fu_profile)
self.copy_fusion_profile(profile_source, dest_folder, force_sync)
# Add temporary profile directory variables to customize Fusion
# to define where it can read custom scripts and tools from
fusion_profile_dir_variable = f"FUSION{VERSION}_PROFILE_DIR"
self.log.info(f"Setting {fusion_profile_dir_variable}: {fusion_profile_dir}") # noqa
self.launch_context.env[fusion_profile_dir_variable] = str(fusion_profile_dir) # noqa
fu_profile_dir_variable = f"FUSION{app_version}_PROFILE_DIR"
self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}")
self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir)

View file

@ -2,7 +2,7 @@ import os
from pathlib import Path
from openpype.lib import PreLaunchHook, ApplicationLaunchFailed
from openpype.hosts.fusion import FUSION_HOST_DIR
from openpype.hosts.fusion import FUSION_PROFILE_VERSION as VERSION
from openpype.hosts.fusion import get_fusion_profile_number
class FusionPrelaunch(PreLaunchHook):
@ -18,10 +18,13 @@ class FusionPrelaunch(PreLaunchHook):
"""
app_groups = ["fusion"]
order = 1
def execute(self):
# making sure python 3 is installed at provided path
# Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17
app_data = self.launch_context.env.get("AVALON_APP_NAME", "fusion/18")
app_version = get_fusion_profile_number(__name__, app_data)
py3_var = "FUSION_PYTHON3_HOME"
fusion_python3_home = self.launch_context.env.get(py3_var, "")
@ -52,7 +55,7 @@ class FusionPrelaunch(PreLaunchHook):
# Fusion 16 and 17 use FUSION16_PYTHON36_HOME instead of
# FUSION_PYTHON3_HOME and will only work with a Python 3.6 version
# TODO: Detect Fusion version to only set for specific Fusion build
self.launch_context.env[f"FUSION{VERSION}_PYTHON36_HOME"] = py3_dir # noqa
self.launch_context.env[f"FUSION{app_version}_PYTHON36_HOME"] = py3_dir
# Add custom Fusion Master Prefs and the temporary
# profile directory variables to customize Fusion
@ -60,7 +63,7 @@ class FusionPrelaunch(PreLaunchHook):
self.log.info(f"Setting OPENPYPE_FUSION: {FUSION_HOST_DIR}")
self.launch_context.env["OPENPYPE_FUSION"] = FUSION_HOST_DIR
master_prefs_variable = f"FUSION{VERSION}_MasterPrefs"
master_prefs_variable = f"FUSION{app_version}_MasterPrefs"
master_prefs = Path(FUSION_HOST_DIR, "deploy", "fusion_shared.prefs")
self.log.info(f"Setting {master_prefs_variable}: {master_prefs}")
self.launch_context.env[master_prefs_variable] = str(master_prefs)