ayon-core/openpype/settings/entities/enum_entity.py
2021-06-22 14:11:57 +02:00

372 lines
12 KiB
Python

from .input_entities import InputEntity
from .exceptions import EntitySchemaError
from .lib import (
NOT_SET,
STRING_TYPE
)
class BaseEnumEntity(InputEntity):
def _item_initalization(self):
self.multiselection = True
self.value_on_not_set = None
self.enum_items = None
self.valid_keys = None
self.valid_value_types = None
self.placeholder = None
def schema_validations(self):
if not isinstance(self.enum_items, list):
raise EntitySchemaError(
self, "Enum item must have defined `enum_items` as list."
)
enum_keys = set()
for item in self.enum_items:
key = tuple(item.keys())[0]
if key in enum_keys:
reason = "Key \"{}\" is more than once in enum items.".format(
key
)
raise EntitySchemaError(self, reason)
enum_keys.add(key)
if not isinstance(key, STRING_TYPE):
reason = "Key \"{}\" has invalid type {}, expected {}.".format(
key, type(key), STRING_TYPE
)
raise EntitySchemaError(self, reason)
super(BaseEnumEntity, self).schema_validations()
def _convert_to_valid_type(self, value):
if self.multiselection:
if isinstance(value, (set, tuple)):
return list(value)
elif isinstance(value, (int, float)):
return str(value)
return NOT_SET
def set(self, value):
new_value = self.convert_to_valid_type(value)
if self.multiselection:
check_values = new_value
else:
check_values = [new_value]
for item in check_values:
if item not in self.valid_keys:
raise ValueError(
"{} Invalid value \"{}\". Expected one of: {}".format(
self.path, item, self.valid_keys
)
)
self._current_value = new_value
self._on_value_change()
class EnumEntity(BaseEnumEntity):
schema_types = ["enum"]
def _item_initalization(self):
self.multiselection = self.schema_data.get("multiselection", False)
self.enum_items = self.schema_data.get("enum_items")
valid_keys = set()
for item in self.enum_items or []:
valid_keys.add(tuple(item.keys())[0])
self.valid_keys = valid_keys
if self.multiselection:
self.valid_value_types = (list, )
self.value_on_not_set = []
else:
for key in valid_keys:
if self.value_on_not_set is NOT_SET:
self.value_on_not_set = key
break
self.valid_value_types = (STRING_TYPE, )
# GUI attribute
self.placeholder = self.schema_data.get("placeholder")
def schema_validations(self):
if not self.enum_items and "enum_items" not in self.schema_data:
raise EntitySchemaError(
self, "Enum item must have defined `enum_items`"
)
super(EnumEntity, self).schema_validations()
class HostsEnumEntity(BaseEnumEntity):
"""Enumeration of host names.
Enum items are hardcoded in definition of the entity.
Hosts enum can have defined empty value as valid option which is
represented by empty string. Schema key to set this option is
`use_empty_value` (true/false). And to set label of empty value set
`empty_label` (string).
Enum can have single and multiselection.
NOTE:
Host name is not the same as application name. Host name defines
implementation instead of application name.
"""
schema_types = ["hosts-enum"]
def _item_initalization(self):
self.multiselection = self.schema_data.get("multiselection", True)
self.use_empty_value = self.schema_data.get(
"use_empty_value", not self.multiselection
)
custom_labels = self.schema_data.get("custom_labels") or {}
host_names = [
"aftereffects",
"blender",
"celaction",
"fusion",
"harmony",
"hiero",
"houdini",
"maya",
"nuke",
"photoshop",
"resolve",
"tvpaint",
"unreal"
]
if self.use_empty_value:
host_names.insert(0, "")
# Add default label for empty value if not available
if "" not in custom_labels:
custom_labels[""] = "< without host >"
# These are hardcoded there is not list of available host in OpenPype
enum_items = []
valid_keys = set()
for key in host_names:
label = custom_labels.get(key, key)
valid_keys.add(key)
enum_items.append({key: label})
self.enum_items = enum_items
self.valid_keys = valid_keys
if self.multiselection:
self.valid_value_types = (list, )
self.value_on_not_set = []
else:
for key in valid_keys:
if self.value_on_not_set is NOT_SET:
self.value_on_not_set = key
break
self.valid_value_types = (STRING_TYPE, )
# GUI attribute
self.placeholder = self.schema_data.get("placeholder")
class AppsEnumEntity(BaseEnumEntity):
schema_types = ["apps-enum"]
def _item_initalization(self):
self.multiselection = True
self.value_on_not_set = []
self.enum_items = []
self.valid_keys = set()
self.valid_value_types = (list, )
self.placeholder = None
def _get_enum_values(self):
system_settings_entity = self.get_entity_from_path("system_settings")
valid_keys = set()
enum_items_list = []
applications_entity = system_settings_entity["applications"]
for group_name, app_group in applications_entity.items():
enabled_entity = app_group.get("enabled")
if enabled_entity and not enabled_entity.value:
continue
host_name_entity = app_group.get("host_name")
if not host_name_entity or not host_name_entity.value:
continue
group_label = app_group["label"].value
variants_entity = app_group["variants"]
for variant_name, variant_entity in variants_entity.items():
enabled_entity = variant_entity.get("enabled")
if enabled_entity and not enabled_entity.value:
continue
variant_label = None
if "variant_label" in variant_entity:
variant_label = variant_entity["variant_label"].value
elif hasattr(variants_entity, "get_key_label"):
variant_label = variants_entity.get_key_label(variant_name)
if not variant_label:
variant_label = variant_name
if group_label:
full_label = "{} {}".format(group_label, variant_label)
else:
full_label = variant_label
full_name = "/".join((group_name, variant_name))
enum_items_list.append((full_name, full_label))
valid_keys.add(full_name)
enum_items = []
for key, value in sorted(enum_items_list, key=lambda item: item[1]):
enum_items.append({key: value})
return enum_items, valid_keys
def set_override_state(self, *args, **kwargs):
super(AppsEnumEntity, self).set_override_state(*args, **kwargs)
self.enum_items, self.valid_keys = self._get_enum_values()
new_value = []
for key in self._current_value:
if key in self.valid_keys:
new_value.append(key)
self._current_value = new_value
class ToolsEnumEntity(BaseEnumEntity):
schema_types = ["tools-enum"]
def _item_initalization(self):
self.multiselection = True
self.value_on_not_set = []
self.enum_items = []
self.valid_keys = set()
self.valid_value_types = (list, )
self.placeholder = None
def _get_enum_values(self):
system_settings_entity = self.get_entity_from_path("system_settings")
valid_keys = set()
enum_items_list = []
tool_groups_entity = system_settings_entity["tools"]["tool_groups"]
for group_name, tool_group in tool_groups_entity.items():
# Try to get group label from entity
group_label = None
if hasattr(tool_groups_entity, "get_key_label"):
group_label = tool_groups_entity.get_key_label(group_name)
variants_entity = tool_group["variants"]
for variant_name in variants_entity.keys():
# Prepare tool name (used as value)
tool_name = "/".join((group_name, variant_name))
# Try to get variant label from entity
variant_label = None
if hasattr(variants_entity, "get_key_label"):
variant_label = variants_entity.get_key_label(variant_name)
# Tool label that will be shown
# - use tool name itself if labels are not filled
if group_label and variant_label:
tool_label = " ".join((group_label, variant_label))
else:
tool_label = tool_name
enum_items_list.append((tool_name, tool_label))
valid_keys.add(tool_name)
enum_items = []
for key, value in sorted(enum_items_list, key=lambda item: item[1]):
enum_items.append({key: value})
return enum_items, valid_keys
def set_override_state(self, *args, **kwargs):
super(ToolsEnumEntity, self).set_override_state(*args, **kwargs)
self.enum_items, self.valid_keys = self._get_enum_values()
new_value = []
for key in self._current_value:
if key in self.valid_keys:
new_value.append(key)
self._current_value = new_value
class TaskTypeEnumEntity(BaseEnumEntity):
schema_types = ["task-types-enum"]
def _item_initalization(self):
self.multiselection = True
self.value_on_not_set = []
self.enum_items = []
self.valid_keys = set()
self.valid_value_types = (list, )
self.placeholder = None
def _get_enum_values(self):
anatomy_entity = self.get_entity_from_path(
"project_settings/project_anatomy"
)
valid_keys = set()
enum_items = []
for task_type in anatomy_entity["tasks"].keys():
enum_items.append({task_type: task_type})
valid_keys.add(task_type)
return enum_items, valid_keys
def set_override_state(self, *args, **kwargs):
super(TaskTypeEnumEntity, self).set_override_state(*args, **kwargs)
self.enum_items, self.valid_keys = self._get_enum_values()
new_value = []
for key in self._current_value:
if key in self.valid_keys:
new_value.append(key)
self._current_value = new_value
class ProvidersEnum(BaseEnumEntity):
schema_types = ["providers-enum"]
def _item_initalization(self):
self.multiselection = False
self.value_on_not_set = ""
self.enum_items = []
self.valid_keys = set()
self.valid_value_types = (str, )
self.placeholder = None
def _get_enum_values(self):
from openpype.modules.sync_server.providers import lib as lib_providers
providers = lib_providers.factory.providers
valid_keys = set()
valid_keys.add('')
enum_items = [{'': 'Choose Provider'}]
for provider_code, provider_info in providers.items():
provider, _ = provider_info
enum_items.append({provider_code: provider.LABEL})
valid_keys.add(provider_code)
return enum_items, valid_keys
def set_override_state(self, *args, **kwargs):
super(ProvidersEnum, self).set_override_state(*args, **kwargs)
self.enum_items, self.valid_keys = self._get_enum_values()
value_on_not_set = list(self.valid_keys)[0]
if self._current_value is NOT_SET:
self._current_value = value_on_not_set
self.value_on_not_set = value_on_not_set