From ec0f6986158b2eab312ade16430c0eb969aa0e68 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 23 Nov 2022 14:52:31 +0100 Subject: [PATCH 01/43] celaction: fixing host --- openpype/hosts/celaction/__init__.py | 10 +++ openpype/hosts/celaction/addon.py | 24 ++++++ .../hooks/pre_celaction_registers.py | 73 ++++++++++++------- 3 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 openpype/hosts/celaction/addon.py diff --git a/openpype/hosts/celaction/__init__.py b/openpype/hosts/celaction/__init__.py index e69de29bb2..8983d48d7d 100644 --- a/openpype/hosts/celaction/__init__.py +++ b/openpype/hosts/celaction/__init__.py @@ -0,0 +1,10 @@ +from .addon import ( + CELACTION_ROOT_DIR, + CelactionAddon, +) + + +__all__ = ( + "CELACTION_ROOT_DIR", + "CelactionAddon", +) diff --git a/openpype/hosts/celaction/addon.py b/openpype/hosts/celaction/addon.py new file mode 100644 index 0000000000..c6d30935a1 --- /dev/null +++ b/openpype/hosts/celaction/addon.py @@ -0,0 +1,24 @@ +import os +from openpype.modules import OpenPypeModule, IHostAddon + +CELACTION_ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class CelactionAddon(OpenPypeModule, IHostAddon): + name = "celaction" + host_name = "celaction" + + def initialize(self, module_settings): + self.enabled = True + + def add_implementation_envs(self, env, _app): + # Set default values if are not already set via settings + defaults = { + "LOGLEVEL": "DEBUG" + } + for key, value in defaults.items(): + if not env.get(key): + env[key] = value + + def get_workfile_extensions(self): + return [".scn"] diff --git a/openpype/hosts/celaction/hooks/pre_celaction_registers.py b/openpype/hosts/celaction/hooks/pre_celaction_registers.py index e49e66f163..84ac3d130a 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_registers.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_registers.py @@ -27,17 +27,24 @@ class CelactionPrelaunchHook(PreLaunchHook): app = "celaction_publish" # setting output parameters - path = r"Software\CelAction\CelAction2D\User Settings" - winreg.CreateKey(winreg.HKEY_CURRENT_USER, path) + path_user_settings = "\\".join([ + "Software", "CelAction", "CelAction2D", "User Settings" + ]) + winreg.CreateKey(winreg.HKEY_CURRENT_USER, path_user_settings) hKey = winreg.OpenKey( - winreg.HKEY_CURRENT_USER, - "Software\\CelAction\\CelAction2D\\User Settings", 0, - winreg.KEY_ALL_ACCESS) + winreg.HKEY_CURRENT_USER, path_user_settings, 0, + winreg.KEY_ALL_ACCESS + ) - # TODO: this will need to be checked more thoroughly - pype_exe = os.getenv("OPENPYPE_EXECUTABLE") + openpype_executable = os.getenv("OPENPYPE_EXECUTABLE") - winreg.SetValueEx(hKey, "SubmitAppTitle", 0, winreg.REG_SZ, pype_exe) + winreg.SetValueEx( + hKey, + "SubmitAppTitle", + 0, + winreg.REG_SZ, + openpype_executable + ) parameters = [ "launch", @@ -53,33 +60,45 @@ class CelactionPrelaunchHook(PreLaunchHook): "--resolutionHeight *Y*", # "--programDir \"'*PROGPATH*'\"" ] - winreg.SetValueEx(hKey, "SubmitParametersTitle", 0, winreg.REG_SZ, - " ".join(parameters)) + winreg.SetValueEx( + hKey, "SubmitParametersTitle", 0, winreg.REG_SZ, + " ".join(parameters) + ) # setting resolution parameters - path = r"Software\CelAction\CelAction2D\User Settings\Dialogs" - path += r"\SubmitOutput" - winreg.CreateKey(winreg.HKEY_CURRENT_USER, path) - hKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, - winreg.KEY_ALL_ACCESS) + path_submit = "\\".join([ + path_user_settings, "Dialogs", "SubmitOutput" + ]) + winreg.CreateKey(winreg.HKEY_CURRENT_USER, path_submit) + hKey = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, path_submit, 0, + winreg.KEY_ALL_ACCESS + ) winreg.SetValueEx(hKey, "SaveScene", 0, winreg.REG_DWORD, 1) winreg.SetValueEx(hKey, "CustomX", 0, winreg.REG_DWORD, 1920) winreg.SetValueEx(hKey, "CustomY", 0, winreg.REG_DWORD, 1080) # making sure message dialogs don't appear when overwriting - path = r"Software\CelAction\CelAction2D\User Settings\Messages" - path += r"\OverwriteScene" - winreg.CreateKey(winreg.HKEY_CURRENT_USER, path) - hKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, - winreg.KEY_ALL_ACCESS) + path_overwrite_scene = "\\".join([ + path_user_settings, "Messages", "OverwriteScene" + ]) + winreg.CreateKey(winreg.HKEY_CURRENT_USER, path_overwrite_scene) + hKey = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, path_overwrite_scene, 0, + winreg.KEY_ALL_ACCESS + ) winreg.SetValueEx(hKey, "Result", 0, winreg.REG_DWORD, 6) winreg.SetValueEx(hKey, "Valid", 0, winreg.REG_DWORD, 1) - path = r"Software\CelAction\CelAction2D\User Settings\Messages" - path += r"\SceneSaved" - winreg.CreateKey(winreg.HKEY_CURRENT_USER, path) - hKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, - winreg.KEY_ALL_ACCESS) + # set scane as not saved + path_scene_saved = "\\".join([ + path_user_settings, "Messages", "SceneSaved" + ]) + winreg.CreateKey(winreg.HKEY_CURRENT_USER, path_scene_saved) + hKey = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, path_scene_saved, 0, + winreg.KEY_ALL_ACCESS + ) winreg.SetValueEx(hKey, "Result", 0, winreg.REG_DWORD, 1) winreg.SetValueEx(hKey, "Valid", 0, winreg.REG_DWORD, 1) @@ -90,11 +109,11 @@ class CelactionPrelaunchHook(PreLaunchHook): if not os.path.exists(workfile_path): # TODO add ability to set different template workfile path via # settings - pype_celaction_dir = os.path.dirname(os.path.dirname( + openpype_celaction_dir = os.path.dirname(os.path.dirname( os.path.abspath(celaction.__file__) )) template_path = os.path.join( - pype_celaction_dir, + openpype_celaction_dir, "resources", "celaction_template_scene.scn" ) From b91c3f5630f9e21db6361452a3fa0b732d3a759f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 14:20:14 +0100 Subject: [PATCH 02/43] celaction rename hook --- .../hooks/{pre_celaction_registers.py => pre_celaction_setup.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename openpype/hosts/celaction/hooks/{pre_celaction_registers.py => pre_celaction_setup.py} (100%) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_registers.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py similarity index 100% rename from openpype/hosts/celaction/hooks/pre_celaction_registers.py rename to openpype/hosts/celaction/hooks/pre_celaction_setup.py From 0f4c4ea6cbaac1870aa1b379d86b50ace6053582 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 14:21:40 +0100 Subject: [PATCH 03/43] default launcher --- openpype/settings/defaults/system_settings/applications.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 03499a8567..7f375a0a20 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -1273,7 +1273,7 @@ "variant_label": "Local", "use_python_2": false, "executables": { - "windows": [], + "windows": ["C:/Program Files/CelAction/CelAction2D Studio/CelAction2D.exe"], "darwin": [], "linux": [] }, From 1b882cb7caddf5921b5e12a921f0b7c6182346b4 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 14:47:44 +0100 Subject: [PATCH 04/43] celaction: recognize hook --- openpype/hosts/celaction/addon.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openpype/hosts/celaction/addon.py b/openpype/hosts/celaction/addon.py index c6d30935a1..9158010011 100644 --- a/openpype/hosts/celaction/addon.py +++ b/openpype/hosts/celaction/addon.py @@ -11,6 +11,13 @@ class CelactionAddon(OpenPypeModule, IHostAddon): def initialize(self, module_settings): self.enabled = True + def get_launch_hook_paths(self, app): + if app.host_name != self.host_name: + return [] + return [ + os.path.join(CELACTION_ROOT_DIR, "hooks") + ] + def add_implementation_envs(self, env, _app): # Set default values if are not already set via settings defaults = { From 1f38d061ce64729becdbd5c79abe1c3dfb30f2ca Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 14:48:15 +0100 Subject: [PATCH 05/43] celaciton: resolving cli to hook --- .../celaction/hooks/pre_celaction_setup.py | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index 84ac3d130a..cda268d669 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -1,8 +1,13 @@ import os import shutil +import subprocess import winreg -from openpype.lib import PreLaunchHook -from openpype.hosts.celaction import api as celaction +from openpype.lib import PreLaunchHook, get_openpype_execute_args +from openpype.hosts.celaction import api as caapi + +CELACTION_API_DIR = os.path.dirname( + os.path.abspath(caapi.__file__) +) class CelactionPrelaunchHook(PreLaunchHook): @@ -19,13 +24,6 @@ class CelactionPrelaunchHook(PreLaunchHook): if workfile_path: self.launch_context.launch_args.append(workfile_path) - project_name = self.data["project_name"] - asset_name = self.data["asset_name"] - task_name = self.data["task_name"] - - # get publish version of celaction - app = "celaction_publish" - # setting output parameters path_user_settings = "\\".join([ "Software", "CelAction", "CelAction2D", "User Settings" @@ -36,29 +34,24 @@ class CelactionPrelaunchHook(PreLaunchHook): winreg.KEY_ALL_ACCESS ) - openpype_executable = os.getenv("OPENPYPE_EXECUTABLE") + path_to_cli = os.path.join(CELACTION_API_DIR, "cli.py") + subproces_args = get_openpype_execute_args("run", path_to_cli) winreg.SetValueEx( hKey, "SubmitAppTitle", 0, winreg.REG_SZ, - openpype_executable + subprocess.list2cmdline(subproces_args) ) parameters = [ - "launch", - f"--app {app}", - f"--project {project_name}", - f"--asset {asset_name}", - f"--task {task_name}", "--currentFile \\\"\"*SCENE*\"\\\"", "--chunk 10", "--frameStart *START*", "--frameEnd *END*", "--resolutionWidth *X*", "--resolutionHeight *Y*", - # "--programDir \"'*PROGPATH*'\"" ] winreg.SetValueEx( hKey, "SubmitParametersTitle", 0, winreg.REG_SZ, @@ -109,9 +102,7 @@ class CelactionPrelaunchHook(PreLaunchHook): if not os.path.exists(workfile_path): # TODO add ability to set different template workfile path via # settings - openpype_celaction_dir = os.path.dirname(os.path.dirname( - os.path.abspath(celaction.__file__) - )) + openpype_celaction_dir = os.path.dirname(CELACTION_API_DIR) template_path = os.path.join( openpype_celaction_dir, "resources", From 54bb955d8b914085582ca6061a84a6c003743982 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 14:57:44 +0100 Subject: [PATCH 06/43] celaction: improving setup hook --- openpype/hosts/celaction/hooks/pre_celaction_setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index cda268d669..76a2e43452 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -42,10 +42,10 @@ class CelactionPrelaunchHook(PreLaunchHook): "SubmitAppTitle", 0, winreg.REG_SZ, - subprocess.list2cmdline(subproces_args) + subproces_args.pop(0) ) - parameters = [ + parameters = subproces_args + [ "--currentFile \\\"\"*SCENE*\"\\\"", "--chunk 10", "--frameStart *START*", From 00bbd4ebe1afbcdcd15668af7611947aac4ecc5c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 15:09:34 +0100 Subject: [PATCH 07/43] celation executable fix --- openpype/hosts/celaction/hooks/pre_celaction_setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index 76a2e43452..aa04c8c088 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -36,13 +36,14 @@ class CelactionPrelaunchHook(PreLaunchHook): path_to_cli = os.path.join(CELACTION_API_DIR, "cli.py") subproces_args = get_openpype_execute_args("run", path_to_cli) + openpype_executables = subproces_args.pop(0) winreg.SetValueEx( hKey, "SubmitAppTitle", 0, winreg.REG_SZ, - subproces_args.pop(0) + openpype_executables ) parameters = subproces_args + [ From a3c55730c164d5b03444c7dcad46d6086ebf0c16 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 15:20:44 +0100 Subject: [PATCH 08/43] celaction removing unused code --- openpype/hosts/celaction/api/cli.py | 30 +++++-------------- .../celaction/hooks/pre_celaction_setup.py | 1 + 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/openpype/hosts/celaction/api/cli.py b/openpype/hosts/celaction/api/cli.py index 88fc11cafb..7b2542ed06 100644 --- a/openpype/hosts/celaction/api/cli.py +++ b/openpype/hosts/celaction/api/cli.py @@ -1,6 +1,5 @@ import os import sys -import copy import argparse import pyblish.api @@ -13,10 +12,9 @@ from openpype.tools.utils import host_tools from openpype.pipeline import install_openpype_plugins -log = Logger.get_logger("Celaction_cli_publisher") - -publish_host = "celaction" +log = Logger.get_logger("celaction") +PUBLISH_HOST = "celaction" HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.celaction.__file__)) PLUGINS_DIR = os.path.join(HOST_DIR, "plugins") PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish") @@ -46,28 +44,16 @@ def cli(): celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ -def _prepare_publish_environments(): - """Prepares environments based on request data.""" - env = copy.deepcopy(os.environ) +# def _prepare_publish_environments(): +# """Prepares environments based on request data.""" +# env = copy.deepcopy(os.environ) - project_name = os.getenv("AVALON_PROJECT") - asset_name = os.getenv("AVALON_ASSET") - - env["AVALON_PROJECT"] = project_name - env["AVALON_ASSET"] = asset_name - env["AVALON_TASK"] = os.getenv("AVALON_TASK") - env["AVALON_WORKDIR"] = os.getenv("AVALON_WORKDIR") - env["AVALON_APP"] = f"hosts.{publish_host}" - env["AVALON_APP_NAME"] = "celaction/local" - - env["PYBLISH_HOSTS"] = publish_host - - os.environ.update(env) +# os.environ.update(env) def main(): # prepare all environments - _prepare_publish_environments() + # _prepare_publish_environments() # Registers pype's Global pyblish plugins install_openpype_plugins() @@ -76,7 +62,7 @@ def main(): log.info(f"Registering path: {PUBLISH_PATH}") pyblish.api.register_plugin_path(PUBLISH_PATH) - pyblish.api.register_host(publish_host) + pyblish.api.register_host(PUBLISH_HOST) return host_tools.show_publish() diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index aa04c8c088..5662f7f38f 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -54,6 +54,7 @@ class CelactionPrelaunchHook(PreLaunchHook): "--resolutionWidth *X*", "--resolutionHeight *Y*", ] + winreg.SetValueEx( hKey, "SubmitParametersTitle", 0, winreg.REG_SZ, " ".join(parameters) From 3aa578047997641b304393ec613701e83c8876fe Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 15:31:59 +0100 Subject: [PATCH 09/43] celaction: clearing old code --- openpype/hosts/celaction/api/cli.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/openpype/hosts/celaction/api/cli.py b/openpype/hosts/celaction/api/cli.py index 7b2542ed06..e00a50cbec 100644 --- a/openpype/hosts/celaction/api/cli.py +++ b/openpype/hosts/celaction/api/cli.py @@ -44,17 +44,7 @@ def cli(): celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ -# def _prepare_publish_environments(): -# """Prepares environments based on request data.""" -# env = copy.deepcopy(os.environ) - -# os.environ.update(env) - - def main(): - # prepare all environments - # _prepare_publish_environments() - # Registers pype's Global pyblish plugins install_openpype_plugins() From 2f80dcc950b88581bf0b7e2c4daa37fef7f80802 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 15:32:36 +0100 Subject: [PATCH 10/43] celaction: fixing scene env and adding chunk --- openpype/hosts/celaction/hooks/pre_celaction_setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index 5662f7f38f..b14fb12797 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -47,8 +47,8 @@ class CelactionPrelaunchHook(PreLaunchHook): ) parameters = subproces_args + [ - "--currentFile \\\"\"*SCENE*\"\\\"", - "--chunk 10", + "--currentFile *SCENE*", + "--chunk *CHUNK*", "--frameStart *START*", "--frameEnd *END*", "--resolutionWidth *X*", From bdda909f1f319c76562d0f62881ca88b09780912 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 15:41:26 +0100 Subject: [PATCH 11/43] celaction icon --- openpype/resources/app_icons/celaction.png | Bin 0 -> 4012 bytes .../resources/app_icons/celaction_local.png | Bin 40783 -> 0 bytes .../resources/app_icons/celaction_remotel.png | Bin 36400 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 openpype/resources/app_icons/celaction.png delete mode 100644 openpype/resources/app_icons/celaction_local.png delete mode 100644 openpype/resources/app_icons/celaction_remotel.png diff --git a/openpype/resources/app_icons/celaction.png b/openpype/resources/app_icons/celaction.png new file mode 100644 index 0000000000000000000000000000000000000000..86ac092365d009052c4e0351732ad1dd067329de GIT binary patch literal 4012 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 diff --git a/openpype/resources/app_icons/celaction_remotel.png b/openpype/resources/app_icons/celaction_remotel.png deleted file mode 100644 index 320e8173eb90df65e0363f8784e4f034da0c76b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36400 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 Date: Thu, 24 Nov 2022 15:41:43 +0100 Subject: [PATCH 12/43] celaction rename variant to current --- openpype/settings/defaults/system_settings/applications.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 7f375a0a20..aa1d7387d0 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -1268,7 +1268,7 @@ "CELACTION_TEMPLATE": "{OPENPYPE_REPOS_ROOT}/openpype/hosts/celaction/celaction_template_scene.scn" }, "variants": { - "local": { + "current": { "enabled": true, "variant_label": "Local", "use_python_2": false, From 0f1995e2972e526bf3f3f2c8e6c53363bd040264 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 15:54:37 +0100 Subject: [PATCH 13/43] celaction current variant settings --- openpype/settings/defaults/system_settings/applications.json | 2 +- .../schemas/system_schema/host_settings/schema_celaction.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index aa1d7387d0..77b91037c9 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -1270,7 +1270,7 @@ "variants": { "current": { "enabled": true, - "variant_label": "Local", + "variant_label": "Current", "use_python_2": false, "executables": { "windows": ["C:/Program Files/CelAction/CelAction2D Studio/CelAction2D.exe"], diff --git a/openpype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json b/openpype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json index 82be15c3b0..b104e3bb82 100644 --- a/openpype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json +++ b/openpype/settings/entities/schemas/system_schema/host_settings/schema_celaction.json @@ -28,8 +28,8 @@ "name": "template_host_variant", "template_data": [ { - "app_variant_label": "Local", - "app_variant": "local" + "app_variant_label": "Current", + "app_variant": "current" } ] } From 08691e257d460ce537a62680d0e3eadf212858e5 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 16:13:06 +0100 Subject: [PATCH 14/43] celaction: ext added to anatomy data --- .../hosts/celaction/plugins/publish/collect_render_path.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/celaction/plugins/publish/collect_render_path.py b/openpype/hosts/celaction/plugins/publish/collect_render_path.py index 9cbb0e4880..ec89fc2e35 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_render_path.py +++ b/openpype/hosts/celaction/plugins/publish/collect_render_path.py @@ -21,7 +21,8 @@ class CollectRenderPath(pyblish.api.InstancePlugin): padding = anatomy.templates.get("frame_padding", 4) anatomy_data.update({ "frame": f"%0{padding}d", - "representation": "png" + "representation": "png", + "ext": "png" }) anatomy_filled = anatomy.format(anatomy_data) From 0167886c1396cbdd76ddae583e68217b9f165515 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 16:21:40 +0100 Subject: [PATCH 15/43] celaction: removing resolution from cli --- openpype/hosts/celaction/api/cli.py | 6 ------ openpype/hosts/celaction/hooks/pre_celaction_setup.py | 4 +--- .../plugins/publish/collect_celaction_instances.py | 9 ++++----- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/celaction/api/cli.py b/openpype/hosts/celaction/api/cli.py index e00a50cbec..1214898e3b 100644 --- a/openpype/hosts/celaction/api/cli.py +++ b/openpype/hosts/celaction/api/cli.py @@ -35,12 +35,6 @@ def cli(): parser.add_argument("--frameEnd", help=("End of frame range")) - parser.add_argument("--resolutionWidth", - help=("Width of resolution")) - - parser.add_argument("--resolutionHeight", - help=("Height of resolution")) - celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index b14fb12797..e4a3bee5ee 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -50,9 +50,7 @@ class CelactionPrelaunchHook(PreLaunchHook): "--currentFile *SCENE*", "--chunk *CHUNK*", "--frameStart *START*", - "--frameEnd *END*", - "--resolutionWidth *X*", - "--resolutionHeight *Y*", + "--frameEnd *END*" ] winreg.SetValueEx( diff --git a/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py b/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py index 1d2d9da1af..b5f99a1416 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py +++ b/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py @@ -52,8 +52,8 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): "subset": subset, "label": scene_file, "family": family, - "families": [family, "ftrack"], - "representations": list() + "families": [], + "representations": [] }) # adding basic script data @@ -72,7 +72,6 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): self.log.info('Publishing Celaction workfile') # render instance - family = "render.farm" subset = f"render{task}Main" instance = context.create_instance(name=subset) # getting instance state @@ -81,8 +80,8 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): # add assetEntity data into instance instance.data.update({ "label": "{} - farm".format(subset), - "family": family, - "families": [family], + "family": "render.farm", + "families": [], "subset": subset }) From 6925a96ee64a57ee928b39d951a85a44296469ba Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 17:09:48 +0100 Subject: [PATCH 16/43] celaction: return back resolution override --- openpype/hosts/celaction/api/cli.py | 6 ++++++ openpype/hosts/celaction/hooks/pre_celaction_setup.py | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/celaction/api/cli.py b/openpype/hosts/celaction/api/cli.py index 1214898e3b..e00a50cbec 100644 --- a/openpype/hosts/celaction/api/cli.py +++ b/openpype/hosts/celaction/api/cli.py @@ -35,6 +35,12 @@ def cli(): parser.add_argument("--frameEnd", help=("End of frame range")) + parser.add_argument("--resolutionWidth", + help=("Width of resolution")) + + parser.add_argument("--resolutionHeight", + help=("Height of resolution")) + celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index e4a3bee5ee..81f77c1654 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -50,7 +50,9 @@ class CelactionPrelaunchHook(PreLaunchHook): "--currentFile *SCENE*", "--chunk *CHUNK*", "--frameStart *START*", - "--frameEnd *END*" + "--frameEnd *END*", + "--resolutionWidth *X*", + "--resolutionHeight *Y*" ] winreg.SetValueEx( From a17f516597a39402e8032bc66b5027f47b199086 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 17:10:07 +0100 Subject: [PATCH 17/43] celaction: deadline submitter to modules --- .../plugins/publish/submit_celaction_deadline.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename openpype/{hosts/celaction => modules/deadline}/plugins/publish/submit_celaction_deadline.py (95%) diff --git a/openpype/hosts/celaction/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py similarity index 95% rename from openpype/hosts/celaction/plugins/publish/submit_celaction_deadline.py rename to openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index ea109e9445..8a3160e83d 100644 --- a/openpype/hosts/celaction/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -37,13 +37,12 @@ class ExtractCelactionDeadline(pyblish.api.InstancePlugin): instance.data["toBeRenderedOn"] = "deadline" context = instance.context - deadline_url = ( - context.data["system_settings"] - ["modules"] - ["deadline"] - ["DEADLINE_REST_URL"] - ) - assert deadline_url, "Requires DEADLINE_REST_URL" + # get default deadline webservice url from deadline module + deadline_url = instance.context.data["defaultDeadline"] + # if custom one is set in instance, use that + if instance.data.get("deadlineUrl"): + deadline_url = instance.data.get("deadlineUrl") + assert deadline_url, "Requires Deadline Webservice URL" self.deadline_url = "{}/api/jobs".format(deadline_url) self._comment = context.data.get("comment", "") From 66bbaf6fccce75e879f29729443531786693efab Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 24 Nov 2022 17:13:21 +0100 Subject: [PATCH 18/43] celaction: project width and height to hook --- openpype/hosts/celaction/hooks/pre_celaction_setup.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index 81f77c1654..cde3a0c723 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -19,6 +19,10 @@ class CelactionPrelaunchHook(PreLaunchHook): platforms = ["windows"] def execute(self): + project_doc = self.data["project_doc"] + width = project_doc["data"]["resolutionWidth"] + height = project_doc["data"]["resolutionHeight"] + # Add workfile path to launch arguments workfile_path = self.workfile_path() if workfile_path: @@ -70,8 +74,8 @@ class CelactionPrelaunchHook(PreLaunchHook): winreg.KEY_ALL_ACCESS ) winreg.SetValueEx(hKey, "SaveScene", 0, winreg.REG_DWORD, 1) - winreg.SetValueEx(hKey, "CustomX", 0, winreg.REG_DWORD, 1920) - winreg.SetValueEx(hKey, "CustomY", 0, winreg.REG_DWORD, 1080) + winreg.SetValueEx(hKey, "CustomX", 0, winreg.REG_DWORD, width) + winreg.SetValueEx(hKey, "CustomY", 0, winreg.REG_DWORD, height) # making sure message dialogs don't appear when overwriting path_overwrite_scene = "\\".join([ From d92448f923a8da0e094c5b78e645c40b45d6f363 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 12:02:08 +0100 Subject: [PATCH 19/43] celaction: adding deadline custom plugin --- .../CelAction/CelAction.ico | Bin 0 -> 103192 bytes .../CelAction/CelAction.param | 38 ++++++ .../CelAction/CelAction.py | 121 ++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.ico create mode 100644 openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.param create mode 100644 openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py diff --git a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.ico b/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.ico new file mode 100644 index 0000000000000000000000000000000000000000..39d61592fe1addb07ed3ef93de362370485a23b9 GIT binary patch literal 103192 zcmeHQ2V4_L7oQ+17Eb(ZC>9jYh9aJ*CI!Yvtch-C}%GyqF4^>y<&9SCuIvvd)< zyn}(Z{5E{Be(h$pp=tdg_5&PnE+#$Pwd3M5(5L>QAp?FM?UI3!p_ z9*8`qYq`0$MK^tmffk0xHhFINd+5)x4>?bta1u{GnrxB#e4a(@6_1Wb=1x7gZK{30 z4oB?j%rLKBZ~mJ$-ri`WK@-vR>td5!SF1CNKeFsoyjQHrad{on_@E2l@k07({*I8r zZGeF?9Co)mCRH~+_Q~SvPrD~HFB?@a#(9pO(Ph+?NzK;wM@JHp2Mv!q>)T;Z z#><(HHePt##ChLlCj;b?y!?EJ9ZTk>@(n{fI#2RBzwOtg57Vr5QCRv(;fPt++K;%g zvY&B^9%{~x7q!>>>xBt2pTItBtUGNxvcIv&m(p!*FmXq=j?@FEe@vh{l4@JZ@*+$18?8#QTLrLpi{|1*jAsSr?~a%;lS=?HIvnAP4M_@ zu9=2A8Zj-5;zWBs1UOD?mc7F6gHf{k@oq+eBU+@e%$Na*bEpZ;g`<6Zmn4Z&jE1K8 zHg!%ozio%;Q`DvWK{gE=n(8tw`nc_-a*jQn*r2ajbStY@)%N#XVbuHYAUhz8}v zi9X+{?c`gx+57tKHm;9o%rNgV%gxgR?XO{BJ1C;BM{v@d_p{wRx1!D0vd4~e$cTC6 z>)!K``|ro8VeAn#ZS)$Bt5##>`!pZXn?F1D{>g1cr`*Gr>@%j06LSM%wrv-WPR!#6 zj%anu7`>fk&rUEqxY%{C`~IxqsQ2HsXJu7!ePb zpKmyboztS(L)YQ#_VrCYf(==nso?0t;Vaty8q{&hy?}`Q|BJQ_)$_2_Te$Q7`Heko zkB6RW$uL-EVcTy28qhS_Yv<>lP7RaicYY8us{YAK!OksD3w!+#;L~#XEVs>i41>O{ zALkfZ#!vC%x+`+We>=F3*+M*A;_75%#j?O)Fr zwZ?5#yNL7V$8GmKdvqf^e(=)IW_B+&da@EjT!x0Zoci)<&zpmKy1f{8B1AR=n(sqX zU(UX`sYiI%{GcWlwmP?J8`s79Xwv-b?XkLbijh@GmZg*>T>xXo= zqz!(wu%2;;);*~CyVC}{xEL*TywA=*ckJmOLD5IIvyKVtqp|3nOYiWQMb6^5q_eCv ze(1kxU>4g}qvO-I);on5=CyrWjavH)3hy^h>^Eh_Y`0+zO_A-Vo{M)49dmbNdU8*% zcu_*Dr6(3MMK;44Gg6;@W<9pu;?Q>mH!f3fHte^JE1F$vojo5|G1Nm{FX-pY*je-T z-M$`EFZ_^mLRjByELvwCUT@TnMs~JI7u!U8%^r+`dpCXGEh8-*?=* z+n`g8l}w$n$p32ZklksUs$1*3OtWME`RAUG?*|#B2(#;WzjnLD8a|)_V`0Cui^G4- zYT}Ul_`(CLYvRVkR&N?~DJ6&9Ib1KwZTw)gdGov;x$EW&8a)<Q+u<%9EzvHw^!@3A-{!ht1JCb$ed+iFS_b>s(HV4?Bdz1qwA~_lRHOyb$Gkm zV}1=!!DRbZ;ifzL9zXH2{#m!ve^9@N+s5BDt~bDl5gX%Sz*?U+xbDJQu`!uzMtX*I zi<>*!Ekf7SW2(re`2e=bAV4u>BZ|p2nW=~TH*P@DUWRX5dW@U<_tsfU#(2)=&g-7m z4j6BPMC1MZhu-w-`-6^a|9~*F7^@~TmW4GGTnTKpa&G!R$(<%x1xB-n8=El(EweTc zXglrdtsKYD_CrH|Ocags>AnBsmQZV+$;g?nBd=^1j*SrAVMlq6cDb<1LYLWL-gf=| z?t^k7=d@dJ(=+(Z|Cs((+dD_M`Z@BS&Q=$fCH)bh&qz%ec5cQ^UC!~Lfu@^{beO$% zUz^0p+s`rNcVyaMMjx6uIIPO|dEdlg*N}SQp>ZD#AHH7QY4xU*G=0a(_CvDc{**&O3LfEm-DxIww5PXK&?8ZfZp?t?%lpF z#o$cy<`19c$5{8eb@4;|U&+ardfW_a#_DC;yOAI6)u*LRy%Wz*m>?a8HLPLtKZd&q z`%md@xhtz)2(>e1f=!pZCrADD)WP+YcfBUdu8^qcF?4n*ruyzI7^on->2 zK+5qy2X%UFfTp%a{YI}69567vlX7(L?JuXn){{;SyBLtIb81q?nD9p|p2=TYm0`>B(nMtog^zK%MAQ#|K!NOuEbMeX;^{$K2-Cw_sy;FHS# z`mlkXFE3B3;l|v*Hzf8)$(d)q^_lRPp=*E7*)Pqix0%Md6!LG{`+eK;1Ap0KH2)W` zx#zuuCiOekV(26o*PQp^*(iND8MV@_?cih6kOP;JaTo8{{I=w@_nv?m&WHD&p75rr zS2eG!;U=ct&n_F8>6`5^IWBK{{j=PQV@?{-um7LpIN#oe=!bAQGg0>zT{c=<_BRnbm zDC}}G*=+Oi`AIf+53!xIbWGPiF+j%?XOC;cok&HnA8$CcX;_nNvBdhat?)}UuQJrusf ze_c$H*_~&*=VxE1!jc|rpLBkAC!SlkW23yApPq4ZeQ;|ea@Z9#X|1VqORi(J(+6+A z$nS9}ePWR7jY~dD?k=yjs6P_STpVb+@Z_Vgs3uMBrT8b+zHJ}R%V=Y$%Un9~@+5R@ zJ7WF%%z0dDWbl{36%!i?lKrFfZ3kW+R!4`~b$VvtFAG1M*^@G1ot|lskz1#^`Ad_3 z`J;326kU%gBbHjcuF;^k+orc;=Ca2;NqaIr|LKia>>drC7#$sSPHH7E)9yAid3n=I zJ`EkiCNx_KLpRTQbilI*gL9pKbLP32F>Q668qWQDaa+oAvqQrB;U@X3F0!9_&v};S z9kA?Zde)9>^YblM8^-TCK7Z=RFKrDN=I5RXr?u_xbgv`-EcaBpYjgKNn*{bhYcCG6 z*%iZBdSj)y!-H8ahO->+AHF`tYxMM4OP+DPQ>I>@!?yQ1`(Vz@&_9#1@2x%X>ob#U zBHOdqFGgAGTJ+H|?y#cS@4fd#ZrRGLxxv%ok1nHlj_18yGcs?i2^gP~@B5DRAjzgj zw>Y0mm-H_*qOG>Hq0kqbKv z1wfm@@OwSHbNm9s+=Uh^FudoiD|`!WeH+Qk$TwS-32O_9c}qMSd1;lN{e!09`X}c<2DKCi=s{!nXR@f`OIp&_*UREZ5_!TjGEmjT;r2>F_t|DPfEfEd-X9iR(y(8W&B*^zRR z@TY6M`-=0#P}KbAwav?Ny% zf#TNx1&Q-0(Wekfl*9byDDTZ?igT;3(y>QTJ`z`rfHM6HUe2Pv^&{`YexiTXs#Pmj znf~+Bk9_Our^NhJqJOnCthx}Z)^sgG9 zs-8>qU)43NT0WwG)%aBPT%!M~u3^>k5&f&ir>f@?{a1AjtCo-GUo}2eJ(uXes%u!a zd_@1M@u}*$ME_M?!>Z*Y`d5ulRnH~*uj(3BEuXgP{|oOG@&8b*TD5YO>7O6>+c)q3 zBYf>a^sknNRTomGf9yxgkF}?;j~(^}`__p6+)=6SiT|%^T`S8iPXF5K6Ru1~l2$wd zME}KO^F8Dc{eKTyE?!2W|KhRv9&%*$&%I|%3E|xu?xUVX=2x6swIz8a%>{*Twm@A* zk@~!ternAld9j0v)Rpx8%B4vCymvb(UX+Dg`R_qznv{{&KYpJ|EKHZ&_u-HmX)cE= zo)2;#bb$9RUYB@pn4fW)Vu$M%sV_)cQes_7#HM)BRz>P^A`Gc7+=Qa_#rYKXVdui~ zn#AUNXp7cAFUC$D+tTVmzBZMgd0x2aNepsAfF#Us!*@={U{!%M65eQErZdy|cq_IG*uE^S{`xxD1O4?_vE<2~3w;kR3=vh3fx zY%oq5gWlzIPul^E2^Yvd%2n4w;2iG&x=yF{&AHp0;=;W@8}9$;G-3l)Q~!#(=Or$r zgs{#cgnM;?;2p(*_1!`nfH`5#Kd5fiMB@9C3Xkca+rsa0aigszddIpiq`WMO1L-n0 z5J7C9YS;?QoAEWjP`5l-S1HuHtPQ|=8nJ<@p>stkVEixq9tQ`W?+JzfQUZ9MSA;n6 z6z5T|LR$g5Nr3x>c8cwhxOO2>wKbtpRy$X*lF_??93 zkW~|z??);;rvp7ksG)CVV?sKy0qwUHsSP~&&juJ2=Wa8K1J6>G(tQ(ITS$jBg3j8H z!uKtK#0EmpW!eVt{l5@=zm(n=z&!%KXQ0bMh`-}3`HtK7jiPo-kJkn8dLOOVl5Btv zK9_V^VguT(dzyQR4TPdIv|jO=umF55iyH?NZ2;z!ztL@xPmAbdnG5F(+Cu?f!s&Mj{}((6m4KU-3|%07Xh#V7y4Sj20uFiE24NC_!vOp zGIV*UyHI;2C!Es=U_H`0#rowXEuy#yPD+WR@V*e#-AuPbLhVHW^f(V}AivNKWS$?D zltyeod-X2MIiA;*!v=^ynJk!E`dexPqLR*eW%)1;_z-_GEmgb>+h7CZK)-BS$6R=y zm!E#P7&!v2l{P^9$+T35uZ}* zXUa>W@O^`V4G_Q5id9jCw~lQ9t_P0_^%|}ttK*V>XX0x~g)>Pys89rmPho|^s}+rx z*9Kr5vCs-Z36sSlkQ0RTU_6)cD}{Y!RQZ+4?=wey3X4Tndoq;y6yoDnVH;j}meq&|fQ=sBS(e=;8U70~5y2-lH@#kEV)wF?2b7O3_q%+H~)ZP5CM z^1<3AA>prTAL3x@Si`K5xzMI3IlP<6inSJSMlF|eLf&f8)AV3fx z2oMAa0t5kq06~BtKoB4Z5CjMU1Ob8oL4Y7Y5FiK;1PB5I0fGQQfFM8+AP5iy2m%BF zf&f9_>mvZKx{#x^2q0t#n?$(N)x-!H=pkfF$3+O4>&nNCOBt7|uh>3(OdR)5cUSHZ z+Q)}1|0GWED6>5X+;gbc@JAo4!j=kBQtQz<1tGJheB7g&d>k_R3y&;3&}GeK=KTT6c~W>MXo(ckpZRx1E~rOuoM^&C@>&WV4z5cGJ}tV zldmpu=^2n$fg%DT1%$*3aY_ME%EMh=1x)!U^-dv9qRJ7#8(i1{c>pnxG5m+a4xt8h z3P=(s{|EvE0fGQQfFM8+AP5iy%8dZLU)U=*3^}Q!P}CN_kF5)3e*qc+@1^O%UPMMJ z>)tJR)By0#RD=J=tPoTO%6*n8n+NY` z;=MfsWzv-EKMW;S5c}nB7WCQ%`1c2jQAKdRcY(5fp$x_=0)CHxa{|jBrK%p}1p!W` zX5I^1lzI#`# za6HrqvlY+?$ex4c=fR%4nm+i?Cu@!TeAstd(}y5wA(3BtZdHKkYNScp{)zsH{gd-w zvj~v!kBtBH+)5*Zbp=AYt0%zw8norPHV3Jk~!cbOA22HH9@?`wuQ3ewktq& z8flW&KjyI_Nh8cwKqC_QnR*mAvTLFI-1}{d*Z}u_o5Fma5w$-S@SJYd$K@-xrNib#p`vMAo8UQ!I2 zQC~Q5a``yUxznfs11KlXXHog-$G&y>-?GDXDPD9RiU)g)OU5nwz8$Aa(r|hKaie~c z$b&KB+-XplUYIX)o^bCOQ*1c5pe#=##;V~)U|q60tj%o1>oc&Hy-)d(X^9BsViROti}lXWyjbwP0dXG1eKrwezyfS~m8)?rs0=b%fvj9^tUbkpH7ZQp zL}!Y9`v;5x7xJt8o|_<}4c0dhmRXT_kTzTkR9P+-0R#N}GK&p!H{P2q6z`pvgt#we zVLXJ8KdxLIXhCHd^SXen8QdqoP(qlq(cd58z1fU05CH~GS|CQbSOgi{f~@cGclU&% z+(Hca@Am=*3^C--DOU$tP#I)w2^b`CVBX6A7y#cN@Rtzx=@@!!aMJ=Y%EcmJU<4S% z0nsumh8xS(ffiJTXZnpme#y6~IB=hfzeh?F8}19iU&i}e_UF+A#PI#@dVs+_4y*&< z?{U&&qTo{~#lBSsW8eqh->IgFzP{Bq;9Mx2BMZ0*|6u_4`E0n)hy0UZD>c4V{x!iD z$X65W;0nH{$KPQQ!gqKu@pHlf1Ic>N6)00%6McQFZD1XPu1~{tP;o4z<6+oVzE%D; z!52Q)3owA|0;~(MZyWqax9VaX?%**)6McQFZQwB<#=YJ68i3~q^q9z(uI~W`?%yi! zn&b=Q+>C92|L8>TI(uyo;MY;j8G)_tL zDX)SKH1Z$s6JZYI1XQ?BL|d{?1i(QKf&f8)AW*3Yz`BSD&}E?eO6VM{nY4oR^SBJG z9km5NsY6Q2;kwtM>{nk~f__f`(d%1^;SR{dM5iBv->x!oI-L%$eQjj`FKblr18ezc z7LZt42AAC<{Y~>M8}9hp{DW^=HQ;9`*oC7K8VB!U<7W~BAa4lkhQx=@K}k7BSg#%q z&o8QfZT_{rKfr!IP?Cn|tNRTA-`9XBLE?N$^!a|7NSNYEp9A4vTc0%lqE9!=JYW98 zi6{J*QE>!+3Vhp%{glys@bfXr_@nLTZ+_P0GLJtZ*4;`UfABjwyl5*R>rxZvPQyy) zpB=7Kz(Y9r9N_mTXrg^Fm^J@P!@nhSQt;D|FIOqoue`TjRNjYul06{s`%+@TdrB-~ z1LabJq(u^5@%w>d@TZZa=YOK`{u5XReC@?)(sySng@61`5auoKy$|rDBYE#fEO=YM zFYqczoF|oGEW8)=u^=7Zk>bS;hIEERhP)4d<1&@OKi<>iDNwwW@b8y0aXS4uq$Max z$7SjIu4Nqu%Tf>e#Xi~TKu5u+rqI6(_S!14hZxN55m1qIWo664OKIx>&vxJ&$L6OW zrMLy}zFq?UYL&K~$|?{1`(U3>0p}?tV8>G2nEu#)gW+CFD}0-PPrOIlKR}XmQzpEn zEizzxf%{f}&V3W`F**hB=$wc5QOjGnwF-m$|?(dRtFh;xv@hi0qY*cXWgN=&nIEKdI5Q@D~qqv^b5A61N_Ra zRng}~Dy08dnzkydEcjkxzr#)JJB`HH*N_kQ#QYEY@f;@&&Ihg7SMGB#$N)ZboXD{|UU}063;I%+FUd!&aM%hs!6Ej>f>40HtsoR( z?<)w!*o_N93j2ZK5Pzu%hfLdo5I2D10%$-ILIXGyOG8SUP8}{tr{KW(>V?=(%NWQG zsL)T#fcR+v9ONhi0x(x;2lpE0GSnK<8Ui&2Y9*6y4)G4~&YH#!nB$EHlD%iZzn22x z{gd&&@C$(y^QUWy0cg87&}$&PHcHbn_vwhUM+m>q3QmY;^&6KS1X_o9ZHzI8lDdxrUWnkfOWJQlo0ms!EwCrJm=OA65k(? zUn9@1z#k2-qk6#@yB5e2$VwXG-^Ir@^xOpc-o=M!soa;d^I+{~tfs~kb=!gdC&Jog zKHeJ!_VoV(agANq)aD@+jp0Q1$rFHI0WW2Z7;tb_x2~qjf!ss5&nNQ)+!qx0#h=)| zS81wkb=v{Ce};ZJ92f^UFb=T8t8dWcJVzZqfCo!>?>z_a7sdbg1n^LE=ht3C0u0PK zk8Lt|$u1Np$^z@+5X||$>YgmnpDEz~p7&}QJfoBNG<@~%Jb~P8I8i?(bK^(iv0;=t z`qOk7z@aJd(L>YilJ>q21d7b5n6Pf)Atjti|5g;GAm=gnjq-0sSE*{2Qm0_$&y@`~b8V2;avJ zlM?=o(=a3|4=7{7e>$F>mv&f=_|F{KkY}l~GGsy->%8~7<&^=kyfi;Np4+Ka|J|;l z^*{KkU7!1~6U-S$O8f))Psd8`oACbKYWDv#|LK@ZaIbej@N%vn?4f*spD^7I$DzJS zN&ItT2HfC8cEi3{CF)99TQJ@?;=Y{wnD_dxL};U>vN9#5K^q2~du{IVUVFTO>v)-b z0-*1@oM`JXZrpHu&t0bdP@tY3=TYx1Sf-MAuB`lmwNHdt;0;wAeTMZ>7LdRlA(1UY JVj#NS{{bY%R3rcZ literal 0 HcmV?d00001 diff --git a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.param b/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.param new file mode 100644 index 0000000000..24c59d2005 --- /dev/null +++ b/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.param @@ -0,0 +1,38 @@ +[About] +Type=label +Label=About +Category=About Plugin +CategoryOrder=-1 +Index=0 +Default=Celaction Plugin for Deadline +Description=Not configurable + +[ConcurrentTasks] +Type=label +Label=ConcurrentTasks +Category=About Plugin +CategoryOrder=-1 +Index=0 +Default=True +Description=Not configurable + +[Executable] +Type=filename +Label=Executable +Category=Config +CategoryOrder=0 +CategoryIndex=0 +Description=The command executable to run +Required=false +DisableIfBlank=true + +[RenderNameSeparator] +Type=string +Label=RenderNameSeparator +Category=Config +CategoryOrder=0 +CategoryIndex=1 +Description=The separator to use for naming +Required=false +DisableIfBlank=true +Default=. diff --git a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py b/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py new file mode 100644 index 0000000000..d19adc4fb9 --- /dev/null +++ b/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py @@ -0,0 +1,121 @@ +from System.Text.RegularExpressions import * + +from Deadline.Plugins import * +from Deadline.Scripting import * + +import _winreg + +###################################################################### +# This is the function that Deadline calls to get an instance of the +# main DeadlinePlugin class. +###################################################################### + + +def GetDeadlinePlugin(): + return CelActionPlugin() + + +def CleanupDeadlinePlugin(deadlinePlugin): + deadlinePlugin.Cleanup() + +###################################################################### +# This is the main DeadlinePlugin class for the CelAction plugin. +###################################################################### + + +class CelActionPlugin(DeadlinePlugin): + + def __init__(self): + self.InitializeProcessCallback += self.InitializeProcess + self.RenderExecutableCallback += self.RenderExecutable + self.RenderArgumentCallback += self.RenderArgument + self.StartupDirectoryCallback += self.StartupDirectory + + def Cleanup(self): + for stdoutHandler in self.StdoutHandlers: + del stdoutHandler.HandleCallback + + del self.InitializeProcessCallback + del self.RenderExecutableCallback + del self.RenderArgumentCallback + del self.StartupDirectoryCallback + + def GetCelActionRegistryKey(self): + # Modify registry for frame separation + path = r'Software\CelAction\CelAction2D\User Settings' + _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, path) + regKey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, path, 0, + _winreg.KEY_ALL_ACCESS) + return regKey + + def GetSeparatorValue(self, regKey): + useSeparator, _ = _winreg.QueryValueEx( + regKey, 'RenderNameUseSeparator') + separator, _ = _winreg.QueryValueEx(regKey, 'RenderNameSeparator') + + return useSeparator, separator + + def SetSeparatorValue(self, regKey, useSeparator, separator): + _winreg.SetValueEx(regKey, 'RenderNameUseSeparator', + 0, _winreg.REG_DWORD, useSeparator) + _winreg.SetValueEx(regKey, 'RenderNameSeparator', + 0, _winreg.REG_SZ, separator) + + def InitializeProcess(self): + # Set the plugin specific settings. + self.SingleFramesOnly = False + + # Set the process specific settings. + self.StdoutHandling = True + self.PopupHandling = True + + # Ignore 'celaction' Pop-up dialog + self.AddPopupIgnorer(".*Rendering.*") + + # Ignore 'celaction' Pop-up dialog + self.AddPopupIgnorer(".*Wait.*") + + # Ignore 'celaction' Pop-up dialog + self.AddPopupIgnorer(".*Timeline Scrub.*") + + celActionRegKey = self.GetCelActionRegistryKey() + + self.SetSeparatorValue(celActionRegKey, 1, self.GetConfigEntryWithDefault( + "RenderNameSeparator", ".").strip()) + + def RenderExecutable(self): + return RepositoryUtils.CheckPathMapping(self.GetConfigEntry("Executable").strip()) + + def RenderArgument(self): + arguments = RepositoryUtils.CheckPathMapping( + self.GetPluginInfoEntry("Arguments").strip()) + arguments = arguments.replace( + "", str(self.GetStartFrame())) + arguments = arguments.replace("", str(self.GetEndFrame())) + arguments = self.ReplacePaddedFrame( + arguments, "", self.GetStartFrame()) + arguments = self.ReplacePaddedFrame( + arguments, "", self.GetEndFrame()) + arguments = arguments.replace("", "\"") + return arguments + + def StartupDirectory(self): + return self.GetPluginInfoEntryWithDefault("StartupDirectory", "").strip() + + def ReplacePaddedFrame(self, arguments, pattern, frame): + frameRegex = Regex(pattern) + while True: + frameMatch = frameRegex.Match(arguments) + if frameMatch.Success: + paddingSize = int(frameMatch.Groups[1].Value) + if paddingSize > 0: + padding = StringUtils.ToZeroPaddedString( + frame, paddingSize, False) + else: + padding = str(frame) + arguments = arguments.replace( + frameMatch.Groups[0].Value, padding) + else: + break + + return arguments From 04ac17455790ffdb6275ae31d0ec4bb4f595732e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 12:30:31 +0100 Subject: [PATCH 20/43] adding .eslintignore file for deadline plugin --- openpype/hosts/celaction/resources/.eslintignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 openpype/hosts/celaction/resources/.eslintignore diff --git a/openpype/hosts/celaction/resources/.eslintignore b/openpype/hosts/celaction/resources/.eslintignore new file mode 100644 index 0000000000..17a45423da --- /dev/null +++ b/openpype/hosts/celaction/resources/.eslintignore @@ -0,0 +1 @@ +deadline_custom_plugin/CelAction/* \ No newline at end of file From 86608dd106f2421062a8746b85caa89a729cb714 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 12:40:53 +0100 Subject: [PATCH 21/43] trying better flake8 ignore --- openpype/hosts/celaction/resources/.eslintignore | 1 - openpype/hosts/celaction/resources/.flake8 | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 openpype/hosts/celaction/resources/.eslintignore create mode 100644 openpype/hosts/celaction/resources/.flake8 diff --git a/openpype/hosts/celaction/resources/.eslintignore b/openpype/hosts/celaction/resources/.eslintignore deleted file mode 100644 index 17a45423da..0000000000 --- a/openpype/hosts/celaction/resources/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -deadline_custom_plugin/CelAction/* \ No newline at end of file diff --git a/openpype/hosts/celaction/resources/.flake8 b/openpype/hosts/celaction/resources/.flake8 new file mode 100644 index 0000000000..6cc095c684 --- /dev/null +++ b/openpype/hosts/celaction/resources/.flake8 @@ -0,0 +1,3 @@ +[flake8] +exclude = + */deadline_custom_plugin/CelAction \ No newline at end of file From f8e3e99aad1af2c4571725f6be7c9617a4768218 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 12:42:29 +0100 Subject: [PATCH 22/43] flake8 ignore almost done --- setup.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 0a9664033d..a721b8e9f6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,7 +8,8 @@ exclude = docs, */vendor, website, - openpype/vendor + openpype/vendor, + */deadline_custom_plugin/CelAction max-complexity = 30 From ceabbe0de37a09915661456dd073ab55a98f8deb Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 12:44:34 +0100 Subject: [PATCH 23/43] flake8 file clearing --- openpype/hosts/celaction/resources/.flake8 | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 openpype/hosts/celaction/resources/.flake8 diff --git a/openpype/hosts/celaction/resources/.flake8 b/openpype/hosts/celaction/resources/.flake8 deleted file mode 100644 index 6cc095c684..0000000000 --- a/openpype/hosts/celaction/resources/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -exclude = - */deadline_custom_plugin/CelAction \ No newline at end of file From 6cefb2ec4b63744b0bed508b3d9671d69e022c57 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 15:01:14 +0100 Subject: [PATCH 24/43] celaction: deadline and settings improvements --- .../plugins/publish/collect_render_path.py | 26 +++++------ .../publish/submit_celaction_deadline.py | 5 +-- .../defaults/project_settings/celaction.json | 12 ++--- .../defaults/project_settings/deadline.json | 9 ++++ .../schema_project_celaction.json | 39 ++++------------ .../schema_project_deadline.json | 45 +++++++++++++++++++ 6 files changed, 82 insertions(+), 54 deletions(-) diff --git a/openpype/hosts/celaction/plugins/publish/collect_render_path.py b/openpype/hosts/celaction/plugins/publish/collect_render_path.py index ec89fc2e35..e5871f8792 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_render_path.py +++ b/openpype/hosts/celaction/plugins/publish/collect_render_path.py @@ -11,29 +11,29 @@ class CollectRenderPath(pyblish.api.InstancePlugin): families = ["render.farm"] # Presets - anatomy_render_key = None - publish_render_metadata = None + output_extension = "png" + anatomy_template_key_render_files = None + anatomy_template_key_metadata = None def process(self, instance): anatomy = instance.context.data["anatomy"] anatomy_data = copy.deepcopy(instance.data["anatomyData"]) - anatomy_data["family"] = "render" - padding = anatomy.templates.get("frame_padding", 4) anatomy_data.update({ - "frame": f"%0{padding}d", - "representation": "png", - "ext": "png" + "family": "render", + "representation": self.output_extension, + "ext": self.output_extension }) anatomy_filled = anatomy.format(anatomy_data) # get anatomy rendering keys - anatomy_render_key = self.anatomy_render_key or "render" - publish_render_metadata = self.publish_render_metadata or "render" + r_anatomy_key = self.anatomy_template_key_render_files + m_anatomy_key = self.anatomy_template_key_metadata # get folder and path for rendering images from celaction - render_dir = anatomy_filled[anatomy_render_key]["folder"] - render_path = anatomy_filled[anatomy_render_key]["path"] + render_dir = anatomy_filled[r_anatomy_key]["folder"] + render_path = anatomy_filled[r_anatomy_key]["path"] + self.log.debug("__ render_path: `{}`".format(render_path)) # create dir if it doesnt exists try: @@ -47,9 +47,9 @@ class CollectRenderPath(pyblish.api.InstancePlugin): instance.data["path"] = render_path # get anatomy for published renders folder path - if anatomy_filled.get(publish_render_metadata): + if anatomy_filled.get(m_anatomy_key): instance.data["publishRenderMetadataFolder"] = anatomy_filled[ - publish_render_metadata]["folder"] + m_anatomy_key]["folder"] self.log.info("Metadata render path: `{}`".format( instance.data["publishRenderMetadataFolder"] )) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index 8a3160e83d..e39c2c0061 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -7,11 +7,10 @@ import requests import pyblish.api -class ExtractCelactionDeadline(pyblish.api.InstancePlugin): +class CelactionSubmitDeadline(pyblish.api.InstancePlugin): """Submit CelAction2D scene to Deadline - Renders are submitted to a Deadline Web Service as - supplied via settings key "DEADLINE_REST_URL". + Renders are submitted to a Deadline Web Service. """ diff --git a/openpype/settings/defaults/project_settings/celaction.json b/openpype/settings/defaults/project_settings/celaction.json index a4a321fb27..dbe5625f06 100644 --- a/openpype/settings/defaults/project_settings/celaction.json +++ b/openpype/settings/defaults/project_settings/celaction.json @@ -1,13 +1,9 @@ { "publish": { - "ExtractCelactionDeadline": { - "enabled": true, - "deadline_department": "", - "deadline_priority": 50, - "deadline_pool": "", - "deadline_pool_secondary": "", - "deadline_group": "", - "deadline_chunk_size": 10 + "CollectRenderPath": { + "output_extension": "png", + "anatomy_template_key_render_files": "render", + "anatomy_template_key_metadata": "render" } } } \ No newline at end of file diff --git a/openpype/settings/defaults/project_settings/deadline.json b/openpype/settings/defaults/project_settings/deadline.json index a6e7b4a94a..8e892bb67e 100644 --- a/openpype/settings/defaults/project_settings/deadline.json +++ b/openpype/settings/defaults/project_settings/deadline.json @@ -70,6 +70,15 @@ "department": "", "multiprocess": true }, + "CelactionSubmitDeadline": { + "enabled": true, + "deadline_department": "", + "deadline_priority": 50, + "deadline_pool": "", + "deadline_pool_secondary": "", + "deadline_group": "", + "deadline_chunk_size": 10 + }, "ProcessSubmittedJobOnFarm": { "enabled": true, "deadline_department": "", diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_celaction.json b/openpype/settings/entities/schemas/projects_schema/schema_project_celaction.json index 500e5b2298..15d9350c84 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_celaction.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_celaction.json @@ -14,45 +14,24 @@ { "type": "dict", "collapsible": true, - "checkbox_key": "enabled", - "key": "ExtractCelactionDeadline", - "label": "ExtractCelactionDeadline", + "key": "CollectRenderPath", + "label": "CollectRenderPath", "is_group": true, "children": [ { - "type": "boolean", - "key": "enabled", - "label": "Enabled" + "type": "text", + "key": "output_extension", + "label": "Output render file extension" }, { "type": "text", - "key": "deadline_department", - "label": "Deadline apartment" - }, - { - "type": "number", - "key": "deadline_priority", - "label": "Deadline priority" + "key": "anatomy_template_key_render_files", + "label": "Anatomy template key: render files" }, { "type": "text", - "key": "deadline_pool", - "label": "Deadline pool" - }, - { - "type": "text", - "key": "deadline_pool_secondary", - "label": "Deadline pool (secondary)" - }, - { - "type": "text", - "key": "deadline_group", - "label": "Deadline Group" - }, - { - "type": "number", - "key": "deadline_chunk_size", - "label": "Deadline Chunk size" + "key": "anatomy_template_key_metadata", + "label": "Anatomy template key: metadata job file" } ] } diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index cd1741ba8b..77d520c54a 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -387,6 +387,51 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "CelactionSubmitDeadline", + "label": "CelactionSubmitDeadline", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "text", + "key": "deadline_department", + "label": "Deadline apartment" + }, + { + "type": "number", + "key": "deadline_priority", + "label": "Deadline priority" + }, + { + "type": "text", + "key": "deadline_pool", + "label": "Deadline pool" + }, + { + "type": "text", + "key": "deadline_pool_secondary", + "label": "Deadline pool (secondary)" + }, + { + "type": "text", + "key": "deadline_group", + "label": "Deadline Group" + }, + { + "type": "number", + "key": "deadline_chunk_size", + "label": "Deadline Chunk size" + } + ] + }, { "type": "dict", "collapsible": true, From ecbdac09e21f0f186d78cbb04c8030bbf1588e82 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:14:45 +0100 Subject: [PATCH 25/43] celaction: add local render target --- openpype/hosts/celaction/api/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/celaction/api/cli.py b/openpype/hosts/celaction/api/cli.py index e00a50cbec..4c07374b08 100644 --- a/openpype/hosts/celaction/api/cli.py +++ b/openpype/hosts/celaction/api/cli.py @@ -53,6 +53,7 @@ def main(): pyblish.api.register_plugin_path(PUBLISH_PATH) pyblish.api.register_host(PUBLISH_HOST) + pyblish.api.register_target("local") return host_tools.show_publish() From 6994e48a716e80a8b7cdb344d609826b0874b447 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:15:09 +0100 Subject: [PATCH 26/43] celaction: returning frame to anatomy data --- openpype/hosts/celaction/plugins/publish/collect_render_path.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/celaction/plugins/publish/collect_render_path.py b/openpype/hosts/celaction/plugins/publish/collect_render_path.py index e5871f8792..f6db6c000d 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_render_path.py +++ b/openpype/hosts/celaction/plugins/publish/collect_render_path.py @@ -18,7 +18,9 @@ class CollectRenderPath(pyblish.api.InstancePlugin): def process(self, instance): anatomy = instance.context.data["anatomy"] anatomy_data = copy.deepcopy(instance.data["anatomyData"]) + padding = anatomy.templates.get("frame_padding", 4) anatomy_data.update({ + "frame": f"%0{padding}d", "family": "render", "representation": self.output_extension, "ext": self.output_extension From f8b00d7ad4a66b93886b48c8100f42fdf9b6fb25 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:16:39 +0100 Subject: [PATCH 27/43] celaction: submit job from published workfile --- .../publish/submit_celaction_deadline.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index e39c2c0061..03d59b30fd 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -80,6 +80,26 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): render_dir = os.path.normpath(os.path.dirname(render_path)) render_path = os.path.normpath(render_path) script_name = os.path.basename(script_path) + + for item in instance.context: + if "workfile" in item.data["families"]: + msg = "Workfile (scene) must be published along" + assert item.data["publish"] is True, msg + + template_data = item.data.get("anatomyData") + rep = item.data.get("representations")[0].get("name") + template_data["representation"] = rep + template_data["ext"] = rep + template_data["comment"] = None + anatomy_filled = instance.context.data["anatomy"].format( + template_data) + template_filled = anatomy_filled["publish"]["path"] + script_path = os.path.normpath(template_filled) + + self.log.info( + "Using published scene for render {}".format(script_path) + ) + jobname = "%s - %s" % (script_name, instance.name) output_filename_0 = self.preview_fname(render_path) @@ -96,7 +116,7 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): chunk_size = self.deadline_chunk_size # search for %02d pattern in name, and padding number - search_results = re.search(r"(.%0)(\d)(d)[._]", render_path).groups() + search_results = re.search(r"(%0)(\d)(d)[._]", render_path).groups() split_patern = "".join(search_results) padding_number = int(search_results[1]) From 2117df1ad2a314e600178dec6c10d977cdfdc6e6 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:38:14 +0100 Subject: [PATCH 28/43] move deadline plugin to correct place --- .../custom/plugins}/CelAction/CelAction.ico | Bin .../custom/plugins}/CelAction/CelAction.param | 0 .../custom/plugins}/CelAction/CelAction.py | 1 + setup.cfg | 2 +- 4 files changed, 2 insertions(+), 1 deletion(-) rename openpype/{hosts/celaction/resources/deadline_custom_plugin => modules/deadline/repository/custom/plugins}/CelAction/CelAction.ico (100%) rename openpype/{hosts/celaction/resources/deadline_custom_plugin => modules/deadline/repository/custom/plugins}/CelAction/CelAction.param (100%) rename openpype/{hosts/celaction/resources/deadline_custom_plugin => modules/deadline/repository/custom/plugins}/CelAction/CelAction.py (98%) diff --git a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.ico b/openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.ico similarity index 100% rename from openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.ico rename to openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.ico diff --git a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.param b/openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.param similarity index 100% rename from openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.param rename to openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.param diff --git a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py b/openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.py similarity index 98% rename from openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py rename to openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.py index d19adc4fb9..2d0edd3dca 100644 --- a/openpype/hosts/celaction/resources/deadline_custom_plugin/CelAction/CelAction.py +++ b/openpype/modules/deadline/repository/custom/plugins/CelAction/CelAction.py @@ -71,6 +71,7 @@ class CelActionPlugin(DeadlinePlugin): # Ignore 'celaction' Pop-up dialog self.AddPopupIgnorer(".*Rendering.*") + self.AddPopupIgnorer(".*AutoRender.*") # Ignore 'celaction' Pop-up dialog self.AddPopupIgnorer(".*Wait.*") diff --git a/setup.cfg b/setup.cfg index a721b8e9f6..10cca3eb3f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,7 +9,7 @@ exclude = */vendor, website, openpype/vendor, - */deadline_custom_plugin/CelAction + *deadline/repository/custom/plugins max-complexity = 30 From 891a7e7609b9bd296af0923f3c508f9b8a203689 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:47:22 +0100 Subject: [PATCH 29/43] celaction: restructuring cli.py and kwargs --- openpype/hosts/celaction/api/__init__.py | 1 - openpype/hosts/celaction/hooks/pre_celaction_setup.py | 11 +++++------ .../plugins/publish/collect_celaction_cli_kwargs.py | 10 +++++----- .../plugins/publish/collect_celaction_instances.py | 3 ++- openpype/hosts/celaction/scripts/__init__.py | 1 + .../celaction/{api/cli.py => scripts/publish_cli.py} | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 openpype/hosts/celaction/api/__init__.py create mode 100644 openpype/hosts/celaction/scripts/__init__.py rename openpype/hosts/celaction/{api/cli.py => scripts/publish_cli.py} (93%) diff --git a/openpype/hosts/celaction/api/__init__.py b/openpype/hosts/celaction/api/__init__.py deleted file mode 100644 index 8c93d93738..0000000000 --- a/openpype/hosts/celaction/api/__init__.py +++ /dev/null @@ -1 +0,0 @@ -kwargs = None diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index cde3a0c723..21ff38b701 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -1,12 +1,11 @@ import os import shutil -import subprocess import winreg from openpype.lib import PreLaunchHook, get_openpype_execute_args -from openpype.hosts.celaction import api as caapi +from openpype.hosts.celaction import scripts -CELACTION_API_DIR = os.path.dirname( - os.path.abspath(caapi.__file__) +CELACTION_SCRIPTS_DIR = os.path.dirname( + os.path.abspath(scripts.__file__) ) @@ -38,7 +37,7 @@ class CelactionPrelaunchHook(PreLaunchHook): winreg.KEY_ALL_ACCESS ) - path_to_cli = os.path.join(CELACTION_API_DIR, "cli.py") + path_to_cli = os.path.join(CELACTION_SCRIPTS_DIR, "publish_cli.py") subproces_args = get_openpype_execute_args("run", path_to_cli) openpype_executables = subproces_args.pop(0) @@ -108,7 +107,7 @@ class CelactionPrelaunchHook(PreLaunchHook): if not os.path.exists(workfile_path): # TODO add ability to set different template workfile path via # settings - openpype_celaction_dir = os.path.dirname(CELACTION_API_DIR) + openpype_celaction_dir = os.path.dirname(CELACTION_SCRIPTS_DIR) template_path = os.path.join( openpype_celaction_dir, "resources", diff --git a/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py b/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py index 15c5ddaf1c..b82c0f5648 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py +++ b/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py @@ -1,5 +1,5 @@ import pyblish.api -from openpype.hosts.celaction import api as celaction +from openpype.hosts.celaction import scripts class CollectCelactionCliKwargs(pyblish.api.Collector): @@ -9,15 +9,15 @@ class CollectCelactionCliKwargs(pyblish.api.Collector): order = pyblish.api.Collector.order - 0.1 def process(self, context): - kwargs = celaction.kwargs.copy() + passing_kwargs = scripts.PASSING_KWARGS.copy() self.log.info("Storing kwargs: %s" % kwargs) - context.set_data("kwargs", kwargs) + context.set_data("passingKwargs", passing_kwargs) # get kwargs onto context data as keys with values - for k, v in kwargs.items(): + for k, v in passing_kwargs.items(): self.log.info(f"Setting `{k}` to instance.data with value: `{v}`") if k in ["frameStart", "frameEnd"]: - context.data[k] = kwargs[k] = int(v) + context.data[k] = passing_kwargs[k] = int(v) else: context.data[k] = v diff --git a/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py b/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py index b5f99a1416..35ac7fc264 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py +++ b/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py @@ -36,7 +36,8 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): "version": version } - celaction_kwargs = context.data.get("kwargs", {}) + celaction_kwargs = context.data.get( + "passingKwargs", {}) if celaction_kwargs: shared_instance_data.update(celaction_kwargs) diff --git a/openpype/hosts/celaction/scripts/__init__.py b/openpype/hosts/celaction/scripts/__init__.py new file mode 100644 index 0000000000..dfd9b37ae2 --- /dev/null +++ b/openpype/hosts/celaction/scripts/__init__.py @@ -0,0 +1 @@ +PASSING_KWARGS = None diff --git a/openpype/hosts/celaction/api/cli.py b/openpype/hosts/celaction/scripts/publish_cli.py similarity index 93% rename from openpype/hosts/celaction/api/cli.py rename to openpype/hosts/celaction/scripts/publish_cli.py index 4c07374b08..586880dc4c 100644 --- a/openpype/hosts/celaction/api/cli.py +++ b/openpype/hosts/celaction/scripts/publish_cli.py @@ -7,7 +7,7 @@ import pyblish.util import openpype.hosts.celaction from openpype.lib import Logger -from openpype.hosts.celaction import api as celaction +from openpype.hosts.celaction import scripts from openpype.tools.utils import host_tools from openpype.pipeline import install_openpype_plugins @@ -41,7 +41,7 @@ def cli(): parser.add_argument("--resolutionHeight", help=("Height of resolution")) - celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ + scripts.PASSING_KWARGS = parser.parse_args(sys.argv[1:]).__dict__ def main(): From 91580fdb301dd9907660a6a2b145b775f961ac97 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:51:44 +0100 Subject: [PATCH 30/43] celaction: hook should define data from asset_doc rather then from project doc --- openpype/hosts/celaction/hooks/pre_celaction_setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index 21ff38b701..a8fc7f322e 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -18,9 +18,9 @@ class CelactionPrelaunchHook(PreLaunchHook): platforms = ["windows"] def execute(self): - project_doc = self.data["project_doc"] - width = project_doc["data"]["resolutionWidth"] - height = project_doc["data"]["resolutionHeight"] + asset_doc = self.data["asset_doc"] + width = asset_doc["data"]["resolutionWidth"] + height = asset_doc["data"]["resolutionHeight"] # Add workfile path to launch arguments workfile_path = self.workfile_path() From a4e6f67692e46208bb80465987359aeebc610ca3 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 16:56:19 +0100 Subject: [PATCH 31/43] celaction: fix kwargs print --- .../plugins/publish/collect_celaction_cli_kwargs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py b/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py index b82c0f5648..e552e9ba6a 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py +++ b/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py @@ -1,5 +1,6 @@ import pyblish.api from openpype.hosts.celaction import scripts +from pprint import pformat class CollectCelactionCliKwargs(pyblish.api.Collector): @@ -11,7 +12,10 @@ class CollectCelactionCliKwargs(pyblish.api.Collector): def process(self, context): passing_kwargs = scripts.PASSING_KWARGS.copy() - self.log.info("Storing kwargs: %s" % kwargs) + self.log.info("Storing kwargs ...") + self.log.debug("_ passing_kwargs: {}".format(pformat(passing_kwargs))) + + # set kwargs to context data context.set_data("passingKwargs", passing_kwargs) # get kwargs onto context data as keys with values From 30550c26b01bbe502abaf74562408bd0f1308475 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 17:04:19 +0100 Subject: [PATCH 32/43] celaction: render from published workfile fix --- .../deadline/plugins/publish/submit_celaction_deadline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index 03d59b30fd..3be864781f 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -82,7 +82,7 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): script_name = os.path.basename(script_path) for item in instance.context: - if "workfile" in item.data["families"]: + if "workfile" in item.data["family"]: msg = "Workfile (scene) must be published along" assert item.data["publish"] is True, msg From 0c475d5b9d1edaad6ce1c47f16e87f297c3443c4 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 17:40:23 +0100 Subject: [PATCH 33/43] celaction: deadline job delay settings --- .../publish/submit_celaction_deadline.py | 78 ++++++++++++++----- .../defaults/project_settings/deadline.json | 3 +- .../schema_project_deadline.json | 5 ++ 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index 3be864781f..f716621d59 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -5,7 +5,7 @@ import getpass import requests import pyblish.api - +from openpype.pipeline import legacy_io class CelactionSubmitDeadline(pyblish.api.InstancePlugin): """Submit CelAction2D scene to Deadline @@ -25,12 +25,7 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): deadline_pool_secondary = "" deadline_group = "" deadline_chunk_size = 1 - - enviro_filter = [ - "FTRACK_API_USER", - "FTRACK_API_KEY", - "FTRACK_SERVER" - ] + deadline_job_delay = "00:00:08:00" def process(self, instance): instance.data["toBeRenderedOn"] = "deadline" @@ -163,10 +158,11 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): # frames from Deadline Monitor "OutputFilename0": output_filename_0.replace("\\", "/"), - # # Asset dependency to wait for at least the scene file to sync. + # # Asset dependency to wait for at least + # the scene file to sync. # "AssetDependency0": script_path "ScheduledType": "Once", - "JobDelay": "00:00:08:00" + "JobDelay": self.deadline_job_delay }, "PluginInfo": { # Input @@ -191,18 +187,58 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): plugin = payload["JobInfo"]["Plugin"] self.log.info("using render plugin : {}".format(plugin)) - i = 0 - for key, values in dict(os.environ).items(): - if key.upper() in self.enviro_filter: - payload["JobInfo"].update( - { - "EnvironmentKeyValue%d" - % i: "{key}={value}".format( - key=key, value=values - ) - } - ) - i += 1 + # Include critical environment variables with submission + keys = [ + "PYTHONPATH", + "PATH", + "AVALON_PROJECT", + "AVALON_ASSET", + "AVALON_TASK", + "AVALON_APP_NAME", + "FTRACK_API_KEY", + "FTRACK_API_USER", + "FTRACK_SERVER", + "PYBLISHPLUGINPATH", + "NUKE_PATH", + "TOOL_ENV", + "FOUNDRY_LICENSE", + "OPENPYPE_VERSION" + ] + # Add mongo url if it's enabled + if instance.context.data.get("deadlinePassMongoUrl"): + keys.append("OPENPYPE_MONGO") + + # add allowed keys from preset if any + if self.env_allowed_keys: + keys += self.env_allowed_keys + + environment = dict({ + key: os.environ[key] for key in keys + if key in os.environ}, **legacy_io.Session + ) + + for _path in os.environ: + if _path.lower().startswith('openpype_'): + environment[_path] = os.environ[_path] + + # to recognize job from OPENPYPE for turning Event On/Off + environment.update({ + "OPENPYPE_LOG_NO_COLORS": "1", + "OPENPYPE_RENDER_JOB": "1" + }) + + # finally search replace in values of any key + if self.env_search_replace_values: + for key, value in environment.items(): + for _k, _v in self.env_search_replace_values.items(): + environment[key] = value.replace(_k, _v) + + payload["JobInfo"].update({ + "EnvironmentKeyValue%d" % index: "{key}={value}".format( + key=key, + value=environment[key] + ) for index, key in enumerate(environment) + }) self.log.info("Submitting..") self.log.info(json.dumps(payload, indent=4, sort_keys=True)) diff --git a/openpype/settings/defaults/project_settings/deadline.json b/openpype/settings/defaults/project_settings/deadline.json index 8e892bb67e..6e1c0f3540 100644 --- a/openpype/settings/defaults/project_settings/deadline.json +++ b/openpype/settings/defaults/project_settings/deadline.json @@ -77,7 +77,8 @@ "deadline_pool": "", "deadline_pool_secondary": "", "deadline_group": "", - "deadline_chunk_size": 10 + "deadline_chunk_size": 10, + "deadline_job_delay": "00:00:00:00" }, "ProcessSubmittedJobOnFarm": { "enabled": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index 77d520c54a..5295b0e9d6 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -429,6 +429,11 @@ "type": "number", "key": "deadline_chunk_size", "label": "Deadline Chunk size" + }, + { + "type": "text", + "key": "deadline_job_delay", + "label": "Delay job (timecode dd:hh:mm:ss)" } ] }, From eb1b6e037b09c20bca12ab335ec675aeae0b311e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 17:42:22 +0100 Subject: [PATCH 34/43] label readability --- .../schemas/projects_schema/schema_project_deadline.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index 5295b0e9d6..69f81ed682 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -392,7 +392,7 @@ "collapsible": true, "checkbox_key": "enabled", "key": "CelactionSubmitDeadline", - "label": "CelactionSubmitDeadline", + "label": "Celaction Submit Deadline", "is_group": true, "children": [ { From 9f5e892a678307dec9b3d577a0ae1364a680af06 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 17:49:09 +0100 Subject: [PATCH 35/43] removing redundant code --- .../plugins/publish/submit_celaction_deadline.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index f716621d59..e5b06b007c 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -208,10 +208,6 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): if instance.context.data.get("deadlinePassMongoUrl"): keys.append("OPENPYPE_MONGO") - # add allowed keys from preset if any - if self.env_allowed_keys: - keys += self.env_allowed_keys - environment = dict({ key: os.environ[key] for key in keys if key in os.environ}, **legacy_io.Session @@ -227,12 +223,6 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): "OPENPYPE_RENDER_JOB": "1" }) - # finally search replace in values of any key - if self.env_search_replace_values: - for key, value in environment.items(): - for _k, _v in self.env_search_replace_values.items(): - environment[key] = value.replace(_k, _v) - payload["JobInfo"].update({ "EnvironmentKeyValue%d" % index: "{key}={value}".format( key=key, From 3491ef73ac54a98cab2e759c81a211a44549ea37 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 22:25:41 +0100 Subject: [PATCH 36/43] remove nuke code --- .../deadline/plugins/publish/submit_celaction_deadline.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index e5b06b007c..0583e146a7 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -199,9 +199,7 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): "FTRACK_API_USER", "FTRACK_SERVER", "PYBLISHPLUGINPATH", - "NUKE_PATH", "TOOL_ENV", - "FOUNDRY_LICENSE", "OPENPYPE_VERSION" ] # Add mongo url if it's enabled From f162ec56d76b1fe4a6b4267ea1fdfe3ca6ee6927 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 22:58:22 +0100 Subject: [PATCH 37/43] celaction: removing environment from job --- .../publish/submit_celaction_deadline.py | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index 0583e146a7..9a7d74c1f7 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -187,47 +187,6 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): plugin = payload["JobInfo"]["Plugin"] self.log.info("using render plugin : {}".format(plugin)) - # Include critical environment variables with submission - keys = [ - "PYTHONPATH", - "PATH", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_APP_NAME", - "FTRACK_API_KEY", - "FTRACK_API_USER", - "FTRACK_SERVER", - "PYBLISHPLUGINPATH", - "TOOL_ENV", - "OPENPYPE_VERSION" - ] - # Add mongo url if it's enabled - if instance.context.data.get("deadlinePassMongoUrl"): - keys.append("OPENPYPE_MONGO") - - environment = dict({ - key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session - ) - - for _path in os.environ: - if _path.lower().startswith('openpype_'): - environment[_path] = os.environ[_path] - - # to recognize job from OPENPYPE for turning Event On/Off - environment.update({ - "OPENPYPE_LOG_NO_COLORS": "1", - "OPENPYPE_RENDER_JOB": "1" - }) - - payload["JobInfo"].update({ - "EnvironmentKeyValue%d" % index: "{key}={value}".format( - key=key, - value=environment[key] - ) for index, key in enumerate(environment) - }) - self.log.info("Submitting..") self.log.info(json.dumps(payload, indent=4, sort_keys=True)) From 193112c18bcb17c829ea4afb6813823bf10d888e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 25 Nov 2022 22:58:53 +0100 Subject: [PATCH 38/43] deadline: adding openpype version to global job --- openpype/modules/deadline/plugins/publish/submit_publish_job.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 6362b4ca65..249211e965 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -241,6 +241,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): environment["AVALON_ASSET"] = legacy_io.Session["AVALON_ASSET"] environment["AVALON_TASK"] = legacy_io.Session["AVALON_TASK"] environment["AVALON_APP_NAME"] = os.environ.get("AVALON_APP_NAME") + environment["OPENPYPE_VERSION"] = os.environ.get("OPENPYPE_VERSION") environment["OPENPYPE_LOG_NO_COLORS"] = "1" environment["OPENPYPE_USERNAME"] = instance.context.data["user"] environment["OPENPYPE_PUBLISH_JOB"] = "1" From c2e9bdf161b7b073a2133efb2ce9d04e2360540d Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Sat, 26 Nov 2022 21:35:40 +0100 Subject: [PATCH 39/43] celaction: DL improving code --- .../publish/submit_celaction_deadline.py | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index 9a7d74c1f7..7913851d8a 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -2,10 +2,9 @@ import os import re import json import getpass - import requests import pyblish.api -from openpype.pipeline import legacy_io + class CelactionSubmitDeadline(pyblish.api.InstancePlugin): """Submit CelAction2D scene to Deadline @@ -194,10 +193,15 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): self.expected_files(instance, render_path) self.log.debug("__ expectedFiles: `{}`".format( instance.data["expectedFiles"])) + response = requests.post(self.deadline_url, json=payload) if not response.ok: - raise Exception(response.text) + self.log.error("Submission failed!") + self.log.error(response.status_code) + self.log.error(response.content) + self.log.debug(payload) + raise SystemExit(response.text) return response @@ -235,32 +239,29 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): split_path = path.split(split_patern) hashes = "#" * int(search_results[1]) return "".join([split_path[0], hashes, split_path[-1]]) - if "#" in path: - self.log.debug("_ path: `{}`".format(path)) - return path - else: - return path - def expected_files(self, - instance, - path): + self.log.debug("_ path: `{}`".format(path)) + return path + + def expected_files(self, instance, filepath): """ Create expected files in instance data """ if not instance.data.get("expectedFiles"): - instance.data["expectedFiles"] = list() + instance.data["expectedFiles"] = [] - dir = os.path.dirname(path) - file = os.path.basename(path) + dirpath = os.path.dirname(filepath) + filename = os.path.basename(filepath) - if "#" in file: - pparts = file.split("#") + if "#" in filename: + pparts = filename.split("#") padding = "%0{}d".format(len(pparts) - 1) - file = pparts[0] + padding + pparts[-1] + filename = pparts[0] + padding + pparts[-1] - if "%" not in file: - instance.data["expectedFiles"].append(path) + if "%" not in filename: + instance.data["expectedFiles"].append(filepath) return for i in range(self._frame_start, (self._frame_end + 1)): instance.data["expectedFiles"].append( - os.path.join(dir, (file % i)).replace("\\", "/")) + os.path.join(dirpath, (filename % i)).replace("\\", "/") + ) From 1f6be563eb6b28ef0988d55e6a143fe0e98d6aa1 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Sat, 26 Nov 2022 21:36:03 +0100 Subject: [PATCH 40/43] celaction: improving code PR feedback --- .../celaction/hooks/pre_celaction_setup.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/celaction/hooks/pre_celaction_setup.py b/openpype/hosts/celaction/hooks/pre_celaction_setup.py index a8fc7f322e..62cebf99ed 100644 --- a/openpype/hosts/celaction/hooks/pre_celaction_setup.py +++ b/openpype/hosts/celaction/hooks/pre_celaction_setup.py @@ -1,6 +1,7 @@ import os import shutil import winreg +import subprocess from openpype.lib import PreLaunchHook, get_openpype_execute_args from openpype.hosts.celaction import scripts @@ -13,7 +14,6 @@ class CelactionPrelaunchHook(PreLaunchHook): """ Bootstrap celacion with pype """ - workfile_ext = "scn" app_groups = ["celaction"] platforms = ["windows"] @@ -39,28 +39,28 @@ class CelactionPrelaunchHook(PreLaunchHook): path_to_cli = os.path.join(CELACTION_SCRIPTS_DIR, "publish_cli.py") subproces_args = get_openpype_execute_args("run", path_to_cli) - openpype_executables = subproces_args.pop(0) + openpype_executable = subproces_args.pop(0) winreg.SetValueEx( hKey, "SubmitAppTitle", 0, winreg.REG_SZ, - openpype_executables + openpype_executable ) parameters = subproces_args + [ - "--currentFile *SCENE*", - "--chunk *CHUNK*", - "--frameStart *START*", - "--frameEnd *END*", - "--resolutionWidth *X*", - "--resolutionHeight *Y*" + "--currentFile", "*SCENE*", + "--chunk", "*CHUNK*", + "--frameStart", "*START*", + "--frameEnd", "*END*", + "--resolutionWidth", "*X*", + "--resolutionHeight", "*Y*" ] winreg.SetValueEx( hKey, "SubmitParametersTitle", 0, winreg.REG_SZ, - " ".join(parameters) + subprocess.list2cmdline(parameters) ) # setting resolution parameters From f128425155e0144378882cc0b71d5444d82c9f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Wed, 30 Nov 2022 17:27:12 +0100 Subject: [PATCH 41/43] Update openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../deadline/plugins/publish/submit_celaction_deadline.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index 7913851d8a..ea44a24459 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -197,9 +197,9 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin): response = requests.post(self.deadline_url, json=payload) if not response.ok: - self.log.error("Submission failed!") - self.log.error(response.status_code) - self.log.error(response.content) + self.log.error( + "Submission failed! [{}] {}".format( + response.status_code, response.content)) self.log.debug(payload) raise SystemExit(response.text) From 7a90f8f084b8f0d242564584b4df296106c997f9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 30 Nov 2022 17:33:47 +0100 Subject: [PATCH 42/43] celaction: shifting argparse to publish plugin --- .../publish/collect_celaction_cli_kwargs.py | 18 +++++++++++-- openpype/hosts/celaction/scripts/__init__.py | 1 - .../hosts/celaction/scripts/publish_cli.py | 27 ------------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py b/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py index e552e9ba6a..bf97dd744b 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py +++ b/openpype/hosts/celaction/plugins/publish/collect_celaction_cli_kwargs.py @@ -1,5 +1,6 @@ import pyblish.api -from openpype.hosts.celaction import scripts +import argparse +import sys from pprint import pformat @@ -10,7 +11,20 @@ class CollectCelactionCliKwargs(pyblish.api.Collector): order = pyblish.api.Collector.order - 0.1 def process(self, context): - passing_kwargs = scripts.PASSING_KWARGS.copy() + parser = argparse.ArgumentParser(prog="celaction") + parser.add_argument("--currentFile", + help="Pass file to Context as `currentFile`") + parser.add_argument("--chunk", + help=("Render chanks on farm")) + parser.add_argument("--frameStart", + help=("Start of frame range")) + parser.add_argument("--frameEnd", + help=("End of frame range")) + parser.add_argument("--resolutionWidth", + help=("Width of resolution")) + parser.add_argument("--resolutionHeight", + help=("Height of resolution")) + passing_kwargs = parser.parse_args(sys.argv[1:]).__dict__ self.log.info("Storing kwargs ...") self.log.debug("_ passing_kwargs: {}".format(pformat(passing_kwargs))) diff --git a/openpype/hosts/celaction/scripts/__init__.py b/openpype/hosts/celaction/scripts/__init__.py index dfd9b37ae2..e69de29bb2 100644 --- a/openpype/hosts/celaction/scripts/__init__.py +++ b/openpype/hosts/celaction/scripts/__init__.py @@ -1 +0,0 @@ -PASSING_KWARGS = None diff --git a/openpype/hosts/celaction/scripts/publish_cli.py b/openpype/hosts/celaction/scripts/publish_cli.py index 586880dc4c..39d3f1a94d 100644 --- a/openpype/hosts/celaction/scripts/publish_cli.py +++ b/openpype/hosts/celaction/scripts/publish_cli.py @@ -1,13 +1,11 @@ import os import sys -import argparse import pyblish.api import pyblish.util import openpype.hosts.celaction from openpype.lib import Logger -from openpype.hosts.celaction import scripts from openpype.tools.utils import host_tools from openpype.pipeline import install_openpype_plugins @@ -20,30 +18,6 @@ PLUGINS_DIR = os.path.join(HOST_DIR, "plugins") PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish") -def cli(): - parser = argparse.ArgumentParser(prog="celaction_publish") - - parser.add_argument("--currentFile", - help="Pass file to Context as `currentFile`") - - parser.add_argument("--chunk", - help=("Render chanks on farm")) - - parser.add_argument("--frameStart", - help=("Start of frame range")) - - parser.add_argument("--frameEnd", - help=("End of frame range")) - - parser.add_argument("--resolutionWidth", - help=("Width of resolution")) - - parser.add_argument("--resolutionHeight", - help=("Height of resolution")) - - scripts.PASSING_KWARGS = parser.parse_args(sys.argv[1:]).__dict__ - - def main(): # Registers pype's Global pyblish plugins install_openpype_plugins() @@ -59,6 +33,5 @@ def main(): if __name__ == "__main__": - cli() result = main() sys.exit(not bool(result)) From 4acbb9fa1823aec8adcec1e25e69c48a49a51979 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 1 Dec 2022 14:19:30 +0100 Subject: [PATCH 43/43] general: integrate skips transfere files in src == dst --- openpype/plugins/publish/integrate.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/plugins/publish/integrate.py b/openpype/plugins/publish/integrate.py index 401270a788..7e4fc84658 100644 --- a/openpype/plugins/publish/integrate.py +++ b/openpype/plugins/publish/integrate.py @@ -291,6 +291,9 @@ class IntegrateAsset(pyblish.api.InstancePlugin): instance) for src, dst in prepared["transfers"]: + if src == dst: + continue + # todo: add support for hardlink transfers file_transactions.add(src, dst)