Merge pull request #1190 from pypeclub/feature/key_validations

Key validations in settings
This commit is contained in:
Milan Kolar 2021-03-30 10:06:25 +02:00 committed by GitHub
commit da869ef633
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 402 additions and 419 deletions

View file

@ -85,6 +85,13 @@ def add_shortcuts_from_presets():
nuke_presets = get_current_project_settings()["nuke"]
if nuke_presets.get("menu"):
menu_label_mapping = {
"manage": "Manage...",
"create": "Create...",
"load": "Load...",
"build_workfile": "Build Workfile",
"publish": "Publish..."
}
for menu_name, menuitems in nuke_presets.get("menu").items():
menu = menubar.findItem(menu_name)
for mitem_name, shortcut in menuitems.items():
@ -92,7 +99,8 @@ def add_shortcuts_from_presets():
shortcut, mitem_name
))
try:
menuitem = menu.findItem(mitem_name)
item_label = menu_label_mapping[mitem_name]
menuitem = menu.findItem(item_label)
menuitem.setShortcut(shortcut)
except AttributeError as e:
log.error(e)

View file

@ -138,20 +138,16 @@ class ApplicationManager:
app_group, app_name, host_name, app_data, self
)
tools_definitions = settings["tools"]
tools_definitions = settings["tools"]["tool_groups"]
for tool_group_name, tool_group_data in tools_definitions.items():
enabled = tool_group_data.get("enabled", True)
tool_variants = tool_group_data.get("variants") or {}
for tool_name, tool_data in tool_variants.items():
if tool_name in self.tools:
tool = ApplicationTool(tool_name, tool_group_name)
if tool.full_name in self.tools:
self.log.warning((
"Duplicated tool name in settings \"{}\""
).format(tool_name))
_enabled = tool_data.get("enabled", enabled)
self.tools[tool_name] = ApplicationTool(
tool_name, tool_group_name, _enabled
)
).format(tool.full_name))
self.tools[tool.full_name] = tool
def launch(self, app_name, **data):
"""Launch procedure.
@ -196,16 +192,15 @@ class ApplicationTool:
Args:
tool_name (str): Name of the tool.
group_name (str): Name of group which wraps tool.
enabled (bool): Is tool enabled by studio.
"""
def __init__(self, tool_name, group_name, enabled):
def __init__(self, tool_name, group_name):
self.name = tool_name
self.group_name = group_name
self.enabled = enabled
def __bool__(self):
return self.enabled
@property
def full_name(self):
return "/".join((self.group_name, self.name))
class ApplicationExecutable:

View file

@ -400,11 +400,10 @@ class CustomAttributes(BaseAction):
def tools_attribute(self, event):
tools_data = []
for tool_name, tool in self.app_manager.tools.items():
if tool.enabled:
tools_data.append({
tool_name: tool_name
})
for tool_name in self.app_manager.tools.keys():
tools_data.append({
tool_name: tool_name
})
# Make sure there is at least one item
if not tools_data:

View file

@ -1,3 +1,6 @@
import re
# Metadata keys for work with studio and project overrides
M_OVERRIDEN_KEY = "__overriden_keys__"
# Metadata key for storing information about environments
@ -19,6 +22,10 @@ LOCAL_SETTING_KEY = "local_settings"
DEFAULT_PROJECT_KEY = "__default_project__"
KEY_ALLOWED_SYMBOLS = "a-zA-Z0-9-_ "
KEY_REGEX = re.compile(r"^[{}]+$".format(KEY_ALLOWED_SYMBOLS))
__all__ = (
"M_OVERRIDEN_KEY",
"M_ENVIRONMENT_KEY",
@ -29,5 +36,10 @@ __all__ = (
"SYSTEM_SETTINGS_KEY",
"PROJECT_SETTINGS_KEY",
"PROJECT_ANATOMY_KEY",
"LOCAL_SETTING_KEY"
"LOCAL_SETTING_KEY",
"DEFAULT_PROJECT_KEY",
"KEY_ALLOWED_SYMBOLS",
"KEY_REGEX"
)

View file

@ -1,11 +1,11 @@
{
"menu": {
"Pype": {
"Create...": "ctrl+shift+alt+c",
"Publish...": "ctrl+alt+p",
"Load...": "ctrl+alt+l",
"Manage...": "ctrl+alt+m",
"Build Workfile": "ctrl+alt+b"
"create": "ctrl+shift+alt+c",
"publish": "ctrl+alt+p",
"load": "ctrl+alt+l",
"manage": "ctrl+alt+m",
"build_workfile": "ctrl+alt+b"
}
},
"create": {

View file

@ -253,7 +253,7 @@
}
},
"variants": {
"nuke_12.2": {
"nuke_12-2": {
"enabled": true,
"label": "",
"variant_label": "12.2",
@ -274,11 +274,11 @@
},
"environment": {
"__environment_keys__": {
"nuke_12.2": []
"nuke_12-2": []
}
}
},
"nuke_12.0": {
"nuke_12-0": {
"enabled": true,
"label": "",
"variant_label": "12.0",
@ -299,11 +299,11 @@
},
"environment": {
"__environment_keys__": {
"nuke_12.0": []
"nuke_12-0": []
}
}
},
"nuke_11.3": {
"nuke_11-3": {
"enabled": true,
"label": "",
"variant_label": "11.3",
@ -324,11 +324,11 @@
},
"environment": {
"__environment_keys__": {
"nuke_11.3": []
"nuke_11-3": []
}
}
},
"nuke_11.2": {
"nuke_11-2": {
"enabled": true,
"label": "",
"variant_label": "11.2",
@ -347,7 +347,7 @@
},
"environment": {
"__environment_keys__": {
"nuke_11.2": []
"nuke_11-2": []
}
}
}
@ -377,7 +377,7 @@
}
},
"variants": {
"nukex_12.2": {
"nukex_12-2": {
"enabled": true,
"label": "",
"variant_label": "12.2",
@ -404,11 +404,11 @@
},
"environment": {
"__environment_keys__": {
"nukex_12.2": []
"nukex_12-2": []
}
}
},
"nukex_12.0": {
"nukex_12-0": {
"enabled": true,
"label": "",
"variant_label": "12.0",
@ -435,11 +435,11 @@
},
"environment": {
"__environment_keys__": {
"nukex_12.0": []
"nukex_12-0": []
}
}
},
"nukex_11.3": {
"nukex_11-3": {
"enabled": true,
"label": "",
"variant_label": "11.3",
@ -466,11 +466,11 @@
},
"environment": {
"__environment_keys__": {
"nukex_11.3": []
"nukex_11-3": []
}
}
},
"nukex_11.2": {
"nukex_11-2": {
"enabled": true,
"label": "",
"variant_label": "11.2",
@ -495,7 +495,7 @@
},
"environment": {
"__environment_keys__": {
"nukex_11.2": []
"nukex_11-2": []
}
}
}
@ -527,7 +527,7 @@
}
},
"variants": {
"nukestudio_12.2": {
"nukestudio_12-2": {
"enabled": true,
"label": "",
"variant_label": "12.2",
@ -554,11 +554,11 @@
},
"environment": {
"__environment_keys__": {
"nukestudio_12.2": []
"nukestudio_12-2": []
}
}
},
"nukestudio_12.0": {
"nukestudio_12-0": {
"enabled": true,
"label": "",
"variant_label": "12.0",
@ -585,11 +585,11 @@
},
"environment": {
"__environment_keys__": {
"nukestudio_12.0": []
"nukestudio_12-0": []
}
}
},
"nukestudio_11.3": {
"nukestudio_11-3": {
"enabled": true,
"label": "",
"variant_label": "11.3",
@ -616,11 +616,11 @@
},
"environment": {
"__environment_keys__": {
"nukestudio_11.3": []
"nukestudio_11-3": []
}
}
},
"nukestudio_11.2": {
"nukestudio_11-2": {
"enabled": true,
"label": "",
"variant_label": "11.2",
@ -643,7 +643,7 @@
},
"environment": {
"__environment_keys__": {
"nukestudio_11.2": []
"nukestudio_11-2": []
}
}
}
@ -675,7 +675,7 @@
}
},
"variants": {
"hiero_12.2": {
"hiero_12-2": {
"enabled": true,
"label": "",
"variant_label": "12.2",
@ -702,11 +702,11 @@
},
"environment": {
"__environment_keys__": {
"hiero_12.2": []
"hiero_12-2": []
}
}
},
"hiero_12.0": {
"hiero_12-0": {
"enabled": true,
"label": "",
"variant_label": "12.0",
@ -733,11 +733,11 @@
},
"environment": {
"__environment_keys__": {
"hiero_12.0": []
"hiero_12-0": []
}
}
},
"hiero_11.3": {
"hiero_11-3": {
"enabled": true,
"label": "",
"variant_label": "11.3",
@ -764,11 +764,11 @@
},
"environment": {
"__environment_keys__": {
"hiero_11.3": []
"hiero_11-3": []
}
}
},
"hiero_11.2": {
"hiero_11-2": {
"enabled": true,
"label": "",
"variant_label": "11.2",
@ -793,7 +793,7 @@
},
"environment": {
"__environment_keys__": {
"hiero_11.2": []
"hiero_11-2": []
}
}
}
@ -992,7 +992,7 @@
}
},
"variants": {
"houdini_18.5": {
"houdini_18-5": {
"enabled": true,
"label": "",
"variant_label": "18.5",
@ -1011,7 +1011,7 @@
},
"environment": {
"__environment_keys__": {
"houdini_18.5": []
"houdini_18-5": []
}
}
},
@ -1080,36 +1080,7 @@
}
},
"variants": {
"blender_2.90": {
"enabled": true,
"label": "",
"variant_label": "2.90",
"icon": "",
"executables": {
"windows": [
"C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe"
],
"darwin": [],
"linux": []
},
"arguments": {
"windows": [
"--python-use-system-env"
],
"darwin": [
"--python-use-system-env"
],
"linux": [
"--python-use-system-env"
]
},
"environment": {
"__environment_keys__": {
"blender_2.90": []
}
}
},
"blender_2.83": {
"blender_2-83": {
"enabled": true,
"label": "",
"variant_label": "2.83",
@ -1134,7 +1105,36 @@
},
"environment": {
"__environment_keys__": {
"blender_2.83": []
"blender_2-83": []
}
}
},
"blender_2-90": {
"enabled": true,
"label": "",
"variant_label": "2.90",
"icon": "",
"executables": {
"windows": [
"C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe"
],
"darwin": [],
"linux": []
},
"arguments": {
"windows": [
"--python-use-system-env"
],
"darwin": [
"--python-use-system-env"
],
"linux": [
"--python-use-system-env"
]
},
"environment": {
"__environment_keys__": {
"blender_2-90": []
}
}
}
@ -1216,7 +1216,7 @@
}
},
"variants": {
"tvpaint_Animation 11 (64bits)": {
"tvpaint_animation_11-64bits": {
"enabled": true,
"label": "",
"variant_label": "11 (64bits)",
@ -1235,11 +1235,11 @@
},
"environment": {
"__environment_keys__": {
"tvpaint_Animation 11 (64bits)": []
"tvpaint_animation_11-64bits": []
}
}
},
"tvpaint_Animation 11 (32bits)": {
"tvpaint_animation_11-32bits": {
"enabled": true,
"label": "",
"variant_label": "11 (32bits)",
@ -1258,7 +1258,7 @@
},
"environment": {
"__environment_keys__": {
"tvpaint_Animation 11 (32bits)": []
"tvpaint_animation_11-32bits": []
}
}
}
@ -1430,23 +1430,6 @@
"celation_Local": []
}
}
},
"celation_Publish": {
"enabled": true,
"label": "",
"variant_label": "Pulblish",
"icon": "",
"executables": "",
"arguments": {
"windows": [],
"darwin": [],
"linux": []
},
"environment": {
"__environment_keys__": {
"celation_Publish": []
}
}
}
}
},
@ -1468,7 +1451,7 @@
}
},
"variants": {
"unreal_4.24": {
"unreal_4-24": {
"enabled": true,
"label": "",
"variant_label": "4.24",
@ -1485,7 +1468,7 @@
},
"environment": {
"__environment_keys__": {
"unreal_4.24": []
"unreal_4-24": []
}
}
}
@ -1499,7 +1482,7 @@
}
},
"variants": {
"python_Python 3.7": {
"python_python_3-7": {
"enabled": true,
"label": "Python",
"variant_label": "3.7",
@ -1516,11 +1499,11 @@
},
"environment": {
"__environment_keys__": {
"python_Python 3.7": []
"python_python_3-7": []
}
}
},
"python_Python 2.7": {
"python_python_2-7": {
"enabled": true,
"label": "Python",
"variant_label": "2.7",
@ -1537,11 +1520,11 @@
},
"environment": {
"__environment_keys__": {
"python_Python 2.7": []
"python_python_2-7": []
}
}
},
"terminal_Terminal": {
"terminal_terminal": {
"enabled": true,
"label": "Terminal",
"variant_label": "",
@ -1558,7 +1541,7 @@
},
"environment": {
"__environment_keys__": {
"terminal_Terminal": []
"terminal_terminal": []
}
}
}
@ -1575,7 +1558,7 @@
}
},
"variants": {
"djvview_1.1": {
"djvview_1-1": {
"enabled": true,
"label": "",
"variant_label": "1.1",
@ -1592,7 +1575,7 @@
},
"environment": {
"__environment_keys__": {
"djvview_1.1": []
"djvview_1-1": []
}
}
}

View file

@ -1,78 +1,53 @@
{
"mtoa": {
"enabled": true,
"environment": {
"MTOA": "{PYPE_STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}",
"MAYA_RENDER_DESC_PATH": "{MTOA}",
"MAYA_MODULE_PATH": "{MTOA}",
"ARNOLD_PLUGIN_PATH": "{MTOA}/shaders",
"MTOA_EXTENSIONS_PATH": {
"darwin": "{MTOA}/extensions",
"linux": "{MTOA}/extensions",
"windows": "{MTOA}/extensions"
"tool_groups": {
"mtoa": {
"environment": {
"MTOA": "{PYPE_STUDIO_SOFTWARE}/arnold/mtoa_{MAYA_VERSION}_{MTOA_VERSION}",
"MAYA_RENDER_DESC_PATH": "{MTOA}",
"MAYA_MODULE_PATH": "{MTOA}",
"ARNOLD_PLUGIN_PATH": "{MTOA}/shaders",
"MTOA_EXTENSIONS_PATH": {
"darwin": "{MTOA}/extensions",
"linux": "{MTOA}/extensions",
"windows": "{MTOA}/extensions"
},
"MTOA_EXTENSIONS": {
"darwin": "{MTOA}/extensions",
"linux": "{MTOA}/extensions",
"windows": "{MTOA}/extensions"
},
"DYLD_LIBRARY_PATH": {
"darwin": "{MTOA}/bin"
},
"PATH": {
"windows": "{PATH};{MTOA}/bin"
}
},
"MTOA_EXTENSIONS": {
"darwin": "{MTOA}/extensions",
"linux": "{MTOA}/extensions",
"windows": "{MTOA}/extensions"
},
"DYLD_LIBRARY_PATH": {
"darwin": "{MTOA}/bin"
},
"PATH": {
"windows": "{PATH};{MTOA}/bin"
},
"__environment_keys__": {
"mtoa": [
"MTOA",
"MAYA_RENDER_DESC_PATH",
"MAYA_MODULE_PATH",
"ARNOLD_PLUGIN_PATH",
"MTOA_EXTENSIONS_PATH",
"MTOA_EXTENSIONS",
"DYLD_LIBRARY_PATH",
"PATH"
]
"variants": {
"3-2": {
"MTOA_VERSION": "3.2"
},
"3-1": {
"MTOA_VERSION": "3.1"
},
"__dynamic_keys_labels__": {
"3-2": "3.2",
"3-1": "3.2"
}
}
},
"variants": {
"mtoa_3.2": {
"MTOA_VERSION": "3.2",
"__environment_keys__": {
"mtoa_3.2": [
"MTOA_VERSION"
]
}
},
"mtoa_3.1": {
"MTOA_VERSION": "3.1",
"__environment_keys__": {
"mtoa_3.1": [
"MTOA_VERSION"
]
}
}
"vray": {
"environment": {},
"variants": {}
},
"yeti": {
"environment": {},
"variants": {}
},
"__dynamic_keys_labels__": {
"mtoa": "Autodesk Arnold",
"vray": "Chaos Group Vray",
"yeti": "Pergrine Labs Yeti"
}
},
"vray": {
"enabled": true,
"environment": {
"__environment_keys__": {
"vray": []
}
},
"variants": {}
},
"yeti": {
"enabled": true,
"environment": {
"__environment_keys__": {
"yeti": []
}
},
"variants": {}
},
"other": {
"variants": {}
}
}

View file

@ -58,6 +58,7 @@ from .exceptions import (
DefaultsNotDefined,
StudioDefaultsNotDefined,
InvalidValueType,
InvalidKeySymbols,
SchemaMissingFileInfo,
SchemeGroupHierarchyBug,
SchemaDuplicatedKeys,
@ -114,6 +115,7 @@ __all__ = (
"DefaultsNotDefined",
"StudioDefaultsNotDefined",
"InvalidValueType",
"InvalidKeySymbols",
"SchemaMissingFileInfo",
"SchemeGroupHierarchyBug",
"SchemaDuplicatedKeys",

View file

@ -7,7 +7,8 @@ from .lib import (
)
from pype.settings.constants import (
METADATA_KEYS,
M_OVERRIDEN_KEY
M_OVERRIDEN_KEY,
KEY_REGEX
)
from . import (
BaseItemEntity,
@ -17,7 +18,8 @@ from . import (
)
from .exceptions import (
SchemaDuplicatedKeys,
EntitySchemaError
EntitySchemaError,
InvalidKeySymbols
)
@ -88,6 +90,10 @@ class DictImmutableKeysEntity(ItemEntity):
else:
raise SchemaDuplicatedKeys(self, child_entity.key)
for key in self.keys():
if not KEY_REGEX.match(key):
raise InvalidKeySymbols(self.path, key)
if self.checkbox_key:
checkbox_child = self.non_gui_children.get(self.checkbox_key)
if not checkbox_child:

View file

@ -1,3 +1,4 @@
import re
import copy
from .lib import (
@ -7,6 +8,7 @@ from .lib import (
from . import EndpointEntity
from .exceptions import (
DefaultsNotDefined,
InvalidKeySymbols,
StudioDefaultsNotDefined,
RequiredKeyModified,
EntitySchemaError
@ -14,7 +16,9 @@ from .exceptions import (
from pype.settings.constants import (
METADATA_KEYS,
M_DYNAMIC_KEY_LABEL,
M_ENVIRONMENT_KEY
M_ENVIRONMENT_KEY,
KEY_REGEX,
KEY_ALLOWED_SYMBOLS
)
@ -92,6 +96,9 @@ class DictMutableKeysEntity(EndpointEntity):
# TODO Check for value type if is Settings entity?
child_obj = self.children_by_key.get(key)
if not child_obj:
if not KEY_REGEX.match(key):
raise InvalidKeySymbols(self.path, key)
child_obj = self.add_key(key)
child_obj.set(value)
@ -102,6 +109,10 @@ class DictMutableKeysEntity(EndpointEntity):
if new_key == old_key:
return
if not KEY_REGEX.match(new_key):
raise InvalidKeySymbols(self.path, new_key)
self.children_by_key[new_key] = self.children_by_key.pop(old_key)
self._on_key_label_change()
@ -116,6 +127,9 @@ class DictMutableKeysEntity(EndpointEntity):
if key in self.children_by_key:
self.pop(key)
if not KEY_REGEX.match(key):
raise InvalidKeySymbols(self.path, key)
if self.value_is_env_group:
item_schema = copy.deepcopy(self.item_schema)
item_schema["env_group_key"] = key
@ -188,7 +202,7 @@ class DictMutableKeysEntity(EndpointEntity):
self.schema_data.get("highlight_content") or False
)
object_type = self.schema_data["object_type"]
object_type = self.schema_data.get("object_type") or {}
if not isinstance(object_type, dict):
# Backwards compatibility
object_type = {
@ -212,6 +226,12 @@ class DictMutableKeysEntity(EndpointEntity):
def schema_validations(self):
super(DictMutableKeysEntity, self).schema_validations()
if not self.schema_data.get("object_type"):
reason = (
"Modifiable dictionary must have specified `object_type`."
)
raise EntitySchemaError(self, reason)
# TODO Ability to store labels should be defined with different key
if self.collapsible_key and not self.file_item:
reason = (
@ -325,6 +345,15 @@ class DictMutableKeysEntity(EndpointEntity):
children_label_by_id = {}
metadata_labels = metadata.get(M_DYNAMIC_KEY_LABEL) or {}
for _key, _value in new_value.items():
if not KEY_REGEX.match(_key):
# Replace invalid characters with underscore
# - this is safety to not break already existing settings
_key = re.sub(
r"[^{}]+".format(KEY_ALLOWED_SYMBOLS),
"_",
_key
)
child_entity = self._add_key(_key)
child_entity.update_default_value(_value)
if using_project_overrides:

View file

@ -170,14 +170,32 @@ class ToolsEnumEntity(BaseEnumEntity):
valid_keys = set()
enum_items = []
for tool_group in system_settings_entity["tools"].values():
enabled_entity = tool_group.get("enabled")
if enabled_entity and not enabled_entity.value:
continue
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)
for variant_name in tool_group["variants"].keys():
enum_items.append({variant_name: variant_name})
valid_keys.add(variant_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.append({tool_name: tool_label})
valid_keys.add(tool_name)
return enum_items, valid_keys
def set_override_state(self, *args, **kwargs):

View file

@ -1,3 +1,6 @@
from pype.settings.constants import KEY_ALLOWED_SYMBOLS
class DefaultsNotDefined(Exception):
def __init__(self, obj):
msg = "Default values for object are not set. {}".format(obj.path)
@ -34,6 +37,14 @@ class RequiredKeyModified(KeyError):
super(RequiredKeyModified, self).__init__(msg.format(entity_path, key))
class InvalidKeySymbols(KeyError):
def __init__(self, entity_path, key):
msg = "{} - Invalid key \"{}\". Allowed symbols are {}"
super(InvalidKeySymbols, self).__init__(
msg.format(entity_path, key, KEY_ALLOWED_SYMBOLS)
)
class SchemaError(Exception):
pass

View file

@ -13,11 +13,15 @@ from .lib import (
get_studio_settings_schema,
get_project_settings_schema
)
from .exceptions import EntitySchemaError
from .exceptions import (
SchemaError,
InvalidKeySymbols
)
from pype.settings.constants import (
SYSTEM_SETTINGS_KEY,
PROJECT_SETTINGS_KEY,
PROJECT_ANATOMY_KEY
PROJECT_ANATOMY_KEY,
KEY_REGEX
)
from pype.settings.lib import (
@ -150,9 +154,13 @@ class RootEntity(BaseItemEntity):
"Root entity \"{}\" has child with `is_group`"
" attribute set to True but root can't save overrides."
).format(self.__class__.__name__)
raise EntitySchemaError(self, reason)
raise SchemaError(reason)
child_entity.schema_validations()
for key in self.non_gui_children.keys():
if not KEY_REGEX.match(key):
raise InvalidKeySymbols(self.path, key)
def get_entity_from_path(self, path):
"""Return system settings entity."""
raise NotImplementedError((

View file

@ -20,27 +20,27 @@
"children": [
{
"type": "text",
"key": "Create...",
"key": "create",
"label": "Create..."
},
{
"type": "text",
"key": "Publish...",
"key": "publish",
"label": "Publish..."
},
{
"type": "text",
"key": "Load...",
"key": "load",
"label": "Load..."
},
{
"type": "text",
"key": "Manage...",
"key": "manage",
"label": "Manage..."
},
{
"type": "text",
"key": "Build Workfile",
"key": "build_workfile",
"label": "Build Workfile"
}
]

View file

@ -29,12 +29,14 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "2020",
"host_name": "aftereffects"
"app_variant_label": "2020",
"app_variant": "2020",
"app_name": "aftereffects"
},
{
"host_version": "2021",
"host_name": "aftereffects"
"app_variant_label": "2021",
"app_variant": "2021",
"app_name": "aftereffects"
}
]
}

View file

@ -29,12 +29,14 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "2.90",
"host_name": "blender"
"app_variant_label": "2.83",
"app_variant": "2-83",
"app_name": "blender"
},
{
"host_version": "2.83",
"host_name": "blender"
"app_variant_label": "2.90",
"app_variant": "2-90",
"app_name": "blender"
}
]
}

View file

@ -29,14 +29,9 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "Local",
"host_name": "celation",
"multiplatform": false,
"multipath_executables": false
},
{
"host_version": "Publish",
"host_name": "celation",
"app_variant_label": "Local",
"app_variant": "Local",
"app_name": "celation",
"multiplatform": false,
"multipath_executables": false
}

View file

@ -28,8 +28,9 @@
"type": "schema_template",
"name": "template_host_variant",
"template_data": {
"host_version": "1.1",
"host_name": "djvview"
"app_variant_label": "1.1",
"app_variant": "1-1",
"app_name": "djvview"
}
}
]

View file

@ -29,12 +29,14 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "16",
"host_name": "fusion"
"app_variant_label": "16",
"app_variant": "16",
"app_name": "fusion"
},
{
"host_version": "9",
"host_name": "fusion"
"app_variant_label": "9",
"app_variant": "9",
"app_name": "fusion"
}
]
}

View file

@ -29,12 +29,14 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "20",
"host_name": "harmony"
"app_variant_label": "20",
"app_variant": "20",
"app_name": "harmony"
},
{
"host_version": "17",
"host_name": "harmony"
"app_variant_label": "17",
"app_variant": "17",
"app_name": "harmony"
}
]
}

View file

@ -29,16 +29,19 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "18.5",
"host_name": "houdini"
"app_variant_label": "18.5",
"app_variant": "18-5",
"app_name": "houdini"
},
{
"host_version": "18",
"host_name": "houdini"
"app_variant_label": "18",
"app_variant": "18",
"app_name": "houdini"
},
{
"host_version": "17",
"host_name": "houdini"
"app_variant_label": "17",
"app_variant": "17",
"app_name": "houdini"
}
]
}

View file

@ -29,16 +29,19 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "2020",
"host_name": "maya"
"app_variant_label": "2020",
"app_variant": "2020",
"app_name": "maya"
},
{
"host_version": "2019",
"host_name": "maya"
"app_variant_label": "2019",
"app_variant": "2019",
"app_name": "maya"
},
{
"host_version": "2018",
"host_name": "maya"
"app_variant_label": "2018",
"app_variant": "2018",
"app_name": "maya"
}
]
}

View file

@ -29,16 +29,19 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "2020",
"host_name": "mayabatch"
"app_variant_label": "2020",
"app_variant": "2020",
"app_name": "mayabatch"
},
{
"host_version": "2019",
"host_name": "mayabatch"
"app_variant_label": "2019",
"app_variant": "2019",
"app_name": "mayabatch"
},
{
"host_version": "2018",
"host_name": "mayabatch"
"app_variant_label": "2018",
"app_variant": "2018",
"app_name": "mayabatch"
}
]
}

View file

@ -29,12 +29,14 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "2020",
"host_name": "photoshop"
"app_variant_label": "2020",
"app_variant": "2020",
"app_name": "photoshop"
},
{
"host_version": "2021",
"host_name": "photoshop"
"app_variant_label": "2021",
"app_variant": "2021",
"app_name": "photoshop"
}
]
}

View file

@ -29,8 +29,9 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "16",
"host_name": "resolve"
"app_variant_label": "16",
"app_variant": "16",
"app_name": "resolve"
}
]
}

View file

@ -25,16 +25,19 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "Python 3.7",
"host_name": "python"
"app_variant": "python_3-7",
"app_variant_label": "Python 3.7",
"app_name": "python"
},
{
"host_version": "Python 2.7",
"host_name": "python"
"app_variant": "python_2-7",
"app_variant_label": "Python 2.7",
"app_name": "python"
},
{
"host_version": "Terminal",
"host_name": "terminal"
"app_variant": "terminal",
"app_variant_label": "Terminal",
"app_name": "terminal"
}
]
}

View file

@ -29,12 +29,14 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "Animation 11 (64bits)",
"host_name": "tvpaint"
"app_variant_label": "Animation 11 (64bits)",
"app_variant": "animation_11-64bits",
"app_name": "tvpaint"
},
{
"host_version": "Animation 11 (32bits)",
"host_name": "tvpaint"
"app_variant_label": "Animation 11 (32bits)",
"app_variant": "animation_11-32bits",
"app_name": "tvpaint"
}
]
}

View file

@ -29,8 +29,9 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "4.24",
"host_name": "unreal"
"app_variant": "4-24",
"app_variant_label": "4.24",
"app_name": "unreal"
}
]
}

View file

@ -7,8 +7,8 @@
},
{
"type": "dict",
"key": "{host_name}_{host_version}",
"label": "{host_version}",
"key": "{app_name}_{app_variant}",
"label": "{app_variant_label}",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
@ -78,7 +78,7 @@
"key": "environment",
"label": "Environment",
"type": "raw-json",
"env_group_key": "{host_name}_{host_version}"
"env_group_key": "{app_name}_{app_variant}"
}
]
}

View file

@ -30,24 +30,24 @@
"name": "template_host_variant",
"template_data": [
{
"host_version": "12.2",
"host_name": "{nuke_type}",
"multipath_executables": true
"app_variant": "12-2",
"app_variant_label": "12.2",
"app_name": "{nuke_type}"
},
{
"host_version": "12.0",
"host_name": "{nuke_type}",
"multipath_executables": true
"app_variant": "12-0",
"app_variant_label": "12.0",
"app_name": "{nuke_type}"
},
{
"host_version": "11.3",
"host_name": "{nuke_type}",
"multipath_executables": true
"app_variant": "11-3",
"app_variant_label": "11.3",
"app_name": "{nuke_type}"
},
{
"host_version": "11.2",
"host_name": "{nuke_type}",
"multipath_executables": true
"app_variant": "11-2",
"app_variant_label": "11.2",
"app_name": "{nuke_type}"
}
]
}

View file

@ -1,37 +1,35 @@
{
"key": "tools",
"type": "dict",
"label": "Tools",
"key": "tools",
"collapsible": true,
"is_file": true,
"children": [
{
"type": "schema",
"name": "schema_arnold"
},
{
"type": "schema",
"name": "schema_vray"
},
{
"type": "schema",
"name": "schema_yeti"
},
{
"type": "dict",
"key": "other",
"children": [
{
"type": "schema_template",
"name": "template_tool_variant",
"template_data": [
{
"tool_name": "othertools",
"tool_label": "Other Tools and Plugins"
"type": "dict-modifiable",
"label": "Tools",
"key": "tool_groups",
"collapsible_key": true,
"object_type": {
"type": "dict",
"children": [
{
"key": "environment",
"label": "Environments",
"type": "raw-json"
},
{
"type": "separator"
},
{
"type": "dict-modifiable",
"key": "variants",
"collapsible_key": true,
"object_type": {
"type": "raw-json"
}
]
}
]
}
]
}
}
]
}

View file

@ -1,29 +0,0 @@
{
"type": "dict",
"key": "mtoa",
"label": "Autodesk Arnold",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"key": "environment",
"label": "Environment (mtoa)",
"type": "raw-json",
"env_group_key": "mtoa"
},
{
"type": "schema_template",
"name": "template_tool_variant",
"template_data": [
{
"tool_label": "Arnold Versions"
}
]
}
]
}

View file

@ -1,29 +0,0 @@
{
"type": "dict",
"key": "vray",
"label": "Chaos Group Vray",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"key": "environment",
"label": "Environment",
"type": "raw-json",
"env_group_key": "vray"
},
{
"type": "schema_template",
"name": "template_tool_variant",
"template_data": [
{
"tool_label": "Vray Versions"
}
]
}
]
}

View file

@ -1,29 +0,0 @@
{
"type": "dict",
"key": "yeti",
"label": "Pergrine Labs Yeti",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"key": "environment",
"label": "Environment",
"type": "raw-json",
"env_group_key": "yeti"
},
{
"type": "schema_template",
"name": "template_tool_variant",
"template_data": [
{
"tool_label": "Yeti Versions"
}
]
}
]
}

View file

@ -1,11 +0,0 @@
[
{
"type": "dict-modifiable",
"key": "variants",
"label": "{tool_label}",
"value_is_env_group": true,
"object_type": {
"type": "raw-json"
}
}
]

View file

@ -12,6 +12,7 @@ from .lib import (
BTN_FIXED_SIZE,
CHILD_OFFSET
)
from pype.settings.constants import KEY_REGEX
def create_add_btn(parent):
@ -37,6 +38,7 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget):
self.collapsible_key = entity_widget.entity.collapsible_key
self.is_duplicated = False
self.key_is_valid = False
if self.collapsible_key:
self.create_collapsible_ui()
@ -86,6 +88,9 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget):
if self.is_duplicated:
return
if not self.key_is_valid:
return
key = self.key_input.text()
if key:
label = self.key_label_input.text()
@ -95,9 +100,10 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget):
def _on_key_change(self):
key = self.key_input.text()
self.key_is_valid = KEY_REGEX.match(key)
self.is_duplicated = self.entity_widget.is_key_duplicated(key)
key_input_state = ""
if self.is_duplicated:
if self.is_duplicated or not self.key_is_valid:
key_input_state = "invalid"
elif key != "":
key_input_state = "modified"
@ -157,6 +163,7 @@ class ModifiableDictItem(QtWidgets.QWidget):
self.ignore_input_changes = entity_widget.ignore_input_changes
self.is_key_duplicated = False
self.key_is_valid = False
self.is_required = False
self.origin_key = None
@ -334,7 +341,7 @@ class ModifiableDictItem(QtWidgets.QWidget):
else:
self._on_focus_lose()
if not self.is_key_duplicated:
if not self.is_key_duplicated and self.key_is_valid:
self.entity_widget.change_key(self.key_value(), self)
def set_key_label(self, key, label):
@ -382,11 +389,12 @@ class ModifiableDictItem(QtWidgets.QWidget):
def _on_key_change(self):
key = self.key_value()
self.key_is_valid = KEY_REGEX.match(key)
is_key_duplicated = self.entity_widget.validate_key_duplication(
self.temp_key, key, self
)
self.temp_key = key
if is_key_duplicated:
if is_key_duplicated or not self.key_is_valid:
return
if key:
@ -458,6 +466,7 @@ class ModifiableDictItem(QtWidgets.QWidget):
self.is_key_duplicated
or self.key_value() == ""
or self.child_invalid
or not self.key_is_valid
)
@property
@ -473,7 +482,11 @@ class ModifiableDictItem(QtWidgets.QWidget):
def update_style(self):
key_input_state = ""
if self.is_key_duplicated or self.key_value() == "":
if (
self.is_key_duplicated
or self.key_value() == ""
or not self.key_is_valid
):
key_input_state = "invalid"
elif self.is_key_modified():
key_input_state = "modified"
@ -752,15 +765,17 @@ class DictMutableKeysWidget(BaseWidget):
old_key_items.append(input_field)
if duplicated_items:
widget.set_is_key_duplicated(True)
for input_field in duplicated_items:
input_field.set_is_key_duplicated(True)
widget.set_is_key_duplicated(True)
else:
widget.set_is_key_duplicated(False)
if len(old_key_items) == 1:
for input_field in old_key_items:
input_field.set_is_key_duplicated(False)
input_field.set_key(old_key)
input_field.update_key_label()
self.trigger_hierarchical_style_update()
return bool(duplicated_items)