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", "standalonepublisher" ] 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