mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge branch 'develop' into bugfix/1421-resolve-fix-loading-clips-to-timeline
This commit is contained in:
commit
7021ef5683
161 changed files with 3778 additions and 1592 deletions
|
|
@ -20,7 +20,7 @@
|
|||
"harmony/20",
|
||||
"photoshop/2021",
|
||||
"aftereffects/2021",
|
||||
"unreal/4-24"
|
||||
"unreal/4-26"
|
||||
],
|
||||
"tools_env": []
|
||||
}
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
"secondary_pool": "",
|
||||
"group": "",
|
||||
"department": "",
|
||||
"limit_groups": {},
|
||||
"use_gpu": true
|
||||
"use_gpu": true,
|
||||
"limit_groups": {}
|
||||
},
|
||||
"HarmonySubmitDeadline": {
|
||||
"enabled": true,
|
||||
|
|
|
|||
|
|
@ -73,8 +73,18 @@
|
|||
"enabled": true,
|
||||
"options": {
|
||||
"font_size": 42,
|
||||
"opacity": 1.0,
|
||||
"bg_opacity": 0.5,
|
||||
"font_color": [
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
255
|
||||
],
|
||||
"bg_color": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
127
|
||||
],
|
||||
"x_offset": 5,
|
||||
"y_offset": 5,
|
||||
"bg_padding": 5
|
||||
|
|
|
|||
|
|
@ -21,10 +21,20 @@
|
|||
"LoadClip": {
|
||||
"enabled": true,
|
||||
"families": [
|
||||
"render2d", "source", "plate", "render", "review"
|
||||
"render2d",
|
||||
"source",
|
||||
"plate",
|
||||
"render",
|
||||
"review"
|
||||
],
|
||||
"representations": [
|
||||
"exr", "dpx", "jpg", "jpeg", "png", "h264", "mov"
|
||||
"exr",
|
||||
"dpx",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"h264",
|
||||
"mov"
|
||||
],
|
||||
"clip_name_template": "{asset}_{subset}_{representation}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,11 +210,11 @@
|
|||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"13-0": "13.0 (Testing only)",
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2",
|
||||
"13-0": "13.0 (Testing only)"
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -354,11 +354,11 @@
|
|||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"13-0": "13.0 (Testing only)",
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2",
|
||||
"13-0": "13.0 (Testing only)"
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -496,11 +496,11 @@
|
|||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"13-0": "13.0 (Testing only)",
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2",
|
||||
"13-0": "13.0 (Testing only)"
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -640,11 +640,11 @@
|
|||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"13-0": "13.0 (Testing only)",
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2",
|
||||
"13-0": "13.0 (Testing only)"
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
{
|
||||
"studio_name": "Studio name",
|
||||
"studio_code": "stu",
|
||||
"admin_password": "",
|
||||
"environment": {
|
||||
"OPENPYPE_OCIO_CONFIG": "{STUDIO_SOFT}/OpenColorIO-Configs",
|
||||
"__environment_keys__": {
|
||||
"global": [
|
||||
"OPENPYPE_OCIO_CONFIG"
|
||||
]
|
||||
"global": []
|
||||
}
|
||||
},
|
||||
"openpype_path": {
|
||||
|
|
|
|||
|
|
@ -457,27 +457,18 @@ class BaseItemEntity(BaseEntity):
|
|||
pass
|
||||
|
||||
@property
|
||||
def can_discard_changes(self):
|
||||
"""Result defines if `discard_changes` will be processed.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
def _can_discard_changes(self):
|
||||
"""Defines if `discard_changes` will be processed."""
|
||||
return self.has_unsaved_changes
|
||||
|
||||
@property
|
||||
def can_add_to_studio_default(self):
|
||||
"""Result defines if `add_to_studio_default` will be processed.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
def _can_add_to_studio_default(self):
|
||||
"""Defines if `add_to_studio_default` will be processed."""
|
||||
if self._override_state is not OverrideState.STUDIO:
|
||||
return False
|
||||
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
|
||||
# Skip if entity is under group
|
||||
if self.group_item:
|
||||
if self.group_item is not None:
|
||||
return False
|
||||
|
||||
# Skip if is group and any children is already marked with studio
|
||||
|
|
@ -487,36 +478,24 @@ class BaseItemEntity(BaseEntity):
|
|||
return True
|
||||
|
||||
@property
|
||||
def can_remove_from_studio_default(self):
|
||||
"""Result defines if `remove_from_studio_default` can be triggered.
|
||||
|
||||
This can be also used as validation before the method is called.
|
||||
"""
|
||||
def _can_remove_from_studio_default(self):
|
||||
"""Defines if `remove_from_studio_default` can be processed."""
|
||||
if self._override_state is not OverrideState.STUDIO:
|
||||
return False
|
||||
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
|
||||
if not self.has_studio_override:
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def can_add_to_project_override(self):
|
||||
"""Result defines if `add_to_project_override` can be triggered.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
|
||||
def _can_add_to_project_override(self):
|
||||
"""Defines if `add_to_project_override` can be processed."""
|
||||
# Show only when project overrides are set
|
||||
if self._override_state is not OverrideState.PROJECT:
|
||||
return False
|
||||
|
||||
# Do not show on items under group item
|
||||
if self.group_item:
|
||||
if self.group_item is not None:
|
||||
return False
|
||||
|
||||
# Skip if already is marked to save project overrides
|
||||
|
|
@ -525,14 +504,8 @@ class BaseItemEntity(BaseEntity):
|
|||
return True
|
||||
|
||||
@property
|
||||
def can_remove_from_project_override(self):
|
||||
"""Result defines if `remove_from_project_override` can be triggered.
|
||||
|
||||
This can be also used as validation before the method is called.
|
||||
"""
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
|
||||
def _can_remove_from_project_override(self):
|
||||
"""Defines if `remove_from_project_override` can be processed."""
|
||||
if self._override_state is not OverrideState.PROJECT:
|
||||
return False
|
||||
|
||||
|
|
@ -544,6 +517,54 @@ class BaseItemEntity(BaseEntity):
|
|||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def can_trigger_discard_changes(self):
|
||||
"""Defines if can trigger `discard_changes`.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
return self._can_discard_changes
|
||||
|
||||
@property
|
||||
def can_trigger_add_to_studio_default(self):
|
||||
"""Defines if can trigger `add_to_studio_default`.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
return self._can_add_to_studio_default
|
||||
|
||||
@property
|
||||
def can_trigger_remove_from_studio_default(self):
|
||||
"""Defines if can trigger `remove_from_studio_default`.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
return self._can_remove_from_studio_default
|
||||
|
||||
@property
|
||||
def can_trigger_add_to_project_override(self):
|
||||
"""Defines if can trigger `add_to_project_override`.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
return self._can_add_to_project_override
|
||||
|
||||
@property
|
||||
def can_trigger_remove_from_project_override(self):
|
||||
"""Defines if can trigger `remove_from_project_override`.
|
||||
|
||||
Also can be used as validation before the method is called.
|
||||
"""
|
||||
if self.is_dynamic_item or self.is_in_dynamic_item:
|
||||
return False
|
||||
return self._can_remove_from_project_override
|
||||
|
||||
def discard_changes(self, on_change_trigger=None):
|
||||
"""Discard changes on entity and it's children.
|
||||
|
||||
|
|
@ -568,7 +589,7 @@ class BaseItemEntity(BaseEntity):
|
|||
"""
|
||||
initialized = False
|
||||
if on_change_trigger is None:
|
||||
if not self.can_discard_changes:
|
||||
if not self.can_trigger_discard_changes:
|
||||
return
|
||||
|
||||
initialized = True
|
||||
|
|
@ -588,7 +609,7 @@ class BaseItemEntity(BaseEntity):
|
|||
def add_to_studio_default(self, on_change_trigger=None):
|
||||
initialized = False
|
||||
if on_change_trigger is None:
|
||||
if not self.can_add_to_studio_default:
|
||||
if not self.can_trigger_add_to_studio_default:
|
||||
return
|
||||
|
||||
initialized = True
|
||||
|
|
@ -625,7 +646,7 @@ class BaseItemEntity(BaseEntity):
|
|||
"""
|
||||
initialized = False
|
||||
if on_change_trigger is None:
|
||||
if not self.can_remove_from_studio_default:
|
||||
if not self.can_trigger_remove_from_studio_default:
|
||||
return
|
||||
|
||||
initialized = True
|
||||
|
|
@ -649,7 +670,7 @@ class BaseItemEntity(BaseEntity):
|
|||
def add_to_project_override(self, on_change_trigger=None):
|
||||
initialized = False
|
||||
if on_change_trigger is None:
|
||||
if not self.can_add_to_project_override:
|
||||
if not self.can_trigger_add_to_project_override:
|
||||
return
|
||||
|
||||
initialized = True
|
||||
|
|
@ -689,7 +710,7 @@ class BaseItemEntity(BaseEntity):
|
|||
|
||||
initialized = False
|
||||
if on_change_trigger is None:
|
||||
if not self.can_remove_from_project_override:
|
||||
if not self.can_trigger_remove_from_project_override:
|
||||
return
|
||||
initialized = True
|
||||
on_change_trigger = []
|
||||
|
|
@ -775,7 +796,8 @@ class ItemEntity(BaseItemEntity):
|
|||
# Group item reference
|
||||
if self.parent.is_group:
|
||||
self.group_item = self.parent
|
||||
elif self.parent.group_item:
|
||||
|
||||
elif self.parent.group_item is not None:
|
||||
self.group_item = self.parent.group_item
|
||||
|
||||
self.key = self.schema_data.get("key")
|
||||
|
|
|
|||
|
|
@ -353,6 +353,20 @@ class DictImmutableKeysEntity(ItemEntity):
|
|||
for key in METADATA_KEYS:
|
||||
if key in value:
|
||||
metadata[key] = value.pop(key)
|
||||
|
||||
old_metadata = metadata.get(M_OVERRIDEN_KEY)
|
||||
if old_metadata:
|
||||
old_metadata_set = set(old_metadata)
|
||||
new_metadata = []
|
||||
for key in self.non_gui_children.keys():
|
||||
if key in old_metadata:
|
||||
new_metadata.append(key)
|
||||
old_metadata_set.remove(key)
|
||||
|
||||
for key in old_metadata_set:
|
||||
new_metadata.append(key)
|
||||
metadata[M_OVERRIDEN_KEY] = new_metadata
|
||||
|
||||
return value, metadata
|
||||
|
||||
def update_default_value(self, value):
|
||||
|
|
@ -458,6 +472,9 @@ class DictImmutableKeysEntity(ItemEntity):
|
|||
for child_obj in self.non_gui_children.values():
|
||||
child_obj.add_to_studio_default(on_change_trigger)
|
||||
self._ignore_child_changes = False
|
||||
|
||||
self._update_current_metadata()
|
||||
|
||||
self.parent.on_child_change(self)
|
||||
|
||||
def _remove_from_studio_default(self, on_change_trigger):
|
||||
|
|
@ -471,6 +488,9 @@ class DictImmutableKeysEntity(ItemEntity):
|
|||
for child_obj in self.non_gui_children.values():
|
||||
child_obj.add_to_project_override(_on_change_trigger)
|
||||
self._ignore_child_changes = False
|
||||
|
||||
self._update_current_metadata()
|
||||
|
||||
self.parent.on_child_change(self)
|
||||
|
||||
def _remove_from_project_override(self, on_change_trigger):
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
if self.value_is_env_group:
|
||||
self.item_schema["env_group_key"] = ""
|
||||
|
||||
if not self.group_item:
|
||||
if self.group_item is None:
|
||||
self.is_group = True
|
||||
|
||||
def schema_validations(self):
|
||||
|
|
@ -251,8 +251,18 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
)
|
||||
raise EntitySchemaError(self, reason)
|
||||
|
||||
for child_obj in self.children_by_key.values():
|
||||
child_obj.schema_validations()
|
||||
# Validate object type schema
|
||||
child_validated = False
|
||||
for child_entity in self.children_by_key.values():
|
||||
child_entity.schema_validations()
|
||||
child_validated = True
|
||||
break
|
||||
|
||||
if not child_validated:
|
||||
key = "__tmp__"
|
||||
tmp_child = self._add_key(key)
|
||||
tmp_child.schema_validations()
|
||||
self.children_by_key.pop(key)
|
||||
|
||||
def get_child_path(self, child_obj):
|
||||
result_key = None
|
||||
|
|
@ -277,21 +287,24 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
|
||||
self.on_change()
|
||||
|
||||
def _metadata_for_current_state(self):
|
||||
def _get_metadata_for_state(self, state):
|
||||
if (
|
||||
self._override_state is OverrideState.PROJECT
|
||||
state is OverrideState.PROJECT
|
||||
and self._project_override_value is not NOT_SET
|
||||
):
|
||||
return self._project_override_metadata
|
||||
|
||||
if (
|
||||
self._override_state >= OverrideState.STUDIO
|
||||
state >= OverrideState.STUDIO
|
||||
and self._studio_override_value is not NOT_SET
|
||||
):
|
||||
return self._studio_override_metadata
|
||||
|
||||
return self._default_metadata
|
||||
|
||||
def _metadata_for_current_state(self):
|
||||
return self._get_metadata_for_state(self._override_state)
|
||||
|
||||
def set_override_state(self, state):
|
||||
# Trigger override state change of root if is not same
|
||||
if self.root_item.override_state is not state:
|
||||
|
|
@ -519,6 +532,9 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
self.had_project_override = value is not NOT_SET
|
||||
|
||||
def _discard_changes(self, on_change_trigger):
|
||||
if not self._can_discard_changes:
|
||||
return
|
||||
|
||||
self.set_override_state(self._override_state)
|
||||
on_change_trigger.append(self.on_change)
|
||||
|
||||
|
|
@ -527,6 +543,9 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
self.on_change()
|
||||
|
||||
def _remove_from_studio_default(self, on_change_trigger):
|
||||
if not self._can_remove_from_studio_default:
|
||||
return
|
||||
|
||||
value = self._default_value
|
||||
if value is NOT_SET:
|
||||
value = self.value_on_not_set
|
||||
|
|
@ -536,13 +555,23 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
|
||||
# Simulate `clear` method without triggering value change
|
||||
for key in tuple(self.children_by_key.keys()):
|
||||
child_obj = self.children_by_key.pop(key)
|
||||
self.children_by_key.pop(key)
|
||||
|
||||
metadata = self._get_metadata_for_state(OverrideState.DEFAULTS)
|
||||
metadata_labels = metadata.get(M_DYNAMIC_KEY_LABEL) or {}
|
||||
children_label_by_id = {}
|
||||
|
||||
# Create new children
|
||||
for _key, _value in new_value.items():
|
||||
child_obj = self._add_key(_key)
|
||||
child_obj.update_default_value(_value)
|
||||
child_obj.set_override_state(self._override_state)
|
||||
child_entity = self._add_key(_key)
|
||||
child_entity.update_default_value(_value)
|
||||
label = metadata_labels.get(_key)
|
||||
if label:
|
||||
children_label_by_id[child_entity.id] = label
|
||||
|
||||
child_entity.set_override_state(self._override_state)
|
||||
|
||||
self.children_label_by_id = children_label_by_id
|
||||
|
||||
self._ignore_child_changes = False
|
||||
|
||||
|
|
@ -555,10 +584,7 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
self.on_change()
|
||||
|
||||
def _remove_from_project_override(self, on_change_trigger):
|
||||
if self._override_state is not OverrideState.PROJECT:
|
||||
return
|
||||
|
||||
if not self.has_project_override:
|
||||
if not self._can_remove_from_project_override:
|
||||
return
|
||||
|
||||
if self._has_studio_override:
|
||||
|
|
@ -574,15 +600,26 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
|
||||
# Simulate `clear` method without triggering value change
|
||||
for key in tuple(self.children_by_key.keys()):
|
||||
child_obj = self.children_by_key.pop(key)
|
||||
self.children_by_key.pop(key)
|
||||
|
||||
metadata = self._get_metadata_for_state(OverrideState.STUDIO)
|
||||
metadata_labels = metadata.get(M_DYNAMIC_KEY_LABEL) or {}
|
||||
children_label_by_id = {}
|
||||
|
||||
# Create new children
|
||||
for _key, _value in new_value.items():
|
||||
child_obj = self._add_key(_key)
|
||||
child_obj.update_default_value(_value)
|
||||
child_entity = self._add_key(_key)
|
||||
child_entity.update_default_value(_value)
|
||||
if self._has_studio_override:
|
||||
child_obj.update_studio_value(_value)
|
||||
child_obj.set_override_state(self._override_state)
|
||||
child_entity.update_studio_value(_value)
|
||||
|
||||
label = metadata_labels.get(_key)
|
||||
if label:
|
||||
children_label_by_id[child_entity.id] = label
|
||||
|
||||
child_entity.set_override_state(self._override_state)
|
||||
|
||||
self.children_label_by_id = children_label_by_id
|
||||
|
||||
self._ignore_child_changes = False
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class EndpointEntity(ItemEntity):
|
|||
super(EndpointEntity, self).__init__(*args, **kwargs)
|
||||
|
||||
if (
|
||||
not (self.group_item or self.is_group)
|
||||
not (self.group_item is not None or self.is_group)
|
||||
and not (self.is_dynamic_item or self.is_in_dynamic_item)
|
||||
):
|
||||
self.is_group = True
|
||||
|
|
@ -251,6 +251,9 @@ class InputEntity(EndpointEntity):
|
|||
self._current_value = copy.deepcopy(value)
|
||||
|
||||
def _discard_changes(self, on_change_trigger=None):
|
||||
if not self._can_discard_changes:
|
||||
return
|
||||
|
||||
self._value_is_modified = False
|
||||
if self._override_state >= OverrideState.PROJECT:
|
||||
self._has_project_override = self.had_project_override
|
||||
|
|
@ -286,6 +289,9 @@ class InputEntity(EndpointEntity):
|
|||
self.on_change()
|
||||
|
||||
def _remove_from_studio_default(self, on_change_trigger):
|
||||
if not self._can_remove_from_studio_default:
|
||||
return
|
||||
|
||||
value = self._default_value
|
||||
if value is NOT_SET:
|
||||
value = self.value_on_not_set
|
||||
|
|
@ -301,10 +307,7 @@ class InputEntity(EndpointEntity):
|
|||
self.on_change()
|
||||
|
||||
def _remove_from_project_override(self, on_change_trigger):
|
||||
if self._override_state is not OverrideState.PROJECT:
|
||||
return
|
||||
|
||||
if not self._has_project_override:
|
||||
if not self._can_remove_from_project_override:
|
||||
return
|
||||
|
||||
self._has_project_override = False
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class PathEntity(ItemEntity):
|
|||
return self.child_obj.items()
|
||||
|
||||
def _item_initalization(self):
|
||||
if not self.group_item and not self.is_group:
|
||||
if self.group_item is None and not self.is_group:
|
||||
self.is_group = True
|
||||
|
||||
self.multiplatform = self.schema_data.get("multiplatform", False)
|
||||
|
|
@ -199,7 +199,7 @@ class ListStrictEntity(ItemEntity):
|
|||
|
||||
# GUI attribute
|
||||
self.is_horizontal = self.schema_data.get("horizontal", True)
|
||||
if not self.group_item and not self.is_group:
|
||||
if self.group_item is None and not self.is_group:
|
||||
self.is_group = True
|
||||
|
||||
def schema_validations(self):
|
||||
|
|
@ -453,4 +453,5 @@ class ListStrictEntity(ItemEntity):
|
|||
|
||||
def reset_callbacks(self):
|
||||
super(ListStrictEntity, self).reset_callbacks()
|
||||
self.child_obj.reset_callbacks()
|
||||
for child_obj in self.children:
|
||||
child_obj.reset_callbacks()
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ class ListEntity(EndpointEntity):
|
|||
)
|
||||
|
||||
def append(self, item):
|
||||
child_obj = self._add_new_item()
|
||||
child_obj.set_override_state(self._override_state)
|
||||
child_obj = self.add_new_item(trigger_change=False)
|
||||
child_obj.set(item)
|
||||
self.on_change()
|
||||
|
||||
|
|
@ -92,8 +91,7 @@ class ListEntity(EndpointEntity):
|
|||
raise ValueError("ListEntity.remove(x): x not in ListEntity")
|
||||
|
||||
def insert(self, idx, item):
|
||||
child_obj = self._add_new_item(idx)
|
||||
child_obj.set_override_state(self._override_state)
|
||||
child_obj = self.add_new_item(idx, trigger_change=False)
|
||||
child_obj.set(item)
|
||||
self.on_change()
|
||||
|
||||
|
|
@ -105,10 +103,16 @@ class ListEntity(EndpointEntity):
|
|||
self.children.insert(idx, child_obj)
|
||||
return child_obj
|
||||
|
||||
def add_new_item(self, idx=None):
|
||||
def add_new_item(self, idx=None, trigger_change=True):
|
||||
child_obj = self._add_new_item(idx)
|
||||
child_obj.set_override_state(self._override_state)
|
||||
self.on_change()
|
||||
if self._override_state is OverrideState.STUDIO:
|
||||
child_obj.add_to_studio_default([])
|
||||
elif self._override_state is OverrideState.PROJECT:
|
||||
child_obj.add_to_project_default([])
|
||||
|
||||
if trigger_change:
|
||||
self.on_change()
|
||||
return child_obj
|
||||
|
||||
def swap_items(self, item_1, item_2):
|
||||
|
|
@ -144,7 +148,7 @@ class ListEntity(EndpointEntity):
|
|||
item_schema = {"type": item_schema}
|
||||
self.item_schema = item_schema
|
||||
|
||||
if not self.group_item:
|
||||
if self.group_item is None:
|
||||
self.is_group = True
|
||||
|
||||
# Value that was set on set_override_state
|
||||
|
|
@ -167,8 +171,18 @@ class ListEntity(EndpointEntity):
|
|||
)
|
||||
raise EntitySchemaError(self, reason)
|
||||
|
||||
for child_obj in self.children:
|
||||
child_obj.schema_validations()
|
||||
# Validate object type schema
|
||||
child_validated = False
|
||||
for child_entity in self.children:
|
||||
child_entity.schema_validations()
|
||||
child_validated = True
|
||||
break
|
||||
|
||||
if not child_validated:
|
||||
idx = 0
|
||||
tmp_child = self._add_new_item(idx)
|
||||
tmp_child.schema_validations()
|
||||
self.children.pop(idx)
|
||||
|
||||
def get_child_path(self, child_obj):
|
||||
result_idx = None
|
||||
|
|
@ -343,7 +357,7 @@ class ListEntity(EndpointEntity):
|
|||
return output
|
||||
|
||||
def _discard_changes(self, on_change_trigger):
|
||||
if self._override_state is OverrideState.NOT_DEFINED:
|
||||
if not self._can_discard_changes:
|
||||
return
|
||||
|
||||
not_set = object()
|
||||
|
|
@ -405,7 +419,7 @@ class ListEntity(EndpointEntity):
|
|||
self.on_change()
|
||||
|
||||
def _remove_from_studio_default(self, on_change_trigger):
|
||||
if self._override_state is not OverrideState.STUDIO:
|
||||
if not self._can_remove_from_studio_default:
|
||||
return
|
||||
|
||||
value = self._default_value
|
||||
|
|
@ -433,10 +447,7 @@ class ListEntity(EndpointEntity):
|
|||
self.on_change()
|
||||
|
||||
def _remove_from_project_override(self, on_change_trigger):
|
||||
if self._override_state is not OverrideState.PROJECT:
|
||||
return
|
||||
|
||||
if not self.has_project_override:
|
||||
if not self._can_remove_from_project_override:
|
||||
return
|
||||
|
||||
if self._has_studio_override:
|
||||
|
|
|
|||
|
|
@ -247,8 +247,7 @@
|
|||
"label": "Used in plugins",
|
||||
"object_type": {
|
||||
"type": "text",
|
||||
"key": "pluginClass",
|
||||
"label": "Plugin Class"
|
||||
"key": "pluginClass"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -295,8 +294,7 @@
|
|||
"label": "Used in plugins",
|
||||
"object_type": {
|
||||
"type": "text",
|
||||
"key": "pluginClass",
|
||||
"label": "Plugin Class"
|
||||
"key": "pluginClass"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -301,20 +301,24 @@
|
|||
"minimum": 0
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"key": "opacity",
|
||||
"label": "Font opacity",
|
||||
"decimal": 2,
|
||||
"maximum": 1,
|
||||
"minimum": 0
|
||||
"type": "schema_template",
|
||||
"name": "template_rgba_color",
|
||||
"template_data": [
|
||||
{
|
||||
"label": "Font Color",
|
||||
"name": "font_color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"key": "bg_opacity",
|
||||
"label": "Background opacity",
|
||||
"decimal": 2,
|
||||
"maximum": 1,
|
||||
"minimum": 0
|
||||
"type": "schema_template",
|
||||
"name": "template_rgba_color",
|
||||
"template_data": [
|
||||
{
|
||||
"label": "Background Color",
|
||||
"name": "bg_color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
"key": "filters",
|
||||
"label": "Publish GUI Filters",
|
||||
"object_type": {
|
||||
"type": "raw-json",
|
||||
"label": "Plugins"
|
||||
"type": "raw-json"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,18 @@
|
|||
{
|
||||
"type": "splitter"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "This is <b>NOT a securely stored password!</b>. It only acts as a simple barrier to stop users from accessing studio wide settings."
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "admin_password",
|
||||
"label": "Admin password"
|
||||
},
|
||||
{
|
||||
"type": "splitter"
|
||||
},
|
||||
{
|
||||
"key": "environment",
|
||||
"label": "Environment",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ from .constants import (
|
|||
SYSTEM_SETTINGS_KEY,
|
||||
PROJECT_SETTINGS_KEY,
|
||||
PROJECT_ANATOMY_KEY,
|
||||
LOCAL_SETTING_KEY
|
||||
LOCAL_SETTING_KEY,
|
||||
M_OVERRIDEN_KEY
|
||||
)
|
||||
from .lib import load_json_file
|
||||
|
||||
|
|
@ -167,6 +168,7 @@ class CacheValues:
|
|||
|
||||
class MongoSettingsHandler(SettingsHandler):
|
||||
"""Settings handler that use mongo for storing and loading of settings."""
|
||||
global_general_keys = ("openpype_path", "admin_password")
|
||||
|
||||
def __init__(self):
|
||||
# Get mongo connection
|
||||
|
|
@ -225,13 +227,106 @@ class MongoSettingsHandler(SettingsHandler):
|
|||
self._prepare_project_settings_keys()
|
||||
return self._attribute_keys
|
||||
|
||||
def _prepare_global_settings(self, data):
|
||||
def _extract_global_settings(self, data):
|
||||
"""Extract global settings data from system settings overrides.
|
||||
|
||||
This is now limited to "general" key in system settings which must be
|
||||
set as group in schemas.
|
||||
|
||||
Returns:
|
||||
dict: Global settings extracted from system settings data.
|
||||
"""
|
||||
output = {}
|
||||
# Add "openpype_path" key to global settings if is set
|
||||
if "general" in data and "openpype_path" in data["general"]:
|
||||
output["openpype_path"] = data["general"]["openpype_path"]
|
||||
if "general" not in data:
|
||||
return output
|
||||
|
||||
general_data = data["general"]
|
||||
|
||||
# Add predefined keys to global settings if are set
|
||||
for key in self.global_general_keys:
|
||||
if key not in general_data:
|
||||
continue
|
||||
# Pop key from values
|
||||
output[key] = general_data.pop(key)
|
||||
# Pop key from overriden metadata
|
||||
if (
|
||||
M_OVERRIDEN_KEY in general_data
|
||||
and key in general_data[M_OVERRIDEN_KEY]
|
||||
):
|
||||
general_data[M_OVERRIDEN_KEY].remove(key)
|
||||
return output
|
||||
|
||||
def _apply_global_settings(
|
||||
self, system_settings_document, globals_document
|
||||
):
|
||||
"""Apply global settings data to system settings.
|
||||
|
||||
Applification is skipped if document with global settings is not
|
||||
available or does not have set data in.
|
||||
|
||||
System settings document is "faked" like it exists if global document
|
||||
has set values.
|
||||
|
||||
Args:
|
||||
system_settings_document (dict): System settings document from
|
||||
MongoDB.
|
||||
globals_document (dict): Global settings document from MongoDB.
|
||||
|
||||
Returns:
|
||||
Merged document which has applied global settings data.
|
||||
"""
|
||||
# Skip if globals document is not available
|
||||
if (
|
||||
not globals_document
|
||||
or "data" not in globals_document
|
||||
or not globals_document["data"]
|
||||
):
|
||||
return system_settings_document
|
||||
|
||||
globals_data = globals_document["data"]
|
||||
# Check if data contain any key from predefined keys
|
||||
any_key_found = False
|
||||
if globals_data:
|
||||
for key in self.global_general_keys:
|
||||
if key in globals_data:
|
||||
any_key_found = True
|
||||
break
|
||||
|
||||
# Skip if any key from predefined key was not found in globals
|
||||
if not any_key_found:
|
||||
return system_settings_document
|
||||
|
||||
# "Fake" system settings document if document does not exist
|
||||
# - global settings document may exist but system settings not yet
|
||||
if not system_settings_document:
|
||||
system_settings_document = {}
|
||||
|
||||
if "data" in system_settings_document:
|
||||
system_settings_data = system_settings_document["data"]
|
||||
else:
|
||||
system_settings_data = {}
|
||||
system_settings_document["data"] = system_settings_data
|
||||
|
||||
if "general" in system_settings_data:
|
||||
system_general = system_settings_data["general"]
|
||||
else:
|
||||
system_general = {}
|
||||
system_settings_data["general"] = system_general
|
||||
|
||||
overriden_keys = system_general.get(M_OVERRIDEN_KEY) or []
|
||||
for key in self.global_general_keys:
|
||||
if key not in globals_data:
|
||||
continue
|
||||
|
||||
system_general[key] = globals_data[key]
|
||||
if key not in overriden_keys:
|
||||
overriden_keys.append(key)
|
||||
|
||||
if overriden_keys:
|
||||
system_general[M_OVERRIDEN_KEY] = overriden_keys
|
||||
|
||||
return system_settings_document
|
||||
|
||||
def save_studio_settings(self, data):
|
||||
"""Save studio overrides of system settings.
|
||||
|
||||
|
|
@ -243,23 +338,29 @@ class MongoSettingsHandler(SettingsHandler):
|
|||
Args:
|
||||
data(dict): Data of studio overrides with override metadata.
|
||||
"""
|
||||
# Store system settings
|
||||
# Update cache
|
||||
self.system_settings_cache.update_data(data)
|
||||
|
||||
# Get copy of just updated cache
|
||||
system_settings_data = self.system_settings_cache.data_copy()
|
||||
|
||||
# Extract global settings from system settings
|
||||
global_settings = self._extract_global_settings(
|
||||
system_settings_data
|
||||
)
|
||||
|
||||
# Store system settings
|
||||
self.collection.replace_one(
|
||||
{
|
||||
"type": SYSTEM_SETTINGS_KEY
|
||||
},
|
||||
{
|
||||
"type": SYSTEM_SETTINGS_KEY,
|
||||
"data": self.system_settings_cache.data
|
||||
"data": system_settings_data
|
||||
},
|
||||
upsert=True
|
||||
)
|
||||
|
||||
# Get global settings from system settings
|
||||
global_settings = self._prepare_global_settings(
|
||||
self.system_settings_cache.data
|
||||
)
|
||||
# Store global settings
|
||||
self.collection.replace_one(
|
||||
{
|
||||
|
|
@ -418,11 +519,27 @@ class MongoSettingsHandler(SettingsHandler):
|
|||
def get_studio_system_settings_overrides(self):
|
||||
"""Studio overrides of system settings."""
|
||||
if self.system_settings_cache.is_outdated:
|
||||
document = self.collection.find_one({
|
||||
"type": SYSTEM_SETTINGS_KEY
|
||||
system_settings_document = None
|
||||
globals_document = None
|
||||
docs = self.collection.find({
|
||||
# Use `$or` as system settings may have more filters in future
|
||||
"$or": [
|
||||
{"type": GLOBAL_SETTINGS_KEY},
|
||||
{"type": SYSTEM_SETTINGS_KEY},
|
||||
]
|
||||
})
|
||||
for doc in docs:
|
||||
doc_type = doc["type"]
|
||||
if doc_type == GLOBAL_SETTINGS_KEY:
|
||||
globals_document = doc
|
||||
elif doc_type == SYSTEM_SETTINGS_KEY:
|
||||
system_settings_document = doc
|
||||
|
||||
self.system_settings_cache.update_from_document(document)
|
||||
merged_document = self._apply_global_settings(
|
||||
system_settings_document, globals_document
|
||||
)
|
||||
|
||||
self.system_settings_cache.update_from_document(merged_document)
|
||||
return self.system_settings_cache.data_copy()
|
||||
|
||||
def _get_project_settings_overrides(self, project_name):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue