From b2aab371f44e4eaa837949d0d5e29898431f78b9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 28 May 2021 16:30:10 +0000 Subject: [PATCH 1/7] Create draft PR for #1600 From f7a61b341ac994a15e358b22ca8551ae04cd2156 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 28 May 2021 18:30:58 +0200 Subject: [PATCH 2/7] implemented function to pop metadata keys --- openpype/settings/entities/lib.py | 39 ++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/openpype/settings/entities/lib.py b/openpype/settings/entities/lib.py index ed3d7aed84e..521099c6c8a 100644 --- a/openpype/settings/entities/lib.py +++ b/openpype/settings/entities/lib.py @@ -17,9 +17,34 @@ 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 ): @@ -29,14 +54,12 @@ def _fill_schema_template_data( 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) + + metadata_item = _pop_metadata_item(template) + + default_values = metadata_item.get(DEFAULT_VALUES_KEY) or {} for key, value in default_values.items(): if key not in template_data: From 1cdbd39be1fc775f6bb89a7ed644a01bdcd551f1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 28 May 2021 18:31:35 +0200 Subject: [PATCH 3/7] template may be schema_template or just template --- openpype/settings/entities/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/entities/lib.py b/openpype/settings/entities/lib.py index 521099c6c8a..e3a9e7d7025 100644 --- a/openpype/settings/entities/lib.py +++ b/openpype/settings/entities/lib.py @@ -189,7 +189,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 ): From 6798b05546840a1563dcb284d6824b48fe6f60d2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 28 May 2021 18:38:40 +0200 Subject: [PATCH 4/7] load skip_paths from template definition --- openpype/settings/entities/lib.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/settings/entities/lib.py b/openpype/settings/entities/lib.py index e3a9e7d7025..32c1d61cb6f 100644 --- a/openpype/settings/entities/lib.py +++ b/openpype/settings/entities/lib.py @@ -128,6 +128,10 @@ 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: From 6d1bbb6a124e0fe02c0a29e88c6fff296f04070a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 28 May 2021 18:44:40 +0200 Subject: [PATCH 5/7] care about skip paths when processing template item --- openpype/settings/entities/lib.py | 42 ++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/openpype/settings/entities/lib.py b/openpype/settings/entities/lib.py index 32c1d61cb6f..94f18f4ecba 100644 --- a/openpype/settings/entities/lib.py +++ b/openpype/settings/entities/lib.py @@ -46,40 +46,70 @@ def _pop_metadata_item(template): 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 + + # Cleanup skip paths (skip empty values) + skip_paths = [path for path in skip_paths if path] + required_keys = set() missing_keys = set() # 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): @@ -136,7 +166,7 @@ def _fill_schema_template(child_data, schema_collection, schema_templates): 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: From 467a3969cb3cd6b1b44c52541054f7f7dff5d2dd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 28 May 2021 18:54:18 +0200 Subject: [PATCH 6/7] added ability to pass curly brackets in templates as labels --- openpype/settings/entities/lib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/settings/entities/lib.py b/openpype/settings/entities/lib.py index 94f18f4ecba..cee2d43b662 100644 --- a/openpype/settings/entities/lib.py +++ b/openpype/settings/entities/lib.py @@ -114,6 +114,7 @@ def _fill_schema_template_data( 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) @@ -129,7 +130,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 From 027d0d405351f2db80c04700e7c236f91999dba1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 1 Jun 2021 01:18:00 +0200 Subject: [PATCH 7/7] added ability to se skip paths in template data --- openpype/settings/entities/lib.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/settings/entities/lib.py b/openpype/settings/entities/lib.py index cee2d43b662..a5c61a9ddaf 100644 --- a/openpype/settings/entities/lib.py +++ b/openpype/settings/entities/lib.py @@ -52,6 +52,11 @@ def _fill_schema_template_data( 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]