created objects for controller <-> ui communiction related to plugin actions and validation errors

This commit is contained in:
Jakub Trllo 2022-10-07 11:23:01 +02:00
parent f13d2bc965
commit a3d16def9b

View file

@ -377,6 +377,242 @@ class PublishPluginsProxy:
)
class PublishPluginActionItem:
"""Representation of publish plugin action.
Data driven object which is used as proxy for controller and UI.
Args:
action_id (str): Action id.
plugin_id (str): Plugin id.
active (bool): Action is active.
on_filter (str): Actions have 'on' attribte which define when can be
action triggered (e.g. 'all', 'failed', ...).
label (str): Action's label.
icon (Union[str, None]) Action's icon.
"""
def __init__(self, action_id, plugin_id, active, on_filter, label, icon):
self.action_id = action_id
self.plugin_id = plugin_id
self.active = active
self.on_filter = on_filter
self.label = label
self.icon = icon
def to_data(self):
"""Serialize object to dictionary.
Returns:
Dict[str, Union[str,bool,None]]: Serialized object.
"""
return {
"action_id": self.action_id,
"plugin_id": self.plugin_id,
"active": self.active,
"on_filter": self.on_filter,
"label": self.label,
"icon": self.icon
}
@classmethod
def from_data(cls, data):
"""Create object from data.
Args:
data (Dict[str, Union[str,bool,None]]): Data used to recreate
object.
Returns:
PublishPluginActionItem: Object created using data.
"""
return cls(**data)
class ValidationErrorItem:
"""Data driven validation error item.
Prepared data container with information about validation error and it's
source plugin.
Can be converted to raw data and recreated should be used for controller
and UI connection.
Args:
instance_id (str): Id of pyblish instance to which is validation error
connected.
instance_label (str): Prepared instance label.
plugin_id (str): Id of pyblish Plugin which triggered the validation
error. Id is generated using 'PublishPluginsProxy'.
"""
def __init__(
self,
instance_id,
instance_label,
plugin_id,
context_validation,
title,
description,
detail,
):
self.instance_id = instance_id
self.instance_label = instance_label
self.plugin_id = plugin_id
self.context_validation = context_validation
self.title = title
self.description = description
self.detail = detail
def to_data(self):
"""Serialize object to dictionary.
Returns:
Dict[str, Union[str, bool, None]]: Serialized object data.
"""
return {
"instance_id": self.instance_id,
"instance_label": self.instance_label,
"plugin_id": self.plugin_id,
"context_validation": self.context_validation,
"title": self.title,
"description": self.description,
"detail": self.detail,
}
@classmethod
def from_result(cls, plugin_id, error, instance):
"""Create new object based on resukt from controller.
Returns:
ValidationErrorItem: New object with filled data.
"""
instance_label = None
instance_id = None
if instance is not None:
instance_label = (
instance.data.get("label") or instance.data.get("name")
)
instance_id = instance.id
return cls(
instance_id,
instance_label,
plugin_id,
instance is None,
error.title,
error.description,
error.detail,
)
@classmethod
def from_data(cls, data):
return cls(**data)
class PublishValidationErrorsReport:
"""Publish validation errors report that can be parsed to raw data.
Args:
error_items (List[ValidationErrorItem]): List of validation errors.
plugin_action_items (Dict[str, PublishPluginActionItem]): Action items
by plugin id.
"""
def __init__(self, error_items, plugin_action_items):
self._error_items = error_items
self._plugin_action_items = plugin_action_items
def __iter__(self):
for item in self._error_items:
yield item
def group_items_by_title(self):
"""Group errors by plugin and their titles.
Items are grouped by plugin and title -> same title from different
plugin is different item. Items are ordered by plugin order.
Returns:
List[Dict[str, Any]]: List where each item title, instance
information related to title and possible plugin actions.
"""
ordered_plugin_ids = []
error_items_by_plugin_id = collections.defaultdict(list)
for error_item in self._error_items:
plugin_id = error_item.plugin_id
if plugin_id not in ordered_plugin_ids:
ordered_plugin_ids.append(plugin_id)
error_items_by_plugin_id[plugin_id].append(error_item)
grouped_error_items = []
for plugin_id in ordered_plugin_ids:
plugin_action_items = self._plugin_action_items[plugin_id]
error_items = error_items_by_plugin_id[plugin_id]
titles = []
error_items_by_title = collections.defaultdict(list)
for error_item in error_items:
title = error_item.title
if title not in titles:
titles.append(error_item.title)
error_items_by_title[title].append(error_item)
for title in titles:
grouped_error_items.append({
"plugin_action_items": list(plugin_action_items),
"error_items": error_items_by_title[title],
"title": title
})
return grouped_error_items
def to_data(self):
"""Serialize object to dictionary.
Returns:
Dict[str, Any]: Serialized data.
"""
return {
"error_items": [
item.to_data()
for item in self._error_items
],
"plugin_action_items": {
plugin_id: [
action_item.to_data()
for action_item in action_items
]
for plugin_id, action_items in self._plugin_action_items.items()
}
}
@classmethod
def from_data(cls, data):
"""Recreate object from data.
Args:
data (dict[str, Any]): Data to recreate object. Can be created
using 'to_data' method.
Returns:
PublishValidationErrorsReport: New object based on data.
"""
error_items = [
ValidationErrorItem.from_data(error_item)
for error_item in data["error_items"]
]
plugin_action_items = [
PublishPluginActionItem.from_data(action_item)
for action_item in data["plugin_action_items"]
]
return cls(error_items, plugin_action_items)
@six.add_metaclass(ABCMeta)