From 9ada9acb3ae9c413913a58a2d7a8203e2e8cdc6c Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Mon, 7 Jul 2025 12:40:25 +0200 Subject: [PATCH] Implemented SVG handling --- app/static/css/default.css | 4 ++ app/templates/moduls/card.html.j2 | 17 +++++--- app/utils/cache_manager.py | 65 ++++++++++++++----------------- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/app/static/css/default.css b/app/static/css/default.css index 4385e4a..5e9ae47 100644 --- a/app/static/css/default.css +++ b/app/static/css/default.css @@ -100,6 +100,10 @@ h3.footer-title { font-size: 100px; } +svg { + fill: currentColor; +} + div#navbarNavheader li.nav-item { margin-left: 6px; } diff --git a/app/templates/moduls/card.html.j2 b/app/templates/moduls/card.html.j2 index 4725340..11cfabd 100644 --- a/app/templates/moduls/card.html.j2 +++ b/app/templates/moduls/card.html.j2 @@ -2,12 +2,19 @@
- {# Prioritize image, fallback to icon via onerror #} {% if card.icon.cache %} - {{ card.title }} - {% if card.icon.class %} - + {% if card.icon.cache.endswith('.svg') %} + + {% if card.icon.class %} + + {% endif %} + + {% else %} + {{ card.title }} + {% if card.icon.class %} + + {% endif %} {% endif %} {% elif card.icon.class %} diff --git a/app/utils/cache_manager.py b/app/utils/cache_manager.py index 5c46765..f90729c 100644 --- a/app/utils/cache_manager.py +++ b/app/utils/cache_manager.py @@ -1,33 +1,20 @@ import os import hashlib import requests +import mimetypes class CacheManager: - """ - A class to manage caching of files, including creating temporary directories - and caching files locally with hashed filenames. - """ - def __init__(self, cache_dir="static/cache"): - """ - Initialize the CacheManager with a cache directory. - - :param cache_dir: The directory where cached files will be stored. - """ self.cache_dir = cache_dir self._ensure_cache_dir_exists() def _ensure_cache_dir_exists(self): - """ - Ensure the cache directory exists. If it doesn't, create it. - """ + """Ensure the cache directory exists on disk.""" if not os.path.exists(self.cache_dir): os.makedirs(self.cache_dir) def clear_cache(self): - """ - Clear all files in the cache directory. - """ + """Remove all files from the cache directory.""" if os.path.exists(self.cache_dir): for filename in os.listdir(self.cache_dir): file_path = os.path.join(self.cache_dir, filename) @@ -36,31 +23,39 @@ class CacheManager: def cache_file(self, file_url): """ - Download a file and store it locally in the cache directory with a hashed filename. - - :param file_url: The URL of the file to cache. - :return: The local path of the cached file. + Download a file from `file_url` and store it in the cache. + If any HTTP error occurs, return "Undefined" instead of raising. """ - # Generate a hashed filename based on the URL + # Compute a short hash suffix for the URL hash_object = hashlib.blake2s(file_url.encode('utf-8'), digest_size=8) hash_suffix = hash_object.hexdigest() - # Determine the base name for the file - splitted_file_url = file_url.split("/") - base_name = splitted_file_url[-2] if splitted_file_url[-1] == "download" else splitted_file_url[-1] + # Derive a base filename: drop trailing 'download' if present + url_parts = file_url.rstrip("/").split("/") + base_name = url_parts[-2] if url_parts[-1] == "download" else url_parts[-1] - # Construct the full path for the cached file - filename = f"{base_name}_{hash_suffix}.png" + try: + # Attempt to download the file (streaming) + response = requests.get(file_url, stream=True) + response.raise_for_status() + except requests.RequestException: + # On any network/HTTP error, skip caching and return "Undefined" + return "Undefined" + + # Determine file extension from Content-Type header + content_type = response.headers.get('Content-Type', '') + extension = mimetypes.guess_extension(content_type.split(";")[0].strip()) + if extension is None: + extension = '.png' # default extension + + # Build final filename and full path + filename = f"{base_name}_{hash_suffix}{extension}" full_path = os.path.join(self.cache_dir, filename) - # If the file already exists, return the cached path - if os.path.exists(full_path): - return full_path + # Write the file to cache if not already present + if not os.path.exists(full_path): + with open(full_path, "wb") as out_file: + for chunk in response.iter_content(chunk_size=1024): + out_file.write(chunk) - # Download the file and save it locally - response = requests.get(file_url, stream=True) - if response.status_code == 200: - with open(full_path, "wb") as file: - for chunk in response.iter_content(1024): - file.write(chunk) return full_path