mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge branch 'develop' into enhancement/use-ayon-logger-in-load-plugins
This commit is contained in:
commit
6b57f406ca
5 changed files with 88 additions and 26 deletions
|
|
@ -9,7 +9,7 @@ from typing import Optional, Union, Any
|
|||
|
||||
import ayon_api
|
||||
|
||||
from ayon_core.host import ILoadHost
|
||||
from ayon_core.host import ILoadHost, AbstractHost
|
||||
from ayon_core.lib import (
|
||||
StringTemplate,
|
||||
TemplateUnsolved,
|
||||
|
|
@ -942,15 +942,21 @@ def any_outdated_containers(host=None, project_name=None):
|
|||
return False
|
||||
|
||||
|
||||
def get_outdated_containers(host=None, project_name=None):
|
||||
def get_outdated_containers(
|
||||
host: Optional[AbstractHost] = None,
|
||||
project_name: Optional[str] = None,
|
||||
ignore_locked_versions: bool = False,
|
||||
):
|
||||
"""Collect outdated containers from host scene.
|
||||
|
||||
Currently registered host and project in global session are used if
|
||||
arguments are not passed.
|
||||
|
||||
Args:
|
||||
host (ModuleType): Host implementation with 'ls' function available.
|
||||
project_name (str): Name of project in which context we are.
|
||||
host (Optional[AbstractHost]): Host implementation.
|
||||
project_name (Optional[str]): Name of project in which context we are.
|
||||
ignore_locked_versions (bool): Locked versions are ignored.
|
||||
|
||||
"""
|
||||
from ayon_core.pipeline import registered_host, get_current_project_name
|
||||
|
||||
|
|
@ -964,7 +970,16 @@ def get_outdated_containers(host=None, project_name=None):
|
|||
containers = host.get_containers()
|
||||
else:
|
||||
containers = host.ls()
|
||||
return filter_containers(containers, project_name).outdated
|
||||
|
||||
outdated_containers = []
|
||||
for container in filter_containers(containers, project_name).outdated:
|
||||
if (
|
||||
not ignore_locked_versions
|
||||
and container.get("version_locked") is True
|
||||
):
|
||||
continue
|
||||
outdated_containers.append(container)
|
||||
return outdated_containers
|
||||
|
||||
|
||||
def _is_valid_representation_id(repre_id: Any) -> bool:
|
||||
|
|
@ -985,6 +1000,9 @@ def filter_containers(containers, project_name):
|
|||
'invalid' are invalid containers (invalid content) and 'not_found' has
|
||||
some missing entity in database.
|
||||
|
||||
Todos:
|
||||
Respect 'project_name' on containers if is available.
|
||||
|
||||
Args:
|
||||
containers (Iterable[dict]): List of containers referenced into scene.
|
||||
project_name (str): Name of project in which context shoud look for
|
||||
|
|
@ -993,8 +1011,8 @@ def filter_containers(containers, project_name):
|
|||
Returns:
|
||||
ContainersFilterResult: Named tuple with 'latest', 'outdated',
|
||||
'invalid' and 'not_found' containers.
|
||||
"""
|
||||
|
||||
"""
|
||||
# Make sure containers is list that won't change
|
||||
containers = list(containers)
|
||||
|
||||
|
|
@ -1042,13 +1060,13 @@ def filter_containers(containers, project_name):
|
|||
hero=True,
|
||||
fields={"id", "productId", "version"}
|
||||
)
|
||||
verisons_by_id = {}
|
||||
versions_by_id = {}
|
||||
versions_by_product_id = collections.defaultdict(list)
|
||||
hero_version_ids = set()
|
||||
for version_entity in version_entities:
|
||||
version_id = version_entity["id"]
|
||||
# Store versions by their ids
|
||||
verisons_by_id[version_id] = version_entity
|
||||
versions_by_id[version_id] = version_entity
|
||||
# There's no need to query products for hero versions
|
||||
# - they are considered as latest?
|
||||
if version_entity["version"] < 0:
|
||||
|
|
@ -1083,24 +1101,23 @@ def filter_containers(containers, project_name):
|
|||
|
||||
repre_entity = repre_entities_by_id.get(repre_id)
|
||||
if not repre_entity:
|
||||
log.debug((
|
||||
"Container '{}' has an invalid representation."
|
||||
log.debug(
|
||||
f"Container '{container_name}' has an invalid representation."
|
||||
" It is missing in the database."
|
||||
).format(container_name))
|
||||
)
|
||||
not_found_containers.append(container)
|
||||
continue
|
||||
|
||||
version_id = repre_entity["versionId"]
|
||||
if version_id in outdated_version_ids:
|
||||
outdated_containers.append(container)
|
||||
|
||||
elif version_id not in verisons_by_id:
|
||||
log.debug((
|
||||
"Representation on container '{}' has an invalid version."
|
||||
" It is missing in the database."
|
||||
).format(container_name))
|
||||
if version_id not in versions_by_id:
|
||||
log.debug(
|
||||
f"Representation on container '{container_name}' has an"
|
||||
" invalid version. It is missing in the database."
|
||||
)
|
||||
not_found_containers.append(container)
|
||||
|
||||
elif version_id in outdated_version_ids:
|
||||
outdated_containers.append(container)
|
||||
else:
|
||||
uptodate_containers.append(container)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
from qtpy import QtWidgets, QtCore, QtGui
|
||||
|
||||
from .model import VERSION_LABEL_ROLE
|
||||
from ayon_core.tools.utils import get_qt_icon
|
||||
|
||||
from .model import VERSION_LABEL_ROLE, CONTAINER_VERSION_LOCKED_ROLE
|
||||
|
||||
|
||||
class VersionDelegate(QtWidgets.QStyledItemDelegate):
|
||||
"""A delegate that display version integer formatted as version string."""
|
||||
_locked_icon = None
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
fg_color = index.data(QtCore.Qt.ForegroundRole)
|
||||
if fg_color:
|
||||
|
|
@ -45,10 +49,35 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
|
|||
QtWidgets.QStyle.PM_FocusFrameHMargin, option, option.widget
|
||||
) + 1
|
||||
|
||||
text_rect_f = text_rect.adjusted(
|
||||
text_margin, 0, - text_margin, 0
|
||||
)
|
||||
|
||||
painter.drawText(
|
||||
text_rect.adjusted(text_margin, 0, - text_margin, 0),
|
||||
text_rect_f,
|
||||
option.displayAlignment,
|
||||
text
|
||||
)
|
||||
if index.data(CONTAINER_VERSION_LOCKED_ROLE) is True:
|
||||
icon = self._get_locked_icon()
|
||||
size = max(text_rect_f.height() // 2, 16)
|
||||
margin = (text_rect_f.height() - size) // 2
|
||||
|
||||
icon_rect = QtCore.QRect(
|
||||
text_rect_f.right() - size,
|
||||
text_rect_f.top() + margin,
|
||||
size,
|
||||
size
|
||||
)
|
||||
icon.paint(painter, icon_rect)
|
||||
|
||||
painter.restore()
|
||||
|
||||
def _get_locked_icon(cls):
|
||||
if cls._locked_icon is None:
|
||||
cls._locked_icon = get_qt_icon({
|
||||
"type": "material-symbols",
|
||||
"name": "lock",
|
||||
"color": "white",
|
||||
})
|
||||
return cls._locked_icon
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ REMOTE_SITE_ICON_ROLE = QtCore.Qt.UserRole + 23
|
|||
# containers inbetween refresh.
|
||||
ITEM_UNIQUE_NAME_ROLE = QtCore.Qt.UserRole + 24
|
||||
PROJECT_NAME_ROLE = QtCore.Qt.UserRole + 25
|
||||
CONTAINER_VERSION_LOCKED_ROLE = QtCore.Qt.UserRole + 26
|
||||
|
||||
|
||||
class InventoryModel(QtGui.QStandardItemModel):
|
||||
|
|
@ -291,6 +292,10 @@ class InventoryModel(QtGui.QStandardItemModel):
|
|||
item.setData(container_item.object_name, OBJECT_NAME_ROLE)
|
||||
item.setData(True, IS_CONTAINER_ITEM_ROLE)
|
||||
item.setData(unique_name, ITEM_UNIQUE_NAME_ROLE)
|
||||
item.setData(
|
||||
container_item.version_locked,
|
||||
CONTAINER_VERSION_LOCKED_ROLE
|
||||
)
|
||||
container_model_items.append(item)
|
||||
|
||||
progress = progress_by_id[repre_id]
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ class ContainerItem:
|
|||
namespace,
|
||||
object_name,
|
||||
item_id,
|
||||
project_name
|
||||
project_name,
|
||||
version_locked,
|
||||
):
|
||||
self.representation_id = representation_id
|
||||
self.loader_name = loader_name
|
||||
|
|
@ -103,6 +104,7 @@ class ContainerItem:
|
|||
self.namespace = namespace
|
||||
self.item_id = item_id
|
||||
self.project_name = project_name
|
||||
self.version_locked = version_locked
|
||||
|
||||
@classmethod
|
||||
def from_container_data(cls, current_project_name, container):
|
||||
|
|
@ -114,7 +116,8 @@ class ContainerItem:
|
|||
item_id=uuid.uuid4().hex,
|
||||
project_name=container.get(
|
||||
"project_name", current_project_name
|
||||
)
|
||||
),
|
||||
version_locked=container.get("version_locked", False),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from ayon_core.tools.utils.lib import (
|
|||
format_version,
|
||||
preserve_expanded_rows,
|
||||
preserve_selection,
|
||||
get_qt_icon,
|
||||
)
|
||||
from ayon_core.tools.utils.delegates import StatusDelegate
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
hierarchy_view_changed = QtCore.Signal(bool)
|
||||
|
||||
def __init__(self, controller, parent):
|
||||
super(SceneInventoryView, self).__init__(parent=parent)
|
||||
super().__init__(parent=parent)
|
||||
|
||||
# view settings
|
||||
self.setIndentation(12)
|
||||
|
|
@ -524,7 +525,14 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
submenu = QtWidgets.QMenu("Actions", self)
|
||||
for action in custom_actions:
|
||||
color = action.color or DEFAULT_COLOR
|
||||
icon = qtawesome.icon("fa.%s" % action.icon, color=color)
|
||||
icon_def = action.icon
|
||||
if not isinstance(action.icon, dict):
|
||||
icon_def = {
|
||||
"type": "awesome-font",
|
||||
"name": icon_def,
|
||||
"color": color,
|
||||
}
|
||||
icon = get_qt_icon(icon_def)
|
||||
action_item = QtWidgets.QAction(icon, action.label, submenu)
|
||||
action_item.triggered.connect(
|
||||
partial(
|
||||
|
|
@ -622,7 +630,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
if isinstance(result, (list, set)):
|
||||
self._select_items_by_action(result)
|
||||
|
||||
if isinstance(result, dict):
|
||||
elif isinstance(result, dict):
|
||||
self._select_items_by_action(
|
||||
result["objectNames"], result["options"]
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue