mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2025-06-28 23:55:31 +02:00
Compare commits
6 Commits
96ab80eaf2
...
1629d9728d
Author | SHA1 | Date | |
---|---|---|---|
1629d9728d | |||
268c2eb452 | |||
cdfefe5a63 | |||
e2aee76f54 | |||
35815ce5aa | |||
166055422e |
@ -4,7 +4,6 @@ import requests
|
||||
import hashlib
|
||||
import yaml
|
||||
from utils.configuration_resolver import ConfigurationResolver
|
||||
from pprint import pprint
|
||||
from utils.cache_manager import CacheManager
|
||||
|
||||
# Initialize the CacheManager
|
||||
@ -35,9 +34,6 @@ FLASK_ENV = os.getenv("FLASK_ENV", "production")
|
||||
def reload_config_in_dev():
|
||||
if FLASK_ENV == "development":
|
||||
load_config(app)
|
||||
print("DEVELOPMENT ENVIRONMENT")
|
||||
else:
|
||||
print("PRODUCTIVE ENVIRONMENT")
|
||||
|
||||
# Cache the icons
|
||||
for card in app.config["cards"]:
|
||||
|
389
app/config.yaml
389
app/config.yaml
@ -75,7 +75,6 @@ cards:
|
||||
I deliver expert consulting services. Currently training for my Private Pilot
|
||||
License, I specialize in guiding clients through aviation regulations, safety
|
||||
standards, and operational efficiency.
|
||||
url:
|
||||
link_text: Website under construction
|
||||
- icon:
|
||||
source: https://cloud.veen.world/s/logo_hunter_512x512/download
|
||||
@ -84,7 +83,6 @@ cards:
|
||||
walks, survival trainings, and photo expeditions, merging ecological knowledge
|
||||
with nature respect. My goal is to foster sustainable conservation and enhance
|
||||
appreciation for the natural world through responsible practices.
|
||||
url:
|
||||
link_text: Website under construction
|
||||
- icon:
|
||||
source: https://cloud.veen.world/s/logo_diver_512x512/download
|
||||
@ -93,7 +91,6 @@ cards:
|
||||
diving instruction, underwater photography, and guided dive tours. My experience
|
||||
ensures safe and enriching underwater adventures, highlighting marine conservation
|
||||
and the wonders of aquatic ecosystems.
|
||||
url:
|
||||
link_text: Website under construction
|
||||
- icon:
|
||||
source: https://cloud.veen.world/s/logo_massage_therapist_512x512/download
|
||||
@ -101,8 +98,84 @@ cards:
|
||||
text: Certified in Tantra Massage, I offer unique full-body rituals to awaken senses
|
||||
and harmonize body and mind. My sessions, a blend of ancient Tantra and modern
|
||||
relaxation, focus on energy flow, personal growth, and spiritual awakening.
|
||||
url:
|
||||
link_text: Website under construction
|
||||
|
||||
accounts:
|
||||
name: Accounts
|
||||
description: My Accounts
|
||||
icon:
|
||||
class: fa-solid fa-user-group
|
||||
subitems:
|
||||
- name: Meta
|
||||
description: Social and developer networks
|
||||
icon:
|
||||
class: fa-brands fa-meta
|
||||
subitems:
|
||||
- name: Instagram
|
||||
description: Follow me on Instagram
|
||||
icon:
|
||||
class: fa-brands fa-instagram
|
||||
url: https://www.instagram.com/kevinveenbirkenbach/
|
||||
identifier: kevinveenbirkenbach
|
||||
link: navigation.header.contact.whatsapp.warning
|
||||
- name: Facebook
|
||||
description: Like my Facebook page
|
||||
icon:
|
||||
class: fa-brands fa-facebook
|
||||
url: https://www.facebook.com/kevinveenbirkenbach
|
||||
- name: Messengers
|
||||
description: Messenger Applications
|
||||
icon:
|
||||
class: fas fa-comments
|
||||
subitems:
|
||||
- link: navigation.header.contact.whatsapp
|
||||
- link: navigation.header.contact.signal
|
||||
- link: navigation.header.contact.telegram
|
||||
- name: Carreer Profiles
|
||||
icon:
|
||||
class: fa-solid fa-user-tie
|
||||
subitems:
|
||||
- name: XING
|
||||
description: Visit my XING profile
|
||||
icon:
|
||||
class: bi bi-building
|
||||
url: https://www.xing.com/profile/Kevin_VeenBirkenbach
|
||||
- name: LinkedIn
|
||||
description: Connect on LinkedIn
|
||||
icon:
|
||||
class: bi bi-linkedin
|
||||
url: https://www.linkedin.com/in/kevinveenbirkenbach
|
||||
- name: Sports
|
||||
description: My sport activities
|
||||
icon:
|
||||
class: fa-solid fa-running
|
||||
subitems:
|
||||
- name: Garmin
|
||||
description: My Garmin activities
|
||||
icon:
|
||||
class: fa-solid fa-person-running
|
||||
url: https://s.veen.world/garmin
|
||||
- name: Eversports
|
||||
description: My Eversports sessions
|
||||
icon:
|
||||
class: fa-solid fa-dumbbell
|
||||
url: https://s.veen.world/eversports
|
||||
- name: Duolingo
|
||||
description: Learn with me on Duolingo
|
||||
icon:
|
||||
class: fa-solid fa-language
|
||||
url: https://www.duolingo.com/profile/kevinbirkenbach
|
||||
- name: Spotify
|
||||
description: Listen to my playlists
|
||||
icon:
|
||||
class: fa-brands fa-spotify
|
||||
url: https://open.spotify.com/user/31vebfzbjf3p7oualis76qfpr5ty
|
||||
- name: Patreon
|
||||
description: Support me on Patreon
|
||||
icon:
|
||||
class: fa-brands fa-patreon
|
||||
url: https://patreon.com/kevinveenbirkenbach
|
||||
|
||||
company:
|
||||
titel: Kevin Veen-Birkenbach
|
||||
subtitel: Consulting and Coaching Solutions
|
||||
@ -116,6 +189,7 @@ company:
|
||||
city: Berlin
|
||||
country: Germany
|
||||
imprint_url: https://s.veen.world/imprint
|
||||
|
||||
navigation:
|
||||
header:
|
||||
- name: Microblog
|
||||
@ -123,25 +197,21 @@ navigation:
|
||||
icon:
|
||||
class: fa-brands fa-mastodon
|
||||
url: https://microblog.veen.world/@kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Pictures
|
||||
description: View my photo gallery
|
||||
icon:
|
||||
class: fa-solid fa-camera
|
||||
url: https://picture.veen.world/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Videos
|
||||
description: Watch my videos
|
||||
icon:
|
||||
class: fa-solid fa-video
|
||||
url: https://video.veen.world/a/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Blog
|
||||
description: Read my blog
|
||||
icon:
|
||||
class: fa-solid fa-blog
|
||||
url: https://blog.veen.world
|
||||
subitems: []
|
||||
- name: Code
|
||||
icon:
|
||||
class: fa-solid fa-laptop-code
|
||||
@ -152,13 +222,11 @@ navigation:
|
||||
icon:
|
||||
class: bi bi-github
|
||||
url: https://github.com/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Gitea
|
||||
description: Explore my code repositories
|
||||
icon:
|
||||
class: fa-solid fa-code
|
||||
url: https://git.veen.world/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Contact
|
||||
description: Get in touch
|
||||
icon:
|
||||
@ -171,7 +239,7 @@ navigation:
|
||||
url: mailto:kevin@veen.world
|
||||
identifier: kevin@veen.world
|
||||
alternatives:
|
||||
- link: navigation.header.contact.matrix
|
||||
#- link: navigation.header.contact.matrix
|
||||
- name: Matrix
|
||||
description: Chat with me on Matrix
|
||||
icon:
|
||||
@ -223,7 +291,7 @@ navigation:
|
||||
identifier: "+491781798023"
|
||||
warning: Signal is not hosted by me!
|
||||
alternatives:
|
||||
- link: navigation.header.contact.matrix
|
||||
#- link: navigation.header.contact.matrix
|
||||
- name: Telegram
|
||||
description: Message me on Telegram
|
||||
icon:
|
||||
@ -233,7 +301,7 @@ navigation:
|
||||
identifier: kevinveenbirkenbach
|
||||
warning: Telegram is not hosted by me!
|
||||
alternatives:
|
||||
- link: navigation.header.contact.matrix
|
||||
#- link: navigation.header.contact.matrix
|
||||
- name: WhatsApp
|
||||
description: Chat with me on WhatsApp
|
||||
icon:
|
||||
@ -241,219 +309,118 @@ navigation:
|
||||
url: https://wa.me/491781798023
|
||||
identifier: "+491781798023"
|
||||
alternatives:
|
||||
- link: navigation.header.contact.matrix
|
||||
#- link: navigation.header.contact.matrix
|
||||
warning: |
|
||||
Using software and platforms from the Meta corporation (e.g., Facebook, Instagram, WhatsApp) may compromise your data privacy and digital freedom due to centralized control, extensive data collection practices, and inconsistent moderation policies. These platforms often fail to adequately address harmful content, misinformation, and abuse.
|
||||
|
||||
footer:
|
||||
- name: External Accounts
|
||||
description: Me on other plattforms
|
||||
icon:
|
||||
class: fa-solid fa-external-link-alt
|
||||
subitems:
|
||||
- name: Meta
|
||||
description: Social and developer networks
|
||||
- link: accounts
|
||||
- name: Community
|
||||
description: My presence in the Fediverse
|
||||
icon:
|
||||
class: fa-brands fa-meta
|
||||
class: fa-solid fa-users
|
||||
subitems:
|
||||
- name: Instagram
|
||||
description: Follow me on Instagram
|
||||
- name: Forum
|
||||
description: Join the discussion
|
||||
icon:
|
||||
class: fa-brands fa-instagram
|
||||
url: https://www.instagram.com/kevinveenbirkenbach/
|
||||
identifier: kevinveenbirkenbach
|
||||
link: navigation.header.contact.whatsapp.warning
|
||||
- name: Facebook
|
||||
description: Like my Facebook page
|
||||
class: fa-brands fa-discourse
|
||||
url: https://forum.veen.world/u/kevinveenbirkenbach
|
||||
- name: Newsletter
|
||||
description: Subscribe to my newsletter
|
||||
icon:
|
||||
class: fa-brands fa-facebook
|
||||
url: https://www.facebook.com/kevinveenbirkenbach
|
||||
- name: Communication
|
||||
description: Social and developer networks
|
||||
class: fa-solid fa-envelope-open-text
|
||||
url: https://newsletter.veen.world/subscription/form
|
||||
- name: Work Hub
|
||||
description: Curated collection of self hosted tools for work, organization, and learning.
|
||||
icon:
|
||||
class: fa-brands fa-meta
|
||||
subitems:
|
||||
- link: navigation.header.contact.whatsapp
|
||||
- link: navigation.header.contact.signal
|
||||
- link: navigation.header.contact.telegram
|
||||
- name: Carreer Profiles
|
||||
icon:
|
||||
class: fa-solid fa-user-tie
|
||||
class: fa-solid fa-toolbox
|
||||
subitems:
|
||||
- name: XING
|
||||
description: Visit my XING profile
|
||||
- name: Open Project
|
||||
description: Explore my projects
|
||||
icon:
|
||||
class: bi bi-building
|
||||
url: https://www.xing.com/profile/Kevin_VeenBirkenbach
|
||||
subitems: []
|
||||
- name: LinkedIn
|
||||
description: Connect on LinkedIn
|
||||
class: fa-solid fa-chart-line
|
||||
url: https://project.veen.world/
|
||||
- name: Taiga
|
||||
description: View my Kanban board
|
||||
icon:
|
||||
class: bi bi-linkedin
|
||||
url: https://www.linkedin.com/in/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Sports
|
||||
description: My sport activities
|
||||
class: bi bi-clipboard2-check-fill
|
||||
url: https://kanban.veen.world/
|
||||
- name: Matomo
|
||||
description: Analyze with Matomo
|
||||
icon:
|
||||
class: fa-solid fa-chart-simple
|
||||
url: https://matomo.veen.world/
|
||||
- name: Baserow
|
||||
description: Organize with Baserow
|
||||
icon:
|
||||
class: fa-solid fa-table
|
||||
url: https://baserow.veen.world/
|
||||
- name: Elements
|
||||
description: Chat with me
|
||||
icon:
|
||||
class: fa-solid fa-comment
|
||||
url: https://element.veen.world/
|
||||
- name: Big Blue Button
|
||||
description: Join live events
|
||||
icon:
|
||||
class: fa-solid fa-video
|
||||
url: https://meet.veen.world/
|
||||
- name: Mailu
|
||||
description: Send me a mail
|
||||
icon:
|
||||
class: fa-solid fa-envelope
|
||||
url: https://mail.veen.world/
|
||||
- name: Moodel
|
||||
description: Learn with my academy
|
||||
icon:
|
||||
class: fa-solid fa-graduation-cap
|
||||
url: https://academy.veen.world/
|
||||
- name: Yourls
|
||||
description: Find my curated links
|
||||
icon:
|
||||
class: bi bi-link
|
||||
url: https://s.veen.world/admin/
|
||||
- name: Nextcloud
|
||||
description: Access my cloud storage
|
||||
icon:
|
||||
class: fa-solid fa-cloud
|
||||
url: https://cloud.veen.world/
|
||||
- name: Logbooks
|
||||
description: My activity logs
|
||||
icon:
|
||||
class: fa-solid fa-running
|
||||
url:
|
||||
class: fa-solid fa-book
|
||||
subitems:
|
||||
- name: Garmin
|
||||
description: My Garmin activities
|
||||
- name: Skydiver
|
||||
description: View my skydiving logs
|
||||
icon:
|
||||
class: fa-solid fa-person-running
|
||||
url: https://s.veen.world/garmin
|
||||
subitems: []
|
||||
- name: Eversports
|
||||
description: My Eversports sessions
|
||||
class: fa-solid fa-parachute-box
|
||||
url: https://s.veen.world/skydiverlog
|
||||
- name: Skipper
|
||||
description: See my sailing records
|
||||
icon:
|
||||
class: fa-solid fa-dumbbell
|
||||
url: https://s.veen.world/eversports
|
||||
subitems: []
|
||||
- name: Duolingo
|
||||
description: Learn with me on Duolingo
|
||||
class: fa-solid fa-sailboat
|
||||
url: https://s.veen.world/meilenbuch
|
||||
- name: Diver
|
||||
description: Check my diving logs
|
||||
icon:
|
||||
class: fa-solid fa-fish
|
||||
url: https://s.veen.world/diverlog
|
||||
- name: Pilot
|
||||
description: Review my flight logs
|
||||
icon:
|
||||
class: fa-solid fa-plane
|
||||
url: https://s.veen.world/pilotlog
|
||||
- name: Nature
|
||||
description: Explore my nature logs
|
||||
icon:
|
||||
class: fa-solid fa-tree
|
||||
url: https://s.veen.world/naturejournal
|
||||
- name: Vita
|
||||
description: View my CV and professional background
|
||||
icon:
|
||||
class: fa-solid fa-language
|
||||
url: https://www.duolingo.com/profile/kevinbirkenbach
|
||||
subitems: []
|
||||
- name: Spotify
|
||||
description: Listen to my playlists
|
||||
class: fa-solid fa-file-lines
|
||||
url: https://s.veen.world/lebenslauf
|
||||
- name: Imprint
|
||||
icon:
|
||||
class: fa-brands fa-spotify
|
||||
url: https://open.spotify.com/user/31vebfzbjf3p7oualis76qfpr5ty
|
||||
subitems: []
|
||||
- name: Patreon
|
||||
description: Support me on Patreon
|
||||
icon:
|
||||
class: fa-brands fa-patreon
|
||||
url: https://patreon.com/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Community
|
||||
description: My presence in the Fediverse
|
||||
icon:
|
||||
class: fa-solid fa-users
|
||||
subitems:
|
||||
- name: Forum
|
||||
description: Join the discussion
|
||||
icon:
|
||||
class: fa-brands fa-discourse
|
||||
url: https://forum.veen.world/u/kevinveenbirkenbach
|
||||
subitems: []
|
||||
- name: Newsletter
|
||||
description: Subscribe to my newsletter
|
||||
icon:
|
||||
class: fa-solid fa-envelope-open-text
|
||||
url: https://newsletter.veen.world/subscription/form
|
||||
subitems: []
|
||||
- name: Work Hub
|
||||
description: Curated collection of self hosted tools for work, organization, and
|
||||
learning.
|
||||
icon:
|
||||
class: fa-solid fa-toolbox
|
||||
url:
|
||||
subitems:
|
||||
- name: Open Project
|
||||
description: Explore my projects
|
||||
icon:
|
||||
class: fa-solid fa-chart-line
|
||||
url: https://project.veen.world/
|
||||
subitems: []
|
||||
- name: Taiga
|
||||
description: View my Kanban board
|
||||
icon:
|
||||
class: bi bi-clipboard2-check-fill
|
||||
url: https://kanban.veen.world/
|
||||
subitems: []
|
||||
- name: Matomo
|
||||
description: Analyze with Matomo
|
||||
icon:
|
||||
class: fa-solid fa-chart-simple
|
||||
url: https://matomo.veen.world/
|
||||
subitems: []
|
||||
- name: Baserow
|
||||
description: Organize with Baserow
|
||||
icon:
|
||||
class: fa-solid fa-table
|
||||
url: https://baserow.veen.world/
|
||||
subitems: []
|
||||
- name: Elements
|
||||
description: Chat with me
|
||||
icon:
|
||||
class: fa-solid fa-comment
|
||||
url: https://element.veen.world/
|
||||
subitems: []
|
||||
- name: Big Blue Button
|
||||
description: Join live events
|
||||
icon:
|
||||
class: fa-solid fa-video
|
||||
url: https://meet.veen.world/
|
||||
subitems: []
|
||||
- name: Mailu
|
||||
description: Send me a mail
|
||||
icon:
|
||||
class: fa-solid fa-envelope
|
||||
url: https://mail.veen.world/
|
||||
subitems: []
|
||||
- name: Moodel
|
||||
description: Learn with my academy
|
||||
icon:
|
||||
class: fa-solid fa-graduation-cap
|
||||
url: https://academy.veen.world/
|
||||
subitems: []
|
||||
- name: Yourls
|
||||
description: Find my curated links
|
||||
icon:
|
||||
class: bi bi-link
|
||||
url: https://s.veen.world/admin/
|
||||
subitems: []
|
||||
- name: Nextcloud
|
||||
description: Access my cloud storage
|
||||
icon:
|
||||
class: fa-solid fa-cloud
|
||||
url: https://cloud.veen.world/
|
||||
subitems: []
|
||||
- name: Logbooks
|
||||
description: My activity logs
|
||||
icon:
|
||||
class: fa-solid fa-book
|
||||
url:
|
||||
subitems:
|
||||
- name: Skydiver
|
||||
description: View my skydiving logs
|
||||
icon:
|
||||
class: fa-solid fa-parachute-box
|
||||
url: https://s.veen.world/skydiverlog
|
||||
subitems: []
|
||||
- name: Skipper
|
||||
description: See my sailing records
|
||||
icon:
|
||||
class: fa-solid fa-sailboat
|
||||
url: https://s.veen.world/meilenbuch
|
||||
subitems: []
|
||||
- name: Diver
|
||||
description: Check my diving logs
|
||||
icon:
|
||||
class: fa-solid fa-fish
|
||||
url: https://s.veen.world/diverlog
|
||||
subitems: []
|
||||
- name: Pilot
|
||||
description: Review my flight logs
|
||||
icon:
|
||||
class: fa-solid fa-plane
|
||||
url: https://s.veen.world/pilotlog
|
||||
subitems: []
|
||||
- name: Nature
|
||||
description: Explore my nature logs
|
||||
icon:
|
||||
class: fa-solid fa-tree
|
||||
url: https://s.veen.world/naturejournal
|
||||
- name: Vita
|
||||
description: View my CV and professional background
|
||||
icon:
|
||||
class: fa-solid fa-file-lines
|
||||
url: https://s.veen.world/lebenslauf
|
||||
subitems: []
|
||||
- name: Imprint
|
||||
icon:
|
||||
class: fa-solid fa-scale-balanced
|
||||
url: https://s.veen.world/imprint
|
||||
class: fa-solid fa-scale-balanced
|
||||
url: https://s.veen.world/imprint
|
@ -22,7 +22,7 @@
|
||||
{% if subitem.icon is defined and subitem.icon.class is defined %}
|
||||
<i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
|
||||
{% else %}
|
||||
<p>Fehlendes Icon im Subitem: {{ subitem }}</p>
|
||||
<p>Missing icon in subitem: {{ subitem }}</p>
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
@ -33,9 +33,6 @@
|
||||
<!-- Navigation Bar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<!--
|
||||
<a class="navbar-brand" href="#">Navbar</a>
|
||||
-->
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav{{menu_type}}" aria-controls="navbarNav{{menu_type}}" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
@ -53,7 +50,11 @@
|
||||
<!-- Dropdown Menu -->
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" data-bs-display="dynamic" data-popper-placement="top" title="{{ item.description }}" aria-expanded="false">
|
||||
<i class="{{ item.icon.class }}" data-bs-toggle="tooltip"></i> {{ item.name }}
|
||||
{% if item.icon is defined and item.icon.class is defined %}
|
||||
<i class="{{ item.icon.class }}" data-bs-toggle="tooltip"></i> {{ item.name }}
|
||||
{% else %}
|
||||
<p>Missing icon in item: {{ item }}</p>
|
||||
{% endif %}
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-{{menu_type}}" aria-labelledby="navbarDropdown{{ loop.index }}">
|
||||
{{ render_subitems(item.subitems) }}
|
||||
|
@ -23,7 +23,6 @@ class CacheManager:
|
||||
"""
|
||||
if not os.path.exists(self.cache_dir):
|
||||
os.makedirs(self.cache_dir)
|
||||
print(f"Created cache directory: {self.cache_dir}")
|
||||
|
||||
def clear_cache(self):
|
||||
"""
|
||||
@ -34,7 +33,6 @@ class CacheManager:
|
||||
file_path = os.path.join(self.cache_dir, filename)
|
||||
if os.path.isfile(file_path):
|
||||
os.remove(file_path)
|
||||
print(f"Deleted: {file_path}")
|
||||
|
||||
def cache_file(self, file_url):
|
||||
"""
|
||||
|
@ -1,51 +1,106 @@
|
||||
from pprint import pprint
|
||||
import inspect
|
||||
class ConfigurationResolver:
|
||||
def __init__(self, config):
|
||||
"""
|
||||
Initializes the ConfigurationResolver with a configuration dictionary.
|
||||
|
||||
Args:
|
||||
config (dict): The configuration to resolve links in.
|
||||
"""
|
||||
self.config = config
|
||||
|
||||
def resolve_links(self):
|
||||
"""
|
||||
Resolves all `link` entries in the configuration.
|
||||
Resolves all `link` entries in the configuration by replacing them with
|
||||
the referenced configuration entry.
|
||||
"""
|
||||
self._recursive_resolve(self.config, self.config)
|
||||
|
||||
def _recursive_resolve(self, current_config, root_config):
|
||||
def _recursive_resolve(self, current_config, root_config, path=""):
|
||||
"""
|
||||
Recursively resolves `link` entries in the configuration.
|
||||
Recursively traverses the configuration to resolve all `link` entries.
|
||||
|
||||
Args:
|
||||
current_config (dict or list): The current section of the configuration being processed.
|
||||
root_config (dict): The root of the configuration to resolve links against.
|
||||
path (str): The current path in the configuration for debugging purposes.
|
||||
"""
|
||||
if isinstance(current_config, dict):
|
||||
self._debug(current_config,path,inspect.currentframe().f_lineno)
|
||||
# Traverse all key-value pairs in the dictionary
|
||||
for key, value in list(current_config.items()):
|
||||
if key == "link":
|
||||
if key == "subitems" and isinstance(value, list):
|
||||
pass
|
||||
#self._debug(value,path,inspect.currentframe().f_lineno)
|
||||
#for index, item in enumerate(current_config[key]):
|
||||
# #self._debug(value,path,inspect.currentframe().f_lineno)
|
||||
# if "link" in item:
|
||||
# self._debug(value,path,inspect.currentframe().f_lineno)
|
||||
# self._recursive_resolve(item, root_config, path=f"{path}[{index}]")
|
||||
|
||||
elif key == "link":
|
||||
# Found a `link` entry, attempt to resolve it
|
||||
try:
|
||||
# Attempt to find the target entry in the root configuration
|
||||
target = self._find_entry(root_config, value.lower().replace(" ", "_"))
|
||||
|
||||
|
||||
if isinstance(target, dict):
|
||||
# Replace the current config dictionary with the target dictionary
|
||||
self._debug(value,path,inspect.currentframe().f_lineno)
|
||||
# Replace the current dictionary with the resolved dictionary
|
||||
current_config.clear()
|
||||
current_config.update(target)
|
||||
elif isinstance(target, str):
|
||||
self._debug(value,path,inspect.currentframe().f_lineno)
|
||||
# Replace the `link` entry with the resolved string
|
||||
current_config[key] = target
|
||||
else:
|
||||
current_config[value.split(".")[-1]] = target
|
||||
except Exception as e:
|
||||
raise ValueError(
|
||||
f"Expected a dictionary or string for link '{value}', got {type(target)}"
|
||||
)
|
||||
except KeyError as e:
|
||||
# Handle unresolved links
|
||||
raise ValueError(
|
||||
f"Error resolving link '{value}': {str(e)}. "
|
||||
f"Current path: {key}, Current config: {current_config}"
|
||||
f"Key error while resolving link '{value}': {str(e)}. "
|
||||
f"Current path: {path}, Current config: {current_config}"
|
||||
)
|
||||
else:
|
||||
# Recurse into nested structures
|
||||
self._recursive_resolve(value, root_config)
|
||||
self._debug(value,path,inspect.currentframe().f_lineno)
|
||||
# Recursively resolve non-`link` entries
|
||||
self._recursive_resolve(value, root_config, path=f"{path}.{key}")
|
||||
|
||||
elif isinstance(current_config, list):
|
||||
for item in current_config:
|
||||
self._recursive_resolve(item, root_config)
|
||||
# Traverse all items in the list
|
||||
for index, item in enumerate(current_config):
|
||||
self._recursive_resolve(item, root_config, path=f"{path}[{index}]")
|
||||
|
||||
def _debug(self, value, path, line, condition="accounts"):
|
||||
if condition in path:
|
||||
print("LINE:" + str(line))
|
||||
print("PATH:" + path)
|
||||
print("VALUE:")
|
||||
pprint(value)
|
||||
|
||||
def _find_entry(self, config, path):
|
||||
"""
|
||||
Finds an entry in the configuration by a dot-separated path.
|
||||
Supports both dictionaries and lists with `subitems` navigation.
|
||||
Finds an entry in the configuration by navigating a dot-separated path.
|
||||
|
||||
Args:
|
||||
config (dict or list): The configuration to search within.
|
||||
path (str): The dot-separated path to the desired entry.
|
||||
|
||||
Returns:
|
||||
dict or str: The resolved entry.
|
||||
|
||||
Raises:
|
||||
KeyError: If the path cannot be resolved.
|
||||
ValueError: If the resolved entry is not of the expected type.
|
||||
"""
|
||||
parts = path.split('.')
|
||||
parts = path.split('.') # Split the path into segments
|
||||
current = config
|
||||
|
||||
for part in parts:
|
||||
part = part.replace(" ", "_")
|
||||
part = part.replace(" ", "_") # Normalize part name
|
||||
|
||||
if isinstance(current, list):
|
||||
# Search for a matching entry in a list
|
||||
found = next(
|
||||
@ -57,13 +112,14 @@ class ConfigurationResolver:
|
||||
None
|
||||
)
|
||||
if not found:
|
||||
raise ValueError(
|
||||
raise KeyError(
|
||||
f"No matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
|
||||
f"Current list: {current}"
|
||||
)
|
||||
current = found
|
||||
|
||||
elif isinstance(current, dict):
|
||||
# Perform a case-insensitive dictionary lookup
|
||||
# Search for a key match in a dictionary
|
||||
key = next((k for k in current if k.lower().replace(" ", "_") == part), None)
|
||||
if key is None:
|
||||
raise KeyError(
|
||||
@ -71,20 +127,31 @@ class ConfigurationResolver:
|
||||
f"Current dictionary: {current}"
|
||||
)
|
||||
current = current[key]
|
||||
|
||||
else:
|
||||
# Invalid path segment
|
||||
raise ValueError(
|
||||
f"Invalid path segment '{part}'. Current type: {type(current)}. "
|
||||
f"Path so far: {' > '.join(parts[:parts.index(part)+1])}"
|
||||
)
|
||||
|
||||
# Navigate into `subitems` if present
|
||||
if isinstance(current, dict) and "subitems" in current and current["subitems"]:
|
||||
current = current["subitems"]
|
||||
|
||||
# Stop navigating into `subitems` unless explicitly required by the path
|
||||
if isinstance(current, dict) and "subitems" in current and isinstance(current["subitems"], list) and part != "subitems":
|
||||
break # Stop navigation if `subitems` is not explicitly in the path
|
||||
|
||||
# Ensure the resolved target is a dictionary or string
|
||||
if not isinstance(current, (dict, str)):
|
||||
raise ValueError(
|
||||
f"Expected a dictionary or string for path '{path}', got {type(current)}. Current value: {current}"
|
||||
)
|
||||
|
||||
return current
|
||||
|
||||
def get_config(self):
|
||||
"""
|
||||
Returns the resolved configuration.
|
||||
Returns the fully resolved configuration.
|
||||
|
||||
Returns:
|
||||
dict: The resolved configuration.
|
||||
"""
|
||||
return self.config
|
||||
|
Loading…
x
Reference in New Issue
Block a user