Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1608 from pypeclub/feature/1600-settings-ignore-k…
Browse files Browse the repository at this point in the history
…eys-in-referenced-schema
  • Loading branch information
mkolar authored Jun 1, 2021
2 parents c696003 + 027d0d4 commit 742260e
Showing 1 changed file with 80 additions and 16 deletions.
96 changes: 80 additions & 16 deletions openpype/settings/entities/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,109 @@
NOT_SET = type("NOT_SET", (), {"__bool__": lambda obj: False})()
OVERRIDE_VERSION = 1

DEFAULT_VALUES_KEY = "__default_values__"
TEMPLATE_METADATA_KEYS = (
DEFAULT_VALUES_KEY,
)

template_key_pattern = re.compile(r"(\{.*?[^{0]*\})")


def _pop_metadata_item(template):
found_idx = None
for idx, item in enumerate(template):
if not isinstance(item, dict):
continue

for key in TEMPLATE_METADATA_KEYS:
if key in item:
found_idx = idx
break

if found_idx is not None:
break

metadata_item = {}
if found_idx is not None:
metadata_item = template.pop(found_idx)
return metadata_item


def _fill_schema_template_data(
template, template_data, required_keys=None, missing_keys=None
template, template_data, skip_paths, required_keys=None, missing_keys=None
):
first = False
if required_keys is None:
first = True

if "skip_paths" in template_data:
skip_paths = template_data["skip_paths"]
if not isinstance(skip_paths, list):
skip_paths = [skip_paths]

# Cleanup skip paths (skip empty values)
skip_paths = [path for path in skip_paths if path]

required_keys = set()
missing_keys = set()

_template = []
default_values = {}
for item in template:
if isinstance(item, dict) and "__default_values__" in item:
default_values = item["__default_values__"]
else:
_template.append(item)
template = _template
# Copy template data as content may change
template = copy.deepcopy(template)

# Get metadata item from template
metadata_item = _pop_metadata_item(template)

# Check for default values for template data
default_values = metadata_item.get(DEFAULT_VALUES_KEY) or {}

for key, value in default_values.items():
if key not in template_data:
template_data[key] = value

# Store paths by first part if path
# - None value says that whole key should be skipped
skip_paths_by_first_key = {}
for path in skip_paths:
parts = path.split("/")
key = parts.pop(0)
if key not in skip_paths_by_first_key:
skip_paths_by_first_key[key] = []

value = "/".join(parts)
skip_paths_by_first_key[key].append(value or None)

if not template:
output = template

elif isinstance(template, list):
output = []
for item in template:
output.append(_fill_schema_template_data(
item, template_data, required_keys, missing_keys
))
# Get skip paths for children item
_skip_paths = []
if skip_paths_by_first_key and isinstance(item, dict):
# Check if this item should be skipped
key = item.get("key")
if key and key in skip_paths_by_first_key:
_skip_paths = skip_paths_by_first_key[key]
# Skip whole item if None is in skip paths value
if None in _skip_paths:
continue

output_item = _fill_schema_template_data(
item, template_data, _skip_paths, required_keys, missing_keys
)
output.append(output_item)

elif isinstance(template, dict):
output = {}
for key, value in template.items():
output[key] = _fill_schema_template_data(
value, template_data, required_keys, missing_keys
value, template_data, skip_paths, required_keys, missing_keys
)

elif isinstance(template, STRING_TYPE):
# TODO find much better way how to handle filling template data
template = template.replace("{{", "__dbcb__").replace("}}", "__decb__")
for replacement_string in template_key_pattern.findall(template):
key = str(replacement_string[1:-1])
required_keys.add(key)
Expand All @@ -76,7 +135,8 @@ def _fill_schema_template_data(
else:
# Only replace the key in string
template = template.replace(replacement_string, value)
output = template

output = template.replace("__dbcb__", "{").replace("__decb__", "}")

else:
output = template
Expand Down Expand Up @@ -105,11 +165,15 @@ def _fill_schema_template(child_data, schema_collection, schema_templates):
if isinstance(template_data, dict):
template_data = [template_data]

skip_paths = child_data.get("skip_paths") or []
if isinstance(skip_paths, STRING_TYPE):
skip_paths = [skip_paths]

output = []
for single_template_data in template_data:
try:
filled_child = _fill_schema_template_data(
template, single_template_data
template, single_template_data, skip_paths
)

except SchemaTemplateMissingKeys as exc:
Expand Down Expand Up @@ -166,7 +230,7 @@ def _fill_inner_schemas(schema_data, schema_collection, schema_templates):
schema_templates
)

elif child_type == "schema_template":
elif child_type in ("template", "schema_template"):
for filled_child in _fill_schema_template(
child, schema_collection, schema_templates
):
Expand Down

0 comments on commit 742260e

Please sign in to comment.