mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 08:24:53 +01:00
Merge pull request #1016 from pypeclub/feature/launch_script_for_non_python_hosts
Launch script for non python hosts
This commit is contained in:
commit
249f533e73
5 changed files with 153 additions and 147 deletions
|
|
@ -1,52 +0,0 @@
|
|||
import os
|
||||
|
||||
from pype.lib import PreLaunchHook
|
||||
|
||||
|
||||
class AfterEffectsPrelaunchHook(PreLaunchHook):
|
||||
"""Launch arguments preparation.
|
||||
|
||||
Hook add python executable and execute python script of AfterEffects
|
||||
implementation before AfterEffects executable.
|
||||
"""
|
||||
app_groups = ["aftereffects"]
|
||||
|
||||
def execute(self):
|
||||
# Pop tvpaint executable
|
||||
aftereffects_executable = self.launch_context.launch_args.pop(0)
|
||||
|
||||
# Pop rest of launch arguments - There should not be other arguments!
|
||||
remainders = []
|
||||
while self.launch_context.launch_args:
|
||||
remainders.append(self.launch_context.launch_args.pop(0))
|
||||
|
||||
workfile_path = self.data["last_workfile_path"]
|
||||
if not os.path.exists(workfile_path):
|
||||
workfile_path = ""
|
||||
|
||||
new_launch_args = [
|
||||
self.python_executable(),
|
||||
"-c",
|
||||
(
|
||||
"import avalon.aftereffects;"
|
||||
"avalon.aftereffects.launch(\"{}\", \"{}\")"
|
||||
).format(
|
||||
aftereffects_executable.replace("\\", "\\\\"),
|
||||
workfile_path.replace("\\", "\\\\")
|
||||
)
|
||||
]
|
||||
|
||||
# Append as whole list as these arguments should not be separated
|
||||
self.launch_context.launch_args.append(new_launch_args)
|
||||
|
||||
if remainders:
|
||||
self.log.warning((
|
||||
"There are unexpected launch arguments "
|
||||
"in AfterEffects launch. {}"
|
||||
).format(str(remainders)))
|
||||
self.launch_context.launch_args.extend(remainders)
|
||||
|
||||
def python_executable(self):
|
||||
"""Should lead to python executable."""
|
||||
# TODO change in Pype 3
|
||||
return os.environ["PYPE_PYTHON_EXE"]
|
||||
46
pype/hooks/global/pre_non_python_host_launch.py
Normal file
46
pype/hooks/global/pre_non_python_host_launch.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import os
|
||||
|
||||
from pype.lib import (
|
||||
PreLaunchHook,
|
||||
get_pype_execute_args
|
||||
)
|
||||
import pype.PACKAGE_DIR
|
||||
|
||||
|
||||
class NonPythonHostHook(PreLaunchHook):
|
||||
"""Launch arguments preparation.
|
||||
|
||||
Non python host implementation do not launch host directly but use
|
||||
python script which launch the host. For these cases it is necessary to
|
||||
prepend python (or pype) executable and script path before application's.
|
||||
"""
|
||||
app_groups = ["harmony", "photoshop", "aftereffects"]
|
||||
|
||||
def execute(self):
|
||||
# Pop executable
|
||||
executable_path = self.launch_context.launch_args.pop(0)
|
||||
|
||||
# Pop rest of launch arguments - There should not be other arguments!
|
||||
remainders = []
|
||||
while self.launch_context.launch_args:
|
||||
remainders.append(self.launch_context.launch_args.pop(0))
|
||||
|
||||
script_path = os.path.join(
|
||||
pype.PACKAGE_DIR,
|
||||
"scripts",
|
||||
"non_python_host_launch.py"
|
||||
)
|
||||
|
||||
new_launch_args = get_pype_execute_args(
|
||||
"run", script_path, executable_path
|
||||
)
|
||||
# Add workfile path if exists
|
||||
workfile_path = self.data["last_workfile_path"]
|
||||
if os.path.exists(workfile_path):
|
||||
new_launch_args.append(workfile_path)
|
||||
|
||||
# Append as whole list as these areguments should not be separated
|
||||
self.launch_context.launch_args.append(new_launch_args)
|
||||
|
||||
if remainders:
|
||||
self.launch_context.launch_args.extend(remainders)
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import os
|
||||
|
||||
from pype.lib import PreLaunchHook
|
||||
|
||||
|
||||
class HarmonyPrelaunchHook(PreLaunchHook):
|
||||
"""Launch arguments preparation.
|
||||
|
||||
Hook add python executable and execute python script of harmony
|
||||
implementation before harmony executable.
|
||||
"""
|
||||
app_groups = ["harmony"]
|
||||
|
||||
def execute(self):
|
||||
# Pop tvpaint executable
|
||||
harmony_executable = self.launch_context.launch_args.pop(0)
|
||||
|
||||
# Pop rest of launch arguments - There should not be other arguments!
|
||||
remainders = []
|
||||
while self.launch_context.launch_args:
|
||||
remainders.append(self.launch_context.launch_args.pop(0))
|
||||
|
||||
new_launch_args = [
|
||||
self.python_executable(),
|
||||
"-c",
|
||||
(
|
||||
"import avalon.harmony;"
|
||||
"avalon.harmony.launch(\"{}\")"
|
||||
).format(harmony_executable.replace("\\", "\\\\"))
|
||||
]
|
||||
|
||||
# Append as whole list as these areguments should not be separated
|
||||
self.launch_context.launch_args.append(new_launch_args)
|
||||
|
||||
if remainders:
|
||||
self.log.warning((
|
||||
"There are unexpected launch arguments in Harmony launch. {}"
|
||||
).format(str(remainders)))
|
||||
self.launch_context.launch_args.extend(remainders)
|
||||
|
||||
def python_executable(self):
|
||||
"""Should lead to python executable."""
|
||||
# TODO change in Pype 3
|
||||
return os.environ["PYPE_PYTHON_EXE"]
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
import os
|
||||
|
||||
from pype.lib import PreLaunchHook
|
||||
|
||||
|
||||
class PhotoshopPrelaunchHook(PreLaunchHook):
|
||||
"""Launch arguments preparation.
|
||||
|
||||
Hook add python executable and execute python script of photoshop
|
||||
implementation before photoshop executable.
|
||||
"""
|
||||
app_groups = ["photoshop"]
|
||||
|
||||
def execute(self):
|
||||
# Pop tvpaint executable
|
||||
photoshop_executable = self.launch_context.launch_args.pop(0)
|
||||
|
||||
# Pop rest of launch arguments - There should not be other arguments!
|
||||
remainders = []
|
||||
while self.launch_context.launch_args:
|
||||
remainders.append(self.launch_context.launch_args.pop(0))
|
||||
|
||||
workfile_path = self.data["last_workfile_path"]
|
||||
if not os.path.exists(workfile_path):
|
||||
workfile_path = ""
|
||||
|
||||
new_launch_args = [
|
||||
self.python_executable(),
|
||||
"-c",
|
||||
(
|
||||
"import avalon.photoshop;"
|
||||
"avalon.photoshop.launch(\"{}\", \"{}\")"
|
||||
).format(
|
||||
photoshop_executable.replace("\\", "\\\\"),
|
||||
workfile_path.replace("\\", "\\\\")
|
||||
)
|
||||
]
|
||||
|
||||
# Append as whole list as these areguments should not be separated
|
||||
self.launch_context.launch_args.append(new_launch_args)
|
||||
|
||||
if remainders:
|
||||
self.log.warning((
|
||||
"There are unexpected launch arguments in Photoshop launch. {}"
|
||||
).format(str(remainders)))
|
||||
self.launch_context.launch_args.extend(remainders)
|
||||
|
||||
def python_executable(self):
|
||||
"""Should lead to python executable."""
|
||||
# TODO change in Pype 3
|
||||
return os.environ["PYPE_PYTHON_EXE"]
|
||||
107
pype/scripts/non_python_host_launch.py
Normal file
107
pype/scripts/non_python_host_launch.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
"""Script wraps launch mechanism of non python host implementations.
|
||||
|
||||
Arguments passed to the script are passed to launch function in host
|
||||
implementation. In all cases requires host app executable and may contain
|
||||
workfile or others.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Get current file to locate start point of sys.argv
|
||||
CURRENT_FILE = os.path.abspath(__file__)
|
||||
|
||||
|
||||
def show_error_messagebox(title, message, detail_message=None):
|
||||
"""Function will show message and process ends after closing it."""
|
||||
from Qt import QtWidgets, QtCore
|
||||
from avalon import style
|
||||
|
||||
app = QtWidgets.QApplication([])
|
||||
app.setStyleSheet(style.load_stylesheet())
|
||||
|
||||
msgbox = QtWidgets.QMessageBox()
|
||||
msgbox.setWindowTitle(title)
|
||||
msgbox.setText(message)
|
||||
|
||||
if detail_message:
|
||||
msgbox.setDetailedText(detail_message)
|
||||
|
||||
msgbox.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
msgbox.show()
|
||||
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
def on_invalid_args(script_not_found):
|
||||
"""Show to user message box saying that something went wrong.
|
||||
|
||||
Tell user that arguments to launch implementation are invalid with
|
||||
arguments details.
|
||||
|
||||
Args:
|
||||
script_not_found (bool): Use different message based on this value.
|
||||
"""
|
||||
|
||||
title = "Invalid arguments"
|
||||
joined_args = ", ".join("\"{}\"".format(arg) for arg in sys.argv)
|
||||
if script_not_found:
|
||||
submsg = "Where couldn't find script path:\n\"{}\""
|
||||
else:
|
||||
submsg = "Expected Host executable after script path:\n\"{}\""
|
||||
|
||||
message = "BUG: Got invalid arguments so can't launch Host application."
|
||||
detail_message = "Process was launched with arguments:\n{}\n\n{}".format(
|
||||
joined_args,
|
||||
submsg.format(CURRENT_FILE)
|
||||
)
|
||||
|
||||
show_error_messagebox(title, message, detail_message)
|
||||
|
||||
|
||||
def main(argv):
|
||||
# Modify current file path to find match in sys.argv which may be different
|
||||
# on windows (different letter cases and slashes).
|
||||
modified_current_file = CURRENT_FILE.replace("\\", "/").lower()
|
||||
|
||||
# Create a copy of sys argv
|
||||
sys_args = list(argv)
|
||||
after_script_idx = None
|
||||
# Find script path in sys.argv to know index of argv where host
|
||||
# executable should be.
|
||||
for idx, item in enumerate(sys_args):
|
||||
if item.replace("\\", "/").lower() == modified_current_file:
|
||||
after_script_idx = idx + 1
|
||||
break
|
||||
|
||||
# Validate that there is at least one argument after script path
|
||||
launch_args = None
|
||||
if after_script_idx is not None:
|
||||
launch_args = sys_args[after_script_idx:]
|
||||
|
||||
host_name = os.environ["AVALON_APP"].lower()
|
||||
if host_name == "photoshop":
|
||||
from avalon.photoshop.lib import launch
|
||||
elif host_name == "aftereffects":
|
||||
from avalon.aftereffects.lib import launch
|
||||
elif host_name == "harmony":
|
||||
from avalon.photoshop.lib import launch
|
||||
else:
|
||||
title = "Unknown host name"
|
||||
message = (
|
||||
"BUG: Environment variable AVALON_APP contains unknown"
|
||||
" host name \"{}\""
|
||||
).format(host_name)
|
||||
show_error_messagebox(title, message)
|
||||
return
|
||||
|
||||
if launch_args:
|
||||
# Launch host implementation
|
||||
launch(*launch_args)
|
||||
else:
|
||||
# Show message box
|
||||
on_invalid_args(after_script_idx is None)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
Loading…
Add table
Add a link
Reference in a new issue