mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2025-09-10 03:37:11 +02:00
Refactored code and implemented new childrens loading
This commit is contained in:
@@ -2,7 +2,7 @@ from pprint import pprint
|
||||
class ConfigurationResolver:
|
||||
"""
|
||||
A class to resolve `link` entries in a nested configuration structure.
|
||||
Supports navigation through dictionaries, lists, and `subitems`.
|
||||
Supports navigation through dictionaries, lists, and `children`.
|
||||
"""
|
||||
|
||||
def __init__(self, config):
|
||||
@@ -14,23 +14,58 @@ class ConfigurationResolver:
|
||||
"""
|
||||
self._recursive_resolve(self.config, self.config)
|
||||
|
||||
def __load_children(self,path):
|
||||
"""
|
||||
Check if explicitly children should be loaded and not parent
|
||||
"""
|
||||
return path.split('.').pop() == "children"
|
||||
|
||||
def _replace_in_dict_by_dict(self, dict_origine, old_key, new_dict):
|
||||
if old_key in dict_origine:
|
||||
# Entferne den alten Key
|
||||
old_value = dict_origine.pop(old_key)
|
||||
# Füge die neuen Key-Value-Paare hinzu
|
||||
dict_origine.update(new_dict)
|
||||
|
||||
def _replace_in_list_by_list(self, list_origine, old_element, new_elements):
|
||||
index = list_origine.index(old_element)
|
||||
list_origine[index:index+1] = new_elements
|
||||
|
||||
def _replace_element_in_list(self, list_origine, old_element, new_element):
|
||||
index = list_origine.index(old_element)
|
||||
list_origine[index] = new_element
|
||||
|
||||
def _recursive_resolve(self, current_config, root_config):
|
||||
"""
|
||||
Recursively resolves `link` entries in the configuration.
|
||||
"""
|
||||
if isinstance(current_config, dict):
|
||||
for key, value in list(current_config.items()):
|
||||
if key == "link":
|
||||
if key == "children":
|
||||
for item in value:
|
||||
if "link" in item:
|
||||
loaded_link = self._find_entry(root_config, item['link'].lower(), False)
|
||||
if isinstance(loaded_link, list):
|
||||
self._replace_in_list_by_list(value,item,loaded_link)
|
||||
else:
|
||||
self._replace_element_in_list(value,item,loaded_link)
|
||||
elif key == "link":
|
||||
try:
|
||||
target = self._find_entry(root_config, value.lower(), True)
|
||||
if isinstance(target, list) and len(target) > 2:
|
||||
target = self._find_entry(root_config, value.lower(), False)
|
||||
current_config.clear()
|
||||
current_config.update(target)
|
||||
if self.__load_children(value):
|
||||
loaded = self._find_entry(root_config, value.lower(), False)
|
||||
self._replace_in_dict_by_dict(
|
||||
current_config,key,loaded
|
||||
)
|
||||
else:
|
||||
loaded = self._find_entry(root_config, value.lower(), True)
|
||||
if isinstance(loaded, list) and len(loaded) > 2:
|
||||
loaded = self._find_entry(root_config, value.lower(), False)
|
||||
current_config.clear()
|
||||
current_config.update(loaded)
|
||||
except Exception as e:
|
||||
raise ValueError(
|
||||
f"Error resolving link '{value}': {str(e)}. "
|
||||
f"Current path: {key}, Current config: {current_config}"
|
||||
f"Current path: {key}, Current config: {current_config}" + (f", Loaded: {loaded}" if 'loaded' in locals() or 'loaded' in globals() else "")
|
||||
)
|
||||
else:
|
||||
self._recursive_resolve(value, root_config)
|
||||
@@ -38,9 +73,9 @@ class ConfigurationResolver:
|
||||
for item in current_config:
|
||||
self._recursive_resolve(item, root_config)
|
||||
|
||||
def _get_subitems(self,current):
|
||||
if isinstance(current, dict) and ("subitems" in current and current["subitems"]):
|
||||
current = current["subitems"]
|
||||
def _get_children(self,current):
|
||||
if isinstance(current, dict) and ("children" in current and current["children"]):
|
||||
current = current["children"]
|
||||
return current
|
||||
|
||||
def _find_by_name(self,current, part):
|
||||
@@ -49,33 +84,35 @@ class ConfigurationResolver:
|
||||
None
|
||||
)
|
||||
|
||||
def _find_entry(self, config, path, subitems):
|
||||
def _find_entry(self, config, path, children):
|
||||
"""
|
||||
Finds an entry in the configuration by a dot-separated path.
|
||||
Supports both dictionaries and lists with `subitems` navigation.
|
||||
Supports both dictionaries and lists with `children` navigation.
|
||||
"""
|
||||
parts = path.split('.')
|
||||
current = config
|
||||
for part in parts:
|
||||
if isinstance(current, list):
|
||||
# Look for a matching name in the list
|
||||
found = self._find_by_name(current,part)
|
||||
if found:
|
||||
print(
|
||||
f"Matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
|
||||
f"Current list: {current}"
|
||||
)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"No matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
|
||||
f"Current list: {current}"
|
||||
)
|
||||
current = found
|
||||
# If children explicit declared just load children
|
||||
if part != "children":
|
||||
# Look for a matching name in the list
|
||||
found = self._find_by_name(current,part)
|
||||
if found:
|
||||
current = found
|
||||
print(
|
||||
f"Matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
|
||||
f"Current list: {current}"
|
||||
)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"No matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
|
||||
f"Current list: {current}"
|
||||
)
|
||||
elif isinstance(current, dict):
|
||||
# Case-insensitive dictionary lookup
|
||||
key = next((k for k in current if k.lower() == part), None)
|
||||
if key is None:
|
||||
current = self._find_by_name(current["subitems"],part)
|
||||
current = self._find_by_name(current["children"],part)
|
||||
if not current:
|
||||
raise KeyError(
|
||||
f"Key '{part}' not found in dictionary. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
|
||||
@@ -89,8 +126,8 @@ class ConfigurationResolver:
|
||||
f"Invalid path segment '{part}'. Current type: {type(current)}. "
|
||||
f"Path so far: {' > '.join(parts[:parts.index(part)+1])}"
|
||||
)
|
||||
if subitems:
|
||||
current = self._get_subitems(current)
|
||||
if children:
|
||||
current = self._get_children(current)
|
||||
|
||||
return current
|
||||
|
||||
|
Reference in New Issue
Block a user