mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
[Automated] Merged develop into main
This commit is contained in:
commit
4268311ce6
33 changed files with 222 additions and 114 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -35,6 +35,7 @@ body:
|
|||
label: Version
|
||||
description: What version are you running? Look to OpenPype Tray
|
||||
options:
|
||||
- 3.17.7-nightly.7
|
||||
- 3.17.7-nightly.6
|
||||
- 3.17.7-nightly.5
|
||||
- 3.17.7-nightly.4
|
||||
|
|
@ -134,7 +135,6 @@ body:
|
|||
- 3.15.3-nightly.3
|
||||
- 3.15.3-nightly.2
|
||||
- 3.15.3-nightly.1
|
||||
- 3.15.2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ def convert_v4_version_to_v3(version):
|
|||
output_data[dst_key] = version[src_key]
|
||||
|
||||
if "createdAt" in version:
|
||||
created_at = arrow.get(version["createdAt"])
|
||||
created_at = arrow.get(version["createdAt"]).to("local")
|
||||
output_data["time"] = created_at.strftime("%Y%m%dT%H%M%SZ")
|
||||
|
||||
output["data"] = output_data
|
||||
|
|
|
|||
|
|
@ -60,8 +60,9 @@ class ExtractLocalRender(publish.Extractor):
|
|||
first_repre = not representations
|
||||
if instance.data["review"] and first_repre:
|
||||
repre_data["tags"] = ["review"]
|
||||
thumbnail_path = os.path.join(staging_dir, files[0])
|
||||
instance.data["thumbnailSource"] = thumbnail_path
|
||||
# TODO return back when Extract from source same as regular
|
||||
# thumbnail_path = os.path.join(staging_dir, files[0])
|
||||
# instance.data["thumbnailSource"] = thumbnail_path
|
||||
|
||||
representations.append(repre_data)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,18 +14,13 @@ class CollectChunkSize(pyblish.api.InstancePlugin,
|
|||
hosts = ["houdini"]
|
||||
targets = ["local", "remote"]
|
||||
label = "Collect Chunk Size"
|
||||
chunkSize = 999999
|
||||
chunk_size = 999999
|
||||
|
||||
def process(self, instance):
|
||||
# need to get the chunk size info from the setting
|
||||
attr_values = self.get_attr_values_from_data(instance.data)
|
||||
instance.data["chunkSize"] = attr_values.get("chunkSize")
|
||||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
project_setting = project_settings["houdini"]["publish"]["CollectChunkSize"] # noqa
|
||||
cls.chunkSize = project_setting["chunk_size"]
|
||||
|
||||
@classmethod
|
||||
def get_attribute_defs(cls):
|
||||
return [
|
||||
|
|
@ -33,7 +28,6 @@ class CollectChunkSize(pyblish.api.InstancePlugin,
|
|||
minimum=1,
|
||||
maximum=999999,
|
||||
decimals=0,
|
||||
default=cls.chunkSize,
|
||||
default=cls.chunk_size,
|
||||
label="Frame Per Task")
|
||||
|
||||
]
|
||||
|
|
|
|||
|
|
@ -198,8 +198,8 @@ def _render_preview_animation_max_pre_2024(
|
|||
res_width, res_height, filename=filepath
|
||||
)
|
||||
dib = rt.gw.getViewportDib()
|
||||
dib_width = rt.renderWidth
|
||||
dib_height = rt.renderHeight
|
||||
dib_width = float(dib.width)
|
||||
dib_height = float(dib.height)
|
||||
# aspect ratio
|
||||
viewportRatio = dib_width / dib_height
|
||||
renderRatio = float(res_width / res_height)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import pyblish.api
|
||||
from pymxs import runtime as rt
|
||||
from openpype.pipeline import (
|
||||
PublishValidationError,
|
||||
OptionalPyblishPluginMixin
|
||||
)
|
||||
from pymxs import runtime as rt
|
||||
from openpype.pipeline.publish import (
|
||||
RepairAction,
|
||||
PublishValidationError
|
||||
)
|
||||
from openpype.hosts.max.api.lib import reset_scene_resolution
|
||||
|
||||
|
||||
|
|
@ -16,6 +19,7 @@ class ValidateResolutionSetting(pyblish.api.InstancePlugin,
|
|||
hosts = ["max"]
|
||||
label = "Validate Resolution Setting"
|
||||
optional = True
|
||||
actions = [RepairAction]
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
|
|
|
|||
|
|
@ -257,8 +257,6 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
if 'shot' not in instance.data.get('family', ''):
|
||||
continue
|
||||
|
||||
name = instance.data["asset"]
|
||||
|
||||
# get handles
|
||||
handle_start = int(instance.data["handleStart"])
|
||||
handle_end = int(instance.data["handleEnd"])
|
||||
|
|
@ -286,6 +284,8 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
parents = instance.data.get('parents', [])
|
||||
self.log.debug(f"parents: {pformat(parents)}")
|
||||
|
||||
# Split by '/' for AYON where asset is a path
|
||||
name = instance.data["asset"].split("/")[-1]
|
||||
actual = {name: in_info}
|
||||
|
||||
for parent in reversed(parents):
|
||||
|
|
|
|||
|
|
@ -583,18 +583,9 @@ def prompt_new_file_with_mesh(mesh_filepath):
|
|||
file_dialog.setDirectory(os.path.dirname(mesh_filepath))
|
||||
url = QtCore.QUrl.fromLocalFile(os.path.basename(mesh_filepath))
|
||||
file_dialog.selectUrl(url)
|
||||
|
||||
# Give the explorer window time to refresh to the folder and select
|
||||
# the file
|
||||
while not file_dialog.selectedFiles():
|
||||
app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 1000)
|
||||
print(f"Selected: {file_dialog.selectedFiles()}")
|
||||
|
||||
# Set it again now we know the path is refreshed - without this
|
||||
# accepting the dialog will often not trigger the correct filepath
|
||||
file_dialog.setDirectory(os.path.dirname(mesh_filepath))
|
||||
url = QtCore.QUrl.fromLocalFile(os.path.basename(mesh_filepath))
|
||||
file_dialog.selectUrl(url)
|
||||
# TODO: find a way to improve the process event to
|
||||
# load more complicated mesh
|
||||
app.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents, 3000)
|
||||
|
||||
file_dialog.done(file_dialog.Accepted)
|
||||
app.processEvents(QtCore.QEventLoop.AllEvents)
|
||||
|
|
@ -628,7 +619,12 @@ def prompt_new_file_with_mesh(mesh_filepath):
|
|||
mesh_filename_label = mesh_filename.findChild(QtWidgets.QLabel)
|
||||
if not mesh_filename_label.text():
|
||||
dialog.close()
|
||||
raise RuntimeError(f"Failed to set mesh path: {mesh_filepath}")
|
||||
substance_painter.logging.warning(
|
||||
"Failed to set mesh path with the prompt dialog:"
|
||||
f"{mesh_filepath}\n\n"
|
||||
"Creating new project directly with the mesh path instead.")
|
||||
else:
|
||||
dialog.done(dialog.Accepted)
|
||||
|
||||
new_action = _get_new_project_action()
|
||||
if not new_action:
|
||||
|
|
|
|||
|
|
@ -44,14 +44,22 @@ class SubstanceLoadProjectMesh(load.LoaderPlugin):
|
|||
# Get user inputs
|
||||
import_cameras = data.get("import_cameras", True)
|
||||
preserve_strokes = data.get("preserve_strokes", True)
|
||||
|
||||
sp_settings = substance_painter.project.Settings(
|
||||
import_cameras=import_cameras
|
||||
)
|
||||
if not substance_painter.project.is_open():
|
||||
# Allow to 'initialize' a new project
|
||||
path = self.filepath_from_context(context)
|
||||
# TODO: improve the prompt dialog function to not
|
||||
# only works for simple polygon scene
|
||||
result = prompt_new_file_with_mesh(mesh_filepath=path)
|
||||
if not result:
|
||||
self.log.info("User cancelled new project prompt.")
|
||||
return
|
||||
self.log.info("User cancelled new project prompt."
|
||||
"Creating new project directly from"
|
||||
" Substance Painter API Instead.")
|
||||
settings = substance_painter.project.create(
|
||||
mesh_file_path=path, settings=sp_settings
|
||||
)
|
||||
|
||||
else:
|
||||
# Reload the mesh
|
||||
|
|
|
|||
|
|
@ -155,8 +155,6 @@ class CollectShotInstance(pyblish.api.InstancePlugin):
|
|||
else {}
|
||||
)
|
||||
|
||||
asset_name = instance.data["asset"]
|
||||
|
||||
# get handles
|
||||
handle_start = int(instance.data["handleStart"])
|
||||
handle_end = int(instance.data["handleEnd"])
|
||||
|
|
@ -177,6 +175,8 @@ class CollectShotInstance(pyblish.api.InstancePlugin):
|
|||
|
||||
parents = instance.data.get('parents', [])
|
||||
|
||||
# Split by '/' for AYON where asset is a path
|
||||
asset_name = instance.data["asset"].split("/")[-1]
|
||||
actual = {asset_name: in_info}
|
||||
|
||||
for parent in reversed(parents):
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ def is_running_staging():
|
|||
latest_version = get_latest_version(local=False, remote=True)
|
||||
staging_version = latest_version
|
||||
|
||||
if current_version == production_version:
|
||||
if current_version == staging_version:
|
||||
return True
|
||||
|
||||
return is_staging_enabled()
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ class CollectHierarchy(pyblish.api.ContextPlugin):
|
|||
"resolutionHeight": instance.data["resolutionHeight"],
|
||||
"pixelAspect": instance.data["pixelAspect"]
|
||||
}
|
||||
|
||||
actual = {instance.data["asset"]: shot_data}
|
||||
# Split by '/' for AYON where asset is a path
|
||||
name = instance.data["asset"].split("/")[-1]
|
||||
actual = {name: shot_data}
|
||||
|
||||
for parent in reversed(instance.data["parents"]):
|
||||
next_dict = {}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ class CollectResourcesPath(pyblish.api.InstancePlugin):
|
|||
]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
anatomy = instance.context.data["anatomy"]
|
||||
|
||||
template_data = copy.deepcopy(instance.data["anatomyData"])
|
||||
|
|
@ -80,11 +79,18 @@ class CollectResourcesPath(pyblish.api.InstancePlugin):
|
|||
"representation": "TEMP"
|
||||
})
|
||||
|
||||
# For the first time publish
|
||||
if instance.data.get("hierarchy"):
|
||||
template_data.update({
|
||||
"hierarchy": instance.data["hierarchy"]
|
||||
})
|
||||
# Add fill keys for editorial publishing creating new entity
|
||||
# TODO handle in editorial plugin
|
||||
if instance.data.get("newAssetPublishing"):
|
||||
if "hierarchy" not in instance.data:
|
||||
template_data["hierarchy"] = instance.data["hierarchy"]
|
||||
|
||||
if "asset" not in template_data:
|
||||
asset_name = instance.data["asset"].split("/")[-1]
|
||||
template_data["asset"] = asset_name
|
||||
template_data["folder"] = {
|
||||
"name": asset_name
|
||||
}
|
||||
|
||||
publish_templates = anatomy.templates_obj["publish"]
|
||||
if "folder" in publish_templates:
|
||||
|
|
|
|||
|
|
@ -223,23 +223,24 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin):
|
|||
valid_ids = set()
|
||||
|
||||
hierarchy_queue = collections.deque()
|
||||
hierarchy_queue.append((project_id, project_children_context))
|
||||
hierarchy_queue.append((project_id, "", project_children_context))
|
||||
while hierarchy_queue:
|
||||
queue_item = hierarchy_queue.popleft()
|
||||
parent_id, children_context = queue_item
|
||||
parent_id, parent_path, children_context = queue_item
|
||||
if not children_context:
|
||||
continue
|
||||
|
||||
for asset, asset_info in children_context.items():
|
||||
for folder_name, folder_info in children_context.items():
|
||||
folder_path = "{}/{}".format(parent_path, folder_name)
|
||||
if (
|
||||
asset not in active_folder_paths
|
||||
and not asset_info.get("childs")
|
||||
folder_path not in active_folder_paths
|
||||
and not folder_info.get("childs")
|
||||
):
|
||||
continue
|
||||
asset_name = asset.split("/")[-1]
|
||||
|
||||
item_id = uuid.uuid4().hex
|
||||
new_item = copy.deepcopy(asset_info)
|
||||
new_item["name"] = asset_name
|
||||
new_item = copy.deepcopy(folder_info)
|
||||
new_item["name"] = folder_name
|
||||
new_item["children"] = []
|
||||
new_children_context = new_item.pop("childs", None)
|
||||
tasks = new_item.pop("tasks", {})
|
||||
|
|
@ -253,9 +254,11 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin):
|
|||
items_by_id[item_id] = new_item
|
||||
parent_id_by_item_id[item_id] = parent_id
|
||||
|
||||
if asset in active_folder_paths:
|
||||
if folder_path in active_folder_paths:
|
||||
valid_ids.add(item_id)
|
||||
hierarchy_queue.append((item_id, new_children_context))
|
||||
hierarchy_queue.append(
|
||||
(item_id, folder_path, new_children_context)
|
||||
)
|
||||
|
||||
if not valid_ids:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import os
|
||||
from openpype import AYON_SERVER_ENABLED
|
||||
from openpype.lib.openpype_version import is_running_staging
|
||||
from openpype.lib.openpype_version import is_staging_enabled
|
||||
|
||||
RESOURCES_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ def get_openpype_icon_filepath(staging=None):
|
|||
return get_resource("icons", "AYON_icon_dev.png")
|
||||
|
||||
if staging is None:
|
||||
staging = is_running_staging()
|
||||
staging = is_staging_enabled()
|
||||
|
||||
if staging:
|
||||
return get_openpype_staging_icon_filepath()
|
||||
|
|
@ -68,7 +68,7 @@ def get_openpype_icon_filepath(staging=None):
|
|||
|
||||
def get_openpype_splash_filepath(staging=None):
|
||||
if staging is None:
|
||||
staging = is_running_staging()
|
||||
staging = is_staging_enabled()
|
||||
|
||||
if AYON_SERVER_ENABLED:
|
||||
if os.getenv("AYON_USE_DEV") == "1":
|
||||
|
|
|
|||
|
|
@ -62,6 +62,12 @@
|
|||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateMantraIFD": {
|
||||
"enabled": true,
|
||||
"default_variants": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateMantraROP": {
|
||||
"enabled": true,
|
||||
"default_variants": [
|
||||
|
|
@ -137,14 +143,14 @@
|
|||
}
|
||||
},
|
||||
"publish": {
|
||||
"CollectAssetHandles": {
|
||||
"use_asset_handles": true
|
||||
},
|
||||
"CollectChunkSize": {
|
||||
"enabled": true,
|
||||
"optional": true,
|
||||
"chunk_size": 999999
|
||||
},
|
||||
"CollectAssetHandles": {
|
||||
"use_asset_handles": true
|
||||
},
|
||||
"ValidateContainers": {
|
||||
"enabled": true,
|
||||
"optional": true,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@
|
|||
"key": "CreateKarmaROP",
|
||||
"label": "Create Karma ROP"
|
||||
},
|
||||
{
|
||||
"key": "CreateMantraIFD",
|
||||
"label": "Create Mantra IFD"
|
||||
},
|
||||
{
|
||||
"key": "CreateMantraROP",
|
||||
"label": "Create Mantra ROP"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,31 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"key": "CollectChunkSize",
|
||||
"label": "Collect Chunk Size",
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "optional",
|
||||
"label": "Optional"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"key": "chunk_size",
|
||||
"label": "Frames Per Task"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Validators"
|
||||
|
|
@ -55,31 +80,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"key": "CollectChunkSize",
|
||||
"label": "Collect Chunk Size",
|
||||
"is_group": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "optional",
|
||||
"label": "Optional"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"key": "chunk_size",
|
||||
"label": "Frames Per Task"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
|
|
|
|||
|
|
@ -512,52 +512,58 @@ QAbstractItemView::item:selected:hover {
|
|||
}
|
||||
|
||||
/* Row colors (alternate colors) are from left - right */
|
||||
QAbstractItemView:branch {
|
||||
background: transparent;
|
||||
QTreeView::branch {
|
||||
background: {color:bg-view};
|
||||
}
|
||||
QTreeView::branch:hover {
|
||||
background: {color:bg-view};
|
||||
}
|
||||
QTreeView::branch:selected {
|
||||
background: {color:bg-view};
|
||||
}
|
||||
|
||||
QAbstractItemView::branch:open:has-children:!has-siblings,
|
||||
QAbstractItemView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/branch_open.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
QAbstractItemView::branch:open:has-children:!has-siblings:hover,
|
||||
QAbstractItemView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/branch_open_on.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
|
||||
QAbstractItemView::branch:has-children:!has-siblings:closed,
|
||||
QAbstractItemView::branch:closed:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/branch_closed.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
QAbstractItemView::branch:has-children:!has-siblings:closed:hover,
|
||||
QAbstractItemView::branch:closed:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/branch_closed_on.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
|
||||
QAbstractItemView::branch:has-siblings:!adjoins-item {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/transparent.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
|
||||
QAbstractItemView::branch:has-siblings:adjoins-item {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/transparent.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
|
||||
QAbstractItemView::branch:!has-children:!has-siblings:adjoins-item {
|
||||
border-image: none;
|
||||
image: url(:/openpype/images/transparent.png);
|
||||
background: transparent;
|
||||
background: {color:bg-view};
|
||||
}
|
||||
|
||||
CompleterView {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ def version_item_from_entity(version):
|
|||
# NOTE There is also 'updatedAt', should be used that instead?
|
||||
# TODO skip conversion - converting to '%Y%m%dT%H%M%SZ' is because
|
||||
# 'PrettyTimeDelegate' expects it
|
||||
created_at = arrow.get(version["createdAt"])
|
||||
created_at = arrow.get(version["createdAt"]).to("local")
|
||||
published_time = created_at.strftime("%Y%m%dT%H%M%SZ")
|
||||
author = version["author"]
|
||||
version_num = version["version"]
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ class PublishWorkfilesModel:
|
|||
print("Failed to format workfile path: {}".format(exc))
|
||||
|
||||
dirpath, filename = os.path.split(workfile_path)
|
||||
created_at = arrow.get(repre_entity["createdAt"])
|
||||
created_at = arrow.get(repre_entity["createdAt"].to("local"))
|
||||
return FileItem(
|
||||
dirpath,
|
||||
filename,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ class CreatePluginsModel(BaseSettingsModel):
|
|||
CreateKarmaROP: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Karma ROP")
|
||||
CreateMantraIFD: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Mantra IFD")
|
||||
CreateMantraROP: CreatorModel = Field(
|
||||
default_factory=CreatorModel,
|
||||
title="Create Mantra ROP")
|
||||
|
|
@ -114,6 +117,10 @@ DEFAULT_HOUDINI_CREATE_SETTINGS = {
|
|||
"enabled": True,
|
||||
"default_variants": ["Main"]
|
||||
},
|
||||
"CreateMantraIFD": {
|
||||
"enabled": True,
|
||||
"default_variants": ["Main"]
|
||||
},
|
||||
"CreateMantraROP": {
|
||||
"enabled": True,
|
||||
"default_variants": ["Main"]
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@ class CollectAssetHandlesModel(BaseSettingsModel):
|
|||
title="Use asset handles")
|
||||
|
||||
|
||||
class CollectChunkSizeModel(BaseSettingsModel):
|
||||
"""Collect Chunk Size."""
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
chunk_size: int = Field(
|
||||
title="Frames Per Task")
|
||||
|
||||
|
||||
class ValidateWorkfilePathsModel(BaseSettingsModel):
|
||||
enabled: bool = Field(title="Enabled")
|
||||
optional: bool = Field(title="Optional")
|
||||
|
|
@ -38,6 +46,10 @@ class PublishPluginsModel(BaseSettingsModel):
|
|||
title="Collect Asset Handles.",
|
||||
section="Collectors"
|
||||
)
|
||||
CollectChunkSize: CollectChunkSizeModel = Field(
|
||||
default_factory=CollectChunkSizeModel,
|
||||
title="Collect Chunk Size."
|
||||
)
|
||||
ValidateContainers: BasicValidateModel = Field(
|
||||
default_factory=BasicValidateModel,
|
||||
title="Validate Latest Containers.",
|
||||
|
|
@ -63,6 +75,11 @@ DEFAULT_HOUDINI_PUBLISH_SETTINGS = {
|
|||
"CollectAssetHandles": {
|
||||
"use_asset_handles": True
|
||||
},
|
||||
"CollectChunkSize": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"chunk_size": 999999
|
||||
},
|
||||
"ValidateContainers": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "0.2.9"
|
||||
__version__ = "0.2.10"
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class TestDeadlinePublishInAfterEffects(AEDeadlinePublishTestClass):
|
|||
name="renderTest_taskMain"))
|
||||
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 4))
|
||||
DBAssert.count_of_types(dbcon, "representation", 3))
|
||||
|
||||
additional_args = {"context.subset": "workfileTest_task",
|
||||
"context.ext": "aep"}
|
||||
|
|
@ -77,7 +77,7 @@ class TestDeadlinePublishInAfterEffects(AEDeadlinePublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class TestDeadlinePublishInAfterEffectsMultiComposition(AEDeadlinePublishTestCla
|
|||
name="renderTest_taskMain2"))
|
||||
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 5))
|
||||
DBAssert.count_of_types(dbcon, "representation", 4))
|
||||
|
||||
additional_args = {"context.subset": "workfileTest_task",
|
||||
"context.ext": "aep"}
|
||||
|
|
@ -89,7 +89,7 @@ class TestDeadlinePublishInAfterEffectsMultiComposition(AEDeadlinePublishTestCla
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
name="renderTest_taskMain"))
|
||||
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 4))
|
||||
DBAssert.count_of_types(dbcon, "representation", 3))
|
||||
|
||||
additional_args = {"context.subset": "workfileTest_task",
|
||||
"context.ext": "aep"}
|
||||
|
|
@ -75,7 +75,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
name="renderTest_taskMain"))
|
||||
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 4))
|
||||
DBAssert.count_of_types(dbcon, "representation", 2))
|
||||
|
||||
additional_args = {"context.subset": "workfileTest_task",
|
||||
"context.ext": "aep"}
|
||||
|
|
@ -77,7 +77,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
@ -89,7 +89,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
name="renderTest_taskMain"))
|
||||
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 4))
|
||||
DBAssert.count_of_types(dbcon, "representation", 3))
|
||||
|
||||
additional_args = {"context.subset": "workfileTest_task",
|
||||
"context.ext": "aep"}
|
||||
|
|
@ -62,7 +62,7 @@ class TestPublishInAfterEffects(AELocalPublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class TestDeadlinePublishInMaya(MayaDeadlinePublishTestClass):
|
|||
DBAssert.count_of_types(dbcon, "subset", 1,
|
||||
name="workfileTest_task"))
|
||||
|
||||
failures.append(DBAssert.count_of_types(dbcon, "representation", 8))
|
||||
failures.append(DBAssert.count_of_types(dbcon, "representation", 7))
|
||||
|
||||
# hero included
|
||||
additional_args = {"context.subset": "modelMain",
|
||||
|
|
@ -85,7 +85,7 @@ class TestDeadlinePublishInMaya(MayaDeadlinePublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain_beauty",
|
||||
"context.ext": "jpg"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain_beauty",
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 75 KiB |
|
|
@ -69,7 +69,7 @@ class TestDeadlinePublishInNuke(NukeDeadlinePublishTestClass):
|
|||
name="workfileTest_task"))
|
||||
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 4))
|
||||
DBAssert.count_of_types(dbcon, "representation", 3))
|
||||
|
||||
additional_args = {"context.subset": "workfileTest_task",
|
||||
"context.ext": "nk"}
|
||||
|
|
@ -86,7 +86,7 @@ class TestDeadlinePublishInNuke(NukeDeadlinePublishTestClass):
|
|||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
"name": "thumbnail"}
|
||||
failures.append(
|
||||
DBAssert.count_of_types(dbcon, "representation", 1,
|
||||
DBAssert.count_of_types(dbcon, "representation", 0,
|
||||
additional_args=additional_args))
|
||||
|
||||
additional_args = {"context.subset": "renderTest_taskMain",
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ class DeadlinePublishTest(PublishTest):
|
|||
while not valid_date_finished:
|
||||
time.sleep(0.5)
|
||||
if time.time() - time_start > timeout:
|
||||
raise ValueError("Timeout for DL finish reached")
|
||||
raise ValueError("Timeout for Deadline finish reached")
|
||||
|
||||
response = requests.get(url, timeout=10)
|
||||
if not response.ok:
|
||||
|
|
@ -491,6 +491,61 @@ class DeadlinePublishTest(PublishTest):
|
|||
if not response.json():
|
||||
raise ValueError("Couldn't find {}".format(deadline_job_id))
|
||||
|
||||
job = response.json()[0]
|
||||
|
||||
def recursive_dependencies(job, results=None):
|
||||
if results is None:
|
||||
results = []
|
||||
|
||||
for dependency in job["Props"]["Dep"]:
|
||||
dependency = requests.get(
|
||||
"{}/api/jobs?JobId={}".format(
|
||||
deadline_url, dependency["JobID"]
|
||||
),
|
||||
timeout=10
|
||||
).json()[0]
|
||||
results.append(dependency)
|
||||
grand_dependencies = recursive_dependencies(
|
||||
dependency, results=results
|
||||
)
|
||||
for grand_dependency in grand_dependencies:
|
||||
if grand_dependency not in results:
|
||||
results.append(grand_dependency)
|
||||
return results
|
||||
|
||||
job_status = {
|
||||
0: "Unknown",
|
||||
1: "Active",
|
||||
2: "Suspended",
|
||||
3: "Completed",
|
||||
4: "Failed",
|
||||
6: "Pending"
|
||||
}
|
||||
|
||||
jobs_to_validate = [job]
|
||||
jobs_to_validate.extend(recursive_dependencies(job))
|
||||
failed_jobs = []
|
||||
errors = []
|
||||
for job in jobs_to_validate:
|
||||
if "Failed" == job_status[job["Stat"]]:
|
||||
failed_jobs.append(str(job))
|
||||
|
||||
resp_error = requests.get(
|
||||
"{}/api/jobreports?JobID={}&Data=allerrorcontents".format(
|
||||
deadline_url, job["_id"]
|
||||
),
|
||||
timeout=10
|
||||
)
|
||||
errors.extend(resp_error.json())
|
||||
|
||||
msg = "Errors in Deadline:\n"
|
||||
msg += "\n".join(errors)
|
||||
assert not errors, msg
|
||||
|
||||
msg = "Failed in Deadline:\n"
|
||||
msg += "\n".join(failed_jobs)
|
||||
assert not failed_jobs, msg
|
||||
|
||||
# '0001-...' returned until job is finished
|
||||
valid_date_finished = response.json()[0]["DateComp"][:4] != "0001"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue