mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into enhancement/workfile_template_builder_allow_published_entities
This commit is contained in:
commit
0067b417e7
17 changed files with 769 additions and 40 deletions
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -35,6 +35,7 @@ body:
|
|||
label: Version
|
||||
description: What version are you running? Look to AYON Tray
|
||||
options:
|
||||
- 1.3.2
|
||||
- 1.3.1
|
||||
- 1.3.0
|
||||
- 1.2.0
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@ class OCIOEnvHook(PreLaunchHook):
|
|||
def execute(self):
|
||||
"""Hook entry method."""
|
||||
|
||||
task_entity = self.data.get("task_entity")
|
||||
|
||||
if not task_entity:
|
||||
self.log.info(
|
||||
"Skipping OCIO Environment preparation."
|
||||
"Task Entity is not available."
|
||||
)
|
||||
return
|
||||
|
||||
folder_entity = self.data["folder_entity"]
|
||||
|
||||
template_data = get_template_data(
|
||||
|
|
|
|||
|
|
@ -462,8 +462,8 @@ class Anatomy(BaseAnatomy):
|
|||
Union[Dict[str, str], None]): Local root overrides.
|
||||
"""
|
||||
if not project_name:
|
||||
return
|
||||
return ayon_api.get_project_roots_for_site(
|
||||
return None
|
||||
return ayon_api.get_project_root_overrides_by_site_id(
|
||||
project_name, get_local_site_id()
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Cleanup leftover files from publish."""
|
||||
import os
|
||||
import shutil
|
||||
import pyblish.api
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import pyblish.api
|
||||
|
||||
from ayon_core.lib import is_in_tests
|
||||
from ayon_core.pipeline import PublishError
|
||||
|
||||
|
||||
class CleanUp(pyblish.api.InstancePlugin):
|
||||
|
|
@ -48,17 +51,15 @@ class CleanUp(pyblish.api.InstancePlugin):
|
|||
if is_in_tests():
|
||||
# let automatic test process clean up temporary data
|
||||
return
|
||||
# Get the errored instances
|
||||
failed = []
|
||||
|
||||
# If instance has errors, do not clean up
|
||||
for result in instance.context.data["results"]:
|
||||
if (result["error"] is not None and result["instance"] is not None
|
||||
and result["instance"] not in failed):
|
||||
failed.append(result["instance"])
|
||||
assert instance not in failed, (
|
||||
"Result of '{}' instance were not success".format(
|
||||
instance.data["name"]
|
||||
)
|
||||
)
|
||||
if result["error"] is not None and result["instance"] is instance:
|
||||
raise PublishError(
|
||||
"Result of '{}' instance were not success".format(
|
||||
instance.data["name"]
|
||||
)
|
||||
)
|
||||
|
||||
_skip_cleanup_filepaths = instance.context.data.get(
|
||||
"skipCleanupFilepaths"
|
||||
|
|
@ -71,10 +72,17 @@ class CleanUp(pyblish.api.InstancePlugin):
|
|||
self.log.debug("Cleaning renders new...")
|
||||
self.clean_renders(instance, skip_cleanup_filepaths)
|
||||
|
||||
if [ef for ef in self.exclude_families
|
||||
if instance.data["productType"] in ef]:
|
||||
# TODO: Figure out whether this could be refactored to just a
|
||||
# product_type in self.exclude_families check.
|
||||
product_type = instance.data["productType"]
|
||||
if any(
|
||||
product_type in exclude_family
|
||||
for exclude_family in self.exclude_families
|
||||
):
|
||||
self.log.debug(
|
||||
"Skipping cleanup for instance because product "
|
||||
f"type is excluded from cleanup: {product_type}")
|
||||
return
|
||||
import tempfile
|
||||
|
||||
temp_root = tempfile.gettempdir()
|
||||
staging_dir = instance.data.get("stagingDir", None)
|
||||
|
|
|
|||
|
|
@ -32,16 +32,16 @@ class CollectManagedStagingDir(pyblish.api.InstancePlugin):
|
|||
label = "Collect Managed Staging Directory"
|
||||
order = pyblish.api.CollectorOrder + 0.4990
|
||||
|
||||
def process(self, instance):
|
||||
def process(self, instance: pyblish.api.Instance):
|
||||
""" Collect the staging data and stores it to the instance.
|
||||
|
||||
Args:
|
||||
instance (object): The instance to inspect.
|
||||
"""
|
||||
staging_dir_path = get_instance_staging_dir(instance)
|
||||
persistance = instance.data.get("stagingDir_persistent", False)
|
||||
persistence: bool = instance.data.get("stagingDir_persistent", False)
|
||||
|
||||
self.log.info((
|
||||
self.log.debug(
|
||||
f"Instance staging dir was set to `{staging_dir_path}` "
|
||||
f"and persistence is set to `{persistance}`"
|
||||
))
|
||||
f"and persistence is set to `{persistence}`"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, asdict
|
||||
from typing import (
|
||||
Optional,
|
||||
Dict,
|
||||
|
|
@ -28,6 +29,19 @@ if TYPE_CHECKING:
|
|||
from .models import CreatorItem, PublishErrorInfo, InstanceItem
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommentDef:
|
||||
"""Comment attribute definition."""
|
||||
minimum_chars_required: int
|
||||
|
||||
def to_data(self):
|
||||
return asdict(self)
|
||||
|
||||
@classmethod
|
||||
def from_data(cls, data):
|
||||
return cls(**data)
|
||||
|
||||
|
||||
class CardMessageTypes:
|
||||
standard = None
|
||||
info = "info"
|
||||
|
|
@ -135,6 +149,17 @@ class AbstractPublisherCommon(ABC):
|
|||
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_comment_def(self) -> CommentDef:
|
||||
"""Get comment attribute definition.
|
||||
|
||||
This can define how the Comment field should behave, like having
|
||||
a minimum amount of required characters before being allowed to
|
||||
publish.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class AbstractPublisherBackend(AbstractPublisherCommon):
|
||||
@abstractmethod
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ from .models import (
|
|||
from .abstract import (
|
||||
AbstractPublisherBackend,
|
||||
AbstractPublisherFrontend,
|
||||
CardMessageTypes
|
||||
CardMessageTypes,
|
||||
CommentDef,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -601,3 +602,17 @@ class PublisherController(
|
|||
def _start_publish(self, up_validation):
|
||||
self._publish_model.set_publish_up_validation(up_validation)
|
||||
self._publish_model.start_publish(wait=True)
|
||||
|
||||
def get_comment_def(self) -> CommentDef:
|
||||
# Take the cached settings from the Create Context
|
||||
settings = self.get_create_context().get_current_project_settings()
|
||||
comment_minimum_required_chars: int = (
|
||||
settings
|
||||
.get("core", {})
|
||||
.get("tools", {})
|
||||
.get("publish", {})
|
||||
.get("comment_minimum_required_chars", 0)
|
||||
)
|
||||
return CommentDef(
|
||||
minimum_chars_required=comment_minimum_required_chars
|
||||
)
|
||||
|
|
|
|||
|
|
@ -245,6 +245,13 @@ class PublisherWindow(QtWidgets.QDialog):
|
|||
show_timer.setInterval(1)
|
||||
show_timer.timeout.connect(self._on_show_timer)
|
||||
|
||||
comment_invalid_timer = QtCore.QTimer()
|
||||
comment_invalid_timer.setSingleShot(True)
|
||||
comment_invalid_timer.setInterval(2500)
|
||||
comment_invalid_timer.timeout.connect(
|
||||
self._on_comment_invalid_timeout
|
||||
)
|
||||
|
||||
errors_dialog_message_timer = QtCore.QTimer()
|
||||
errors_dialog_message_timer.setInterval(100)
|
||||
errors_dialog_message_timer.timeout.connect(
|
||||
|
|
@ -395,6 +402,7 @@ class PublisherWindow(QtWidgets.QDialog):
|
|||
self._app_event_listener_installed = False
|
||||
|
||||
self._show_timer = show_timer
|
||||
self._comment_invalid_timer = comment_invalid_timer
|
||||
self._show_counter = 0
|
||||
self._window_is_visible = False
|
||||
|
||||
|
|
@ -823,15 +831,45 @@ class PublisherWindow(QtWidgets.QDialog):
|
|||
self._controller.set_comment(self._comment_input.text())
|
||||
|
||||
def _on_validate_clicked(self):
|
||||
if self._save_changes(False):
|
||||
if self._validate_comment() and self._save_changes(False):
|
||||
self._set_publish_comment()
|
||||
self._controller.validate()
|
||||
|
||||
def _on_publish_clicked(self):
|
||||
if self._save_changes(False):
|
||||
if self._validate_comment() and self._save_changes(False):
|
||||
self._set_publish_comment()
|
||||
self._controller.publish()
|
||||
|
||||
def _validate_comment(self) -> bool:
|
||||
# Validate comment length
|
||||
comment_def = self._controller.get_comment_def()
|
||||
char_count = len(self._comment_input.text().strip())
|
||||
if (
|
||||
comment_def.minimum_chars_required
|
||||
and char_count < comment_def.minimum_chars_required
|
||||
):
|
||||
self._overlay_object.add_message(
|
||||
"Please enter a comment of at least "
|
||||
f"{comment_def.minimum_chars_required} characters",
|
||||
message_type="error"
|
||||
)
|
||||
self._invalidate_comment_field()
|
||||
return False
|
||||
return True
|
||||
|
||||
def _invalidate_comment_field(self):
|
||||
self._comment_invalid_timer.start()
|
||||
self._comment_input.setStyleSheet("border-color: #DD2020")
|
||||
# Set focus so user can start typing and is pointed towards the field
|
||||
self._comment_input.setFocus()
|
||||
self._comment_input.setCursorPosition(
|
||||
len(self._comment_input.text())
|
||||
)
|
||||
|
||||
def _on_comment_invalid_timeout(self):
|
||||
# Reset style
|
||||
self._comment_input.setStyleSheet("")
|
||||
|
||||
def _set_footer_enabled(self, enabled):
|
||||
self._save_btn.setEnabled(True)
|
||||
self._reset_btn.setEnabled(True)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
BIN
client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined-Regular.ttf
vendored
Normal file
BIN
client/ayon_core/vendor/python/qtmaterialsymbols/resources/MaterialSymbolsOutlined-Regular.ttf
vendored
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -5,12 +5,32 @@ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||
|
||||
|
||||
def get_font_filepath(
|
||||
font_name: Optional[str] = "MaterialSymbolsOutlined"
|
||||
font_name: Optional[str] = "MaterialSymbolsOutlined-Regular"
|
||||
) -> str:
|
||||
return os.path.join(CURRENT_DIR, f"{font_name}.ttf")
|
||||
|
||||
|
||||
def get_mapping_filepath(
|
||||
font_name: Optional[str] = "MaterialSymbolsOutlined"
|
||||
font_name: Optional[str] = "MaterialSymbolsOutlined-Regular"
|
||||
) -> str:
|
||||
return os.path.join(CURRENT_DIR, f"{font_name}.json")
|
||||
|
||||
|
||||
def regenerate_mapping():
|
||||
"""Regenerate the MaterialSymbolsOutlined.json file, assuming
|
||||
MaterialSymbolsOutlined.codepoints and the TrueType font file have been
|
||||
updated to support the new symbols.
|
||||
"""
|
||||
import json
|
||||
jfile = get_mapping_filepath()
|
||||
cpfile = jfile.replace(".json", ".codepoints")
|
||||
with open(cpfile, "r") as cpf:
|
||||
codepoints = cpf.read()
|
||||
|
||||
mapping = {}
|
||||
for cp in codepoints.splitlines():
|
||||
name, code = cp.split()
|
||||
mapping[name] = int(f"0x{code}", 16)
|
||||
|
||||
with open(jfile, "w") as jf:
|
||||
json.dump(mapping, jf, indent=4)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring AYON addon 'core' version."""
|
||||
__version__ = "1.3.1+dev"
|
||||
__version__ = "1.3.2+dev"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name = "core"
|
||||
title = "Core"
|
||||
version = "1.3.1+dev"
|
||||
version = "1.3.2+dev"
|
||||
|
||||
client_dir = "ayon_core"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
[tool.poetry]
|
||||
name = "ayon-core"
|
||||
version = "1.3.1+dev"
|
||||
version = "1.3.2+dev"
|
||||
description = ""
|
||||
authors = ["Ynput Team <team@ynput.io>"]
|
||||
readme = "README.md"
|
||||
|
|
|
|||
|
|
@ -358,6 +358,14 @@ class PublishToolModel(BaseSettingsModel):
|
|||
title="Custom Staging Dir Profiles"
|
||||
)
|
||||
)
|
||||
comment_minimum_required_chars: int = SettingsField(
|
||||
0,
|
||||
title="Publish comment minimum required characters",
|
||||
description=(
|
||||
"Minimum number of characters required in the comment field "
|
||||
"before the publisher UI is allowed to continue publishing"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class GlobalToolsModel(BaseSettingsModel):
|
||||
|
|
@ -671,6 +679,7 @@ DEFAULT_TOOLS_VALUES = {
|
|||
"task_names": [],
|
||||
"template_name": "simpleUnrealTextureHero"
|
||||
}
|
||||
]
|
||||
],
|
||||
"comment_minimum_required_chars": 0,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue