diff --git a/biscd/biscd/models/yaml_serializable.py b/biscd/biscd/models/yaml_serializable.py index 61a089d..75072d1 100644 --- a/biscd/biscd/models/yaml_serializable.py +++ b/biscd/biscd/models/yaml_serializable.py @@ -81,25 +81,69 @@ class YamlSerializable(RecursiveProperty): return [] ymlsl_dicts = cls._get_all_from_file() for key, value in kwargs.items(): - # 'name' has to be evaluated separately; 'name' is the key of the entire object - if key == 'name': - ymlsl_dicts = [ymlsl_dict for ymlsl_dict in ymlsl_dicts - if [*ymlsl_dict][0] == value] - else: - # For other keys, filter out any item that does not contain a key, - # or that not match the key's value - ymlsl_dicts = [ymlsl_dict for ymlsl_dict in ymlsl_dicts - if next(iter(ymlsl_dict.values())).get(key, None) == value] - - # After each iteration: if no item is left, return None - if not any(ymlsl_dicts): - return [] + ymlsl_dicts = cls.filter_dicts(ymlsl_dicts, key, value) ymlsls = [] for ymlsl_dict in ymlsl_dicts: ymlsls.append(cls._from_dict(ymlsl_dict, 'name')) return ymlsls + @staticmethod + def filter_dicts(ymlsl_dicts, key, value): + # 'name' has to be evaluated separately; 'name' is the key of the entire object + if key == 'name': + return [ymlsl_dict for ymlsl_dict in ymlsl_dicts + if [*ymlsl_dict][0] == value] + + # For other keys, filter out any item that does not contain the key, or that not match + # the key's value + + # If key is recursive + if '__' in key: + return [ymlsl_dict for ymlsl_dict in ymlsl_dicts + if YamlSerializable.has_recursive_property( + list(ymlsl_dict.items())[0][1], key, value)] + + # If key is normal key + return [ymlsl_dict for ymlsl_dict in ymlsl_dicts + if next(iter(ymlsl_dict.values())).get(key, None) == value] + + @staticmethod + def has_recursive_property(dictionary, key, value): + elements = key.split('__') + for element in elements: + # If last element: check if last element equals value + if element is elements[-1]: + if isinstance(dictionary, list): + item = [item for item in dictionary if list(item.keys())[0] == element][0] + if item[element] == value: + return True + return False + element_in_dict = dictionary.get(element, None) + if isinstance(element_in_dict, list): + if value in element_in_dict: + return True + return False + if element_in_dict == value: + return True + return False + + # Else check if dictionary has element. If so, dictionary becomes element + if isinstance(dictionary, list): + item = [item for item in element_in_dict if list(item.keys())[0] == element][0] + if item[element] is not None: + dictionary = item[element] + continue + element_in_dict = dictionary.get(element, None) + if isinstance(dictionary, list): + if element in [list(item.keys())[0] for item in element_in_dict]: + continue + return False + if element_in_dict is None: + return False + dictionary = element_in_dict + return False + @classmethod def list_names(cls): ymlsls = cls._get_all_from_file()