Merge branch 'develop' into bugfix/1421-resolve-fix-loading-clips-to-timeline

This commit is contained in:
Jakub Jezek 2021-05-05 16:49:44 +02:00
commit 7021ef5683
No known key found for this signature in database
GPG key ID: D8548FBF690B100A
161 changed files with 3778 additions and 1592 deletions

View file

@ -20,7 +20,7 @@
"harmony/20",
"photoshop/2021",
"aftereffects/2021",
"unreal/4-24"
"unreal/4-26"
],
"tools_env": []
}

View file

@ -21,8 +21,8 @@
"secondary_pool": "",
"group": "",
"department": "",
"limit_groups": {},
"use_gpu": true
"use_gpu": true,
"limit_groups": {}
},
"HarmonySubmitDeadline": {
"enabled": true,

View file

@ -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

View file

@ -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}"
}

View file

@ -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"
}
}
},

View file

@ -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": {

View file

@ -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")

View file

@ -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):

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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:

View file

@ -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"
}
},
{

View file

@ -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",

View file

@ -4,7 +4,6 @@
"key": "filters",
"label": "Publish GUI Filters",
"object_type": {
"type": "raw-json",
"label": "Plugins"
"type": "raw-json"
}
}

View file

@ -28,7 +28,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -28,7 +28,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -28,7 +28,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -28,7 +28,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -24,7 +24,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -28,7 +28,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -28,7 +28,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -29,7 +29,6 @@
"object_type": {
"type": "dict",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "schema_template",

View file

@ -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",

View file

@ -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):