Merge branch 'develop' into bugfix/launcher-update-view-properly

This commit is contained in:
Jakub Trllo 2024-05-21 14:12:31 +02:00 committed by GitHub
commit abb5cdc344
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 177 additions and 145 deletions

View file

@ -80,17 +80,21 @@ def get_engine_versions(env=None):
def get_editor_exe_path(engine_path: Path, engine_version: str) -> Path:
"""Get UE Editor executable path."""
ue_path = engine_path / "Engine/Binaries"
ue_name = "UnrealEditor"
# handle older versions of Unreal Engine
if engine_version.split(".")[0] == "4":
ue_name = "UE4Editor"
if platform.system().lower() == "windows":
if engine_version.split(".")[0] == "4":
ue_path /= "Win64/UE4Editor.exe"
elif engine_version.split(".")[0] == "5":
ue_path /= "Win64/UnrealEditor.exe"
ue_path /= f"Win64/{ue_name}.exe"
elif platform.system().lower() == "linux":
ue_path /= "Linux/UE4Editor"
ue_path /= f"Linux/{ue_name}"
elif platform.system().lower() == "darwin":
ue_path /= "Mac/UE4Editor"
ue_path /= f"Mac/{ue_name}"
return ue_path

View file

@ -29,15 +29,11 @@ from ayon_core.pipeline.publish.lib import (
JSONDecodeError = getattr(json.decoder, "JSONDecodeError", ValueError)
# TODO both 'requests_post' and 'requests_get' should not set 'verify' based
# on environment variable. This should be done in a more controlled way,
# e.g. each deadline url could have checkbox to enabled/disable
# ssl verification.
def requests_post(*args, **kwargs):
"""Wrap request post method.
Disabling SSL certificate validation if ``DONT_VERIFY_SSL`` environment
variable is found. This is useful when Deadline server is
Disabling SSL certificate validation if ``verify`` kwarg is set to False.
This is useful when Deadline server is
running with self-signed certificates and its certificate is not
added to trusted certificates on client machines.
@ -46,10 +42,6 @@ def requests_post(*args, **kwargs):
of defense SSL is providing, and it is not recommended.
"""
if 'verify' not in kwargs:
kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL",
True) else True # noqa
auth = kwargs.get("auth")
if auth:
kwargs["auth"] = tuple(auth) # explicit cast to tuple
@ -61,8 +53,8 @@ def requests_post(*args, **kwargs):
def requests_get(*args, **kwargs):
"""Wrap request get method.
Disabling SSL certificate validation if ``DONT_VERIFY_SSL`` environment
variable is found. This is useful when Deadline server is
Disabling SSL certificate validation if ``verify`` kwarg is set to False.
This is useful when Deadline server is
running with self-signed certificates and its certificate is not
added to trusted certificates on client machines.
@ -71,9 +63,6 @@ def requests_get(*args, **kwargs):
of defense SSL is providing, and it is not recommended.
"""
if 'verify' not in kwargs:
kwargs['verify'] = False if os.getenv("OPENPYPE_DONT_VERIFY_SSL",
True) else True # noqa
auth = kwargs.get("auth")
if auth:
kwargs["auth"] = tuple(auth)
@ -466,7 +455,8 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin,
self.aux_files = self.get_aux_files()
auth = instance.data["deadline"]["auth"]
job_id = self.process_submission(auth)
verify = instance.data["deadline"]["verify"]
job_id = self.process_submission(auth, verify)
self.log.info("Submitted job to Deadline: {}.".format(job_id))
# TODO: Find a way that's more generic and not render type specific
@ -479,10 +469,10 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin,
job_info=render_job_info,
plugin_info=render_plugin_info
)
render_job_id = self.submit(payload, auth)
render_job_id = self.submit(payload, auth, verify)
self.log.info("Render job id: %s", render_job_id)
def process_submission(self, auth=None):
def process_submission(self, auth=None, verify=True):
"""Process data for submission.
This takes Deadline JobInfo, PluginInfo, AuxFile, creates payload
@ -493,7 +483,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin,
"""
payload = self.assemble_payload()
return self.submit(payload, auth)
return self.submit(payload, auth, verify)
@abstractmethod
def get_job_info(self):
@ -583,7 +573,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin,
"AuxFiles": aux_files or self.aux_files
}
def submit(self, payload, auth):
def submit(self, payload, auth, verify):
"""Submit payload to Deadline API end-point.
This takes payload in the form of JSON file and POST it to
@ -592,6 +582,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin,
Args:
payload (dict): dict to become json in deadline submission.
auth (tuple): (username, password)
verify (bool): verify SSL certificate if present
Returns:
str: resulting Deadline job id.
@ -601,8 +592,8 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin,
"""
url = "{}/api/jobs".format(self._deadline_url)
response = requests_post(url, json=payload,
auth=auth)
response = requests_post(
url, json=payload, auth=auth, verify=verify)
if not response.ok:
self.log.error("Submission failed!")
self.log.error(response.status_code)

View file

@ -76,6 +76,9 @@ class CollectDeadlineUserCredentials(pyblish.api.InstancePlugin):
)
instance.data["deadline"]["auth"] = None
instance.data["deadline"]["verify"] = (
not deadline_info["not_verify_ssl"])
if not deadline_info["require_authentication"]:
return
# TODO import 'get_addon_site_settings' when available

View file

@ -174,8 +174,9 @@ class BlenderSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
instance.data["toBeRenderedOn"] = "deadline"
payload = self.assemble_payload()
return self.submit(payload,
auth=instance.data["deadline"]["auth"])
auth = instance.data["deadline"]["auth"]
verify = instance.data["deadline"]["verify"]
return self.submit(payload, auth=auth, verify=verify)
def from_published_scene(self):
"""

View file

@ -193,9 +193,11 @@ class CelactionSubmitDeadline(pyblish.api.InstancePlugin):
self.expected_files(instance, render_path)
self.log.debug("__ expectedFiles: `{}`".format(
instance.data["expectedFiles"]))
auth = instance.data["deadline"]["auth"]
verify = instance.data["deadline"]["verify"]
response = requests_post(self.deadline_url, json=payload,
auth=instance.data["deadline"]["require_authentication"])
auth=auth,
verify=verify)
if not response.ok:
self.log.error(

View file

@ -242,7 +242,8 @@ class FusionSubmitDeadline(
# E.g. http://192.168.0.1:8082/api/jobs
url = "{}/api/jobs".format(deadline_url)
auth = instance.data["deadline"]["auth"]
response = requests_post(url, json=payload, auth=auth)
verify = instance.data["deadline"]["verify"]
response = requests_post(url, json=payload, auth=auth, verify=verify)
if not response.ok:
raise Exception(response.text)

View file

@ -181,19 +181,27 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
self.log.debug("Submitting 3dsMax render..")
project_settings = instance.context.data["project_settings"]
auth = instance.data["deadline"]["auth"]
verify = instance.data["deadline"]["verify"]
if instance.data.get("multiCamera"):
self.log.debug("Submitting jobs for multiple cameras..")
payload = self._use_published_name_for_multiples(
payload_data, project_settings)
job_infos, plugin_infos = payload
for job_info, plugin_info in zip(job_infos, plugin_infos):
self.submit(self.assemble_payload(job_info, plugin_info),
instance.data["deadline"]["auth"])
self.submit(
self.assemble_payload(job_info, plugin_info),
auth=auth,
verify=verify
)
else:
payload = self._use_published_name(payload_data, project_settings)
job_info, plugin_info = payload
self.submit(self.assemble_payload(job_info, plugin_info),
instance.data["deadline"]["auth"])
self.submit(
self.assemble_payload(job_info, plugin_info),
auth=auth,
verify=verify
)
def _use_published_name(self, data, project_settings):
# Not all hosts can import these modules.

View file

@ -292,7 +292,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
return plugin_payload
def process_submission(self, auth=None):
def process_submission(self, auth=None, verify=True):
from maya import cmds
instance = self._instance
@ -332,8 +332,10 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
if "vrayscene" in instance.data["families"]:
self.log.debug("Submitting V-Ray scene render..")
vray_export_payload = self._get_vray_export_payload(payload_data)
export_job = self.submit(vray_export_payload,
instance.data["deadline"]["auth"])
auth=auth,
verify=verify)
payload = self._get_vray_render_payload(payload_data)
@ -353,7 +355,8 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
# Submit main render job
job_info, plugin_info = payload
self.submit(self.assemble_payload(job_info, plugin_info),
instance.data["deadline"]["auth"])
auth=auth,
verify=verify)
def _tile_render(self, payload):
"""Submit as tile render per frame with dependent assembly jobs."""
@ -557,13 +560,18 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline,
# Submit assembly jobs
assembly_job_ids = []
num_assemblies = len(assembly_payloads)
auth = instance.data["deadline"]["auth"]
verify = instance.data["deadline"]["verify"]
for i, payload in enumerate(assembly_payloads):
self.log.debug(
"submitting assembly job {} of {}".format(i + 1,
num_assemblies)
)
assembly_job_id = self.submit(payload,
instance.data["deadline"]["auth"])
assembly_job_id = self.submit(
payload,
auth=auth,
verify=verify
)
assembly_job_ids.append(assembly_job_id)
instance.data["assemblySubmissionJobs"] = assembly_job_ids

View file

@ -424,8 +424,12 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin,
self.log.debug("__ expectedFiles: `{}`".format(
instance.data["expectedFiles"]))
auth = instance.data["deadline"]["auth"]
response = requests_post(self.deadline_url, json=payload, timeout=10,
auth=auth)
verify = instance.data["deadline"]["verify"]
response = requests_post(self.deadline_url,
json=payload,
timeout=10,
auth=auth,
verify=verify)
if not response.ok:
raise Exception(response.text)

View file

@ -210,8 +210,9 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin,
url = "{}/api/jobs".format(self.deadline_url)
auth = instance.data["deadline"]["auth"]
response = requests_post(url, json=payload, timeout=10,
auth=auth)
verify = instance.data["deadline"]["verify"]
response = requests_post(
url, json=payload, timeout=10, auth=auth, verify=verify)
if not response.ok:
raise Exception(response.text)

View file

@ -304,8 +304,9 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin,
url = "{}/api/jobs".format(self.deadline_url)
auth = instance.data["deadline"]["auth"]
response = requests_post(url, json=payload, timeout=10,
auth=auth)
verify = instance.data["deadline"]["verify"]
response = requests_post(
url, json=payload, timeout=10, auth=auth, verify=verify)
if not response.ok:
raise Exception(response.text)

View file

@ -920,7 +920,7 @@ def get_imageio_config_preset(
project_entity = None
if anatomy is None:
project_entity = ayon_api.get_project(project_name)
anatomy = Anatomy(project_name, project_entity)
anatomy = Anatomy(project_name, project_entity=project_entity)
if env is None:
env = dict(os.environ.items())

View file

@ -1,6 +1,11 @@
import pyblish.api
from ayon_core.lib import filter_profiles
from ayon_core.host import ILoadHost
from ayon_core.pipeline.load import any_outdated_containers
from ayon_core.pipeline import (
get_current_host_name,
registered_host,
PublishXmlValidationError,
OptionalPyblishPluginMixin
)
@ -18,17 +23,50 @@ class ShowInventory(pyblish.api.Action):
host_tools.show_scene_inventory()
class ValidateContainers(OptionalPyblishPluginMixin,
pyblish.api.ContextPlugin):
class ValidateOutdatedContainers(
OptionalPyblishPluginMixin,
pyblish.api.ContextPlugin
):
"""Containers are must be updated to latest version on publish."""
label = "Validate Outdated Containers"
order = pyblish.api.ValidatorOrder
hosts = ["maya", "houdini", "nuke", "harmony", "photoshop", "aftereffects"]
optional = True
actions = [ShowInventory]
@classmethod
def apply_settings(cls, settings):
# Disable plugin if host does not inherit from 'ILoadHost'
# - not a host that can load containers
host = registered_host()
if not isinstance(host, ILoadHost):
cls.enabled = False
return
# Disable if no profile is found for the current host
profiles = (
settings
["core"]
["publish"]
["ValidateOutdatedContainers"]
["plugin_state_profiles"]
)
profile = filter_profiles(
profiles, {"host_names": get_current_host_name()}
)
if not profile:
cls.enabled = False
return
# Apply settings from profile
for attr_name in {
"enabled",
"optional",
"active",
}:
setattr(cls, attr_name, profile[attr_name])
def process(self, context):
if not self.is_active(context.data):
return

View file

@ -723,7 +723,6 @@ class ProjectPushItemProcess:
dst_project_name = self._item.dst_project_name
dst_folder_id = self._item.dst_folder_id
dst_task_name = self._item.dst_task_name
dst_task_name_low = dst_task_name.lower()
new_folder_name = self._item.new_folder_name
if not dst_folder_id and not new_folder_name:
self._status.set_failed(
@ -765,7 +764,7 @@ class ProjectPushItemProcess:
dst_project_name, folder_ids=[folder_entity["id"]]
)
}
task_info = folder_tasks.get(dst_task_name_low)
task_info = folder_tasks.get(dst_task_name.lower())
if not task_info:
self._status.set_failed(
f"Could find task with name \"{dst_task_name}\""

View file

@ -59,6 +59,33 @@ class CollectFramesFixDefModel(BaseSettingsModel):
)
class ValidateOutdatedContainersProfile(BaseSettingsModel):
_layout = "expanded"
# Filtering
host_names: list[str] = SettingsField(
default_factory=list,
title="Host names"
)
# Profile values
enabled: bool = SettingsField(True, title="Enabled")
optional: bool = SettingsField(True, title="Optional")
active: bool = SettingsField(True, title="Active")
class ValidateOutdatedContainersModel(BaseSettingsModel):
"""Validate if Publishing intent was selected.
It is possible to disable validation for specific publishing context
with profiles.
"""
_isGroup = True
plugin_state_profiles: list[ValidateOutdatedContainersProfile] = SettingsField(
default_factory=list,
title="Plugin enable state profiles",
)
class ValidateIntentProfile(BaseSettingsModel):
_layout = "expanded"
hosts: list[str] = SettingsField(default_factory=list, title="Host names")
@ -770,6 +797,10 @@ class PublishPuginsModel(BaseSettingsModel):
default_factory=ValidateBaseModel,
title="Validate Version"
)
ValidateOutdatedContainers: ValidateOutdatedContainersModel = SettingsField(
default_factory=ValidateOutdatedContainersModel,
title="Validate Containers"
)
ValidateIntent: ValidateIntentModel = SettingsField(
default_factory=ValidateIntentModel,
title="Validate Intent"
@ -855,6 +886,25 @@ DEFAULT_PUBLISH_VALUES = {
"optional": False,
"active": True
},
"ValidateOutdatedContainers": {
"plugin_state_profiles": [
{
# Default host names are based on original
# filter of ValidateContainer pyblish plugin
"host_names": [
"maya",
"houdini",
"nuke",
"harmony",
"photoshop",
"aftereffects"
],
"enabled": True,
"optional": True,
"active": True
}
]
},
"ValidateIntent": {
"enabled": False,
"profiles": []

View file

@ -1,3 +1,3 @@
name = "aftereffects"
title = "AfterEffects"
version = "0.1.3"
version = "0.1.4"

View file

@ -22,12 +22,6 @@ class ValidateSceneSettingsModel(BaseSettingsModel):
)
class ValidateContainersModel(BaseSettingsModel):
enabled: bool = SettingsField(True, title="Enabled")
optional: bool = SettingsField(True, title="Optional")
active: bool = SettingsField(True, title="Active")
class AfterEffectsPublishPlugins(BaseSettingsModel):
CollectReview: CollectReviewPluginModel = SettingsField(
default_factory=CollectReviewPluginModel,
@ -37,10 +31,6 @@ class AfterEffectsPublishPlugins(BaseSettingsModel):
default_factory=ValidateSceneSettingsModel,
title="Validate Scene Settings",
)
ValidateContainers: ValidateContainersModel = SettingsField(
default_factory=ValidateContainersModel,
title="Validate Containers",
)
AE_PUBLISH_PLUGINS_DEFAULTS = {
@ -58,9 +48,4 @@ AE_PUBLISH_PLUGINS_DEFAULTS = {
".*"
]
},
"ValidateContainers": {
"enabled": True,
"optional": True,
"active": True,
}
}

View file

@ -1,3 +1,3 @@
name = "deadline"
title = "Deadline"
version = "0.1.11"
version = "0.1.12"

View file

@ -38,10 +38,9 @@ class ServerItemSubmodel(BaseSettingsModel):
name: str = SettingsField(title="Name")
value: str = SettingsField(title="Url")
require_authentication: bool = SettingsField(
False,
title="Require authentication")
ssl: bool = SettingsField(False,
title="SSL")
False, title="Require authentication")
not_verify_ssl: bool = SettingsField(
False, title="Don't verify SSL")
class DeadlineSettings(BaseSettingsModel):
@ -78,7 +77,7 @@ DEFAULT_VALUES = {
"name": "default",
"value": "http://127.0.0.1:8082",
"require_authentication": False,
"ssl": False
"not_verify_ssl": False
}
],
"deadline_server": "default",

View file

@ -1,3 +1,3 @@
name = "harmony"
title = "Harmony"
version = "0.1.2"
version = "0.1.3"

View file

@ -45,11 +45,6 @@ DEFAULT_HARMONY_SETTING = {
"optional": True,
"active": True
},
"ValidateContainers": {
"enabled": True,
"optional": True,
"active": True
},
"ValidateSceneSettings": {
"enabled": True,
"optional": True,

View file

@ -18,14 +18,6 @@ class ValidateAudioPlugin(BaseSettingsModel):
active: bool = SettingsField(True, title="Active")
class ValidateContainersPlugin(BaseSettingsModel):
"""Check if loaded container is scene are latest versions."""
_isGroup = True
enabled: bool = True
optional: bool = SettingsField(False, title="Optional")
active: bool = SettingsField(True, title="Active")
class ValidateSceneSettingsPlugin(BaseSettingsModel):
"""Validate if FrameStart, FrameEnd and Resolution match shot data in DB.
Use regular expressions to limit validations only on particular asset
@ -63,11 +55,6 @@ class HarmonyPublishPlugins(BaseSettingsModel):
default_factory=ValidateAudioPlugin,
)
ValidateContainers: ValidateContainersPlugin = SettingsField(
title="Validate Containers",
default_factory=ValidateContainersPlugin,
)
ValidateSceneSettings: ValidateSceneSettingsPlugin = SettingsField(
title="Validate Scene Settings",
default_factory=ValidateSceneSettingsPlugin,

View file

@ -1,3 +1,3 @@
name = "houdini"
title = "Houdini"
version = "0.2.14"
version = "0.2.15"

View file

@ -77,10 +77,6 @@ class PublishPluginsModel(BaseSettingsModel):
default_factory=CollectLocalRenderInstancesModel,
title="Collect Local Render Instances."
)
ValidateContainers: BasicValidateModel = SettingsField(
default_factory=BasicValidateModel,
title="Validate Latest Containers.",
section="Validators")
ValidateInstanceInContextHoudini: BasicValidateModel = SettingsField(
default_factory=BasicValidateModel,
title="Validate Instance is in same Context.")
@ -119,11 +115,6 @@ DEFAULT_HOUDINI_PUBLISH_SETTINGS = {
]
}
},
"ValidateContainers": {
"enabled": True,
"optional": True,
"active": True
},
"ValidateInstanceInContextHoudini": {
"enabled": True,
"optional": True,

View file

@ -1,3 +1,3 @@
name = "maya"
title = "Maya"
version = "0.1.19"
version = "0.1.20"

View file

@ -634,10 +634,6 @@ class PublishersModel(BaseSettingsModel):
title="Validate Instance In Context",
section="Validators"
)
ValidateContainers: BasicValidateModel = SettingsField(
default_factory=BasicValidateModel,
title="Validate Containers"
)
ValidateFrameRange: ValidateFrameRangeModel = SettingsField(
default_factory=ValidateFrameRangeModel,
title="Validate Frame Range"
@ -1059,11 +1055,6 @@ DEFAULT_PUBLISH_SETTINGS = {
"optional": True,
"active": True
},
"ValidateContainers": {
"enabled": True,
"optional": True,
"active": True
},
"ValidateFrameRange": {
"enabled": True,
"optional": True,

View file

@ -1,3 +1,3 @@
name = "nuke"
title = "Nuke"
version = "0.1.12"
version = "0.1.13"

View file

@ -231,10 +231,6 @@ class PublishPluginsModel(BaseSettingsModel):
default_factory=OptionalPluginModel,
section="Validators"
)
ValidateContainers: OptionalPluginModel = SettingsField(
title="Validate Containers",
default_factory=OptionalPluginModel
)
ValidateKnobs: ValidateKnobsModel = SettingsField(
title="Validate Knobs",
default_factory=ValidateKnobsModel
@ -300,11 +296,6 @@ DEFAULT_PUBLISH_PLUGIN_SETTINGS = {
"optional": True,
"active": True
},
"ValidateContainers": {
"enabled": True,
"optional": True,
"active": True
},
"ValidateKnobs": {
"enabled": False,
"knobs": "\n".join([

View file

@ -1,3 +1,3 @@
name = "photoshop"
title = "Photoshop"
version = "0.1.2"
version = "0.1.3"

View file

@ -83,14 +83,6 @@ class CollectVersionPlugin(BaseSettingsModel):
enabled: bool = SettingsField(True, title="Enabled")
class ValidateContainersPlugin(BaseSettingsModel):
"""Check that workfile contains latest version of loaded items""" # noqa
_isGroup = True
enabled: bool = True
optional: bool = SettingsField(False, title="Optional")
active: bool = SettingsField(True, title="Active")
class ValidateNamingPlugin(BaseSettingsModel):
"""Validate naming of products and layers""" # noqa
invalid_chars: str = SettingsField(
@ -154,11 +146,6 @@ class PhotoshopPublishPlugins(BaseSettingsModel):
default_factory=CollectVersionPlugin,
)
ValidateContainers: ValidateContainersPlugin = SettingsField(
title="Validate Containers",
default_factory=ValidateContainersPlugin,
)
ValidateNaming: ValidateNamingPlugin = SettingsField(
title="Validate naming of products and layers",
default_factory=ValidateNamingPlugin,
@ -187,11 +174,6 @@ DEFAULT_PUBLISH_SETTINGS = {
"CollectVersion": {
"enabled": False
},
"ValidateContainers": {
"enabled": True,
"optional": True,
"active": True
},
"ValidateNaming": {
"invalid_chars": "[ \\\\/+\\*\\?\\(\\)\\[\\]\\{\\}:,;]",
"replace_char": "_"