From a26d519cf28abd88b9b0c4b4f5b875baa9e5664e Mon Sep 17 00:00:00 2001 From: Florian Heinz Date: Sun, 12 Apr 2026 17:50:17 +0200 Subject: [PATCH] polish nouri 0.6.0 startup and desktop header --- RELEASE_NOTES_0.6.0.md | 4 +++- nouri/images.py | 14 +++++++++++++- nouri/static/css/styles.css | 9 ++++++--- requirements.txt | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/RELEASE_NOTES_0.6.0.md b/RELEASE_NOTES_0.6.0.md index c10358d..8696cd7 100644 --- a/RELEASE_NOTES_0.6.0.md +++ b/RELEASE_NOTES_0.6.0.md @@ -10,6 +10,7 @@ Nouri 0.6.0 bringt die App näher an einen stabilen 1.0-Stand. Der Schwerpunkt l - Überarbeitete PWA-Icons inklusive zusätzlicher Größen und maskierbarer Variante - Ruhigeres visuelles Finish bei Karten, Fokuszuständen, Setup und leeren Bereichen - Mobile Header-Logik bereinigt, damit der obere Bereich auf Smartphones nicht fest mitscrollt +- Desktop-Navigation wieder klarer als durchlaufende Leiste direkt neben dem Logo ### Bilder und Performance @@ -32,6 +33,7 @@ Nouri 0.6.0 bringt die App näher an einen stabilen 1.0-Stand. Der Schwerpunkt l - Restore mit klarer Bestätigung statt versehentlicher Überschreibung - Freundlichere Behandlung von zu großen Bild-Uploads - Robusterer Umgang mit vorhandenen älteren Datenstrukturen +- Startet lokal jetzt auch ohne Pillow-Build auf Python 3.14, statt schon beim Import zu scheitern ### Planung und Vorschläge @@ -46,7 +48,7 @@ Nouri 0.6.0 bringt die App näher an einen stabilen 1.0-Stand. Der Schwerpunkt l - Neue Hilfsmodule für Bildverarbeitung und Backup/Restore - App-Metadaten-Tabelle für robustere Schema-Verwaltung vorbereitet - Cloudron-Version auf 0.6.0 angehoben -- Pillow als zusätzliche Abhängigkeit für lokale Bildverarbeitung ergänzt +- Pillow für Bildverarbeitung ergänzt und auf Python 3.14 lokal als optionale Abhängigkeit abgefedert ## Hinweise zum Update diff --git a/nouri/images.py b/nouri/images.py index 47dcb4f..7070146 100644 --- a/nouri/images.py +++ b/nouri/images.py @@ -4,10 +4,18 @@ import os import uuid from pathlib import Path -from PIL import Image, ImageOps, UnidentifiedImageError from werkzeug.datastructures import FileStorage from werkzeug.utils import secure_filename +try: + from PIL import Image, ImageOps, UnidentifiedImageError + PILLOW_AVAILABLE = True +except ImportError: # pragma: no cover - local fallback when Pillow is unavailable + Image = None + ImageOps = None + UnidentifiedImageError = OSError + PILLOW_AVAILABLE = False + ALLOWED_IMAGE_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "webp"} IMAGE_VARIANTS = { @@ -54,6 +62,8 @@ def remove_photo_assets(upload_folder: str | Path, filename: str | None) -> None def _open_image(upload: FileStorage) -> Image.Image: + if not PILLOW_AVAILABLE or Image is None or ImageOps is None: + raise OSError("Pillow ist nicht verfügbar.") upload.stream.seek(0) image = Image.open(upload.stream) image.load() @@ -61,6 +71,8 @@ def _open_image(upload: FileStorage) -> Image.Image: def _prepare_image(image: Image.Image) -> Image.Image: + if not PILLOW_AVAILABLE: + return image if image.mode not in {"RGB", "RGBA"}: image = image.convert("RGBA" if "A" in image.getbands() else "RGB") return image diff --git a/nouri/static/css/styles.css b/nouri/static/css/styles.css index 5e232eb..b88cf32 100644 --- a/nouri/static/css/styles.css +++ b/nouri/static/css/styles.css @@ -165,8 +165,8 @@ button.secondary:hover, .site-header { position: static; z-index: 10; - display: grid; - grid-template-columns: auto 1fr auto; + display: flex; + flex-wrap: wrap; gap: 1rem; align-items: center; padding: 1rem 1.2rem; @@ -223,7 +223,8 @@ h3, display: flex; flex-wrap: wrap; gap: 0.45rem; - justify-content: center; + justify-content: flex-start; + flex: 1 1 32rem; min-width: 0; } @@ -251,6 +252,8 @@ h3, align-items: center; gap: 0.75rem; justify-content: flex-end; + margin-left: auto; + flex-wrap: wrap; } .user-chip, diff --git a/requirements.txt b/requirements.txt index db71091..182c53d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ Flask==3.1.1 gunicorn==23.0.0 pywebpush==2.3.0 -Pillow==11.2.1 +Pillow==11.2.1; python_version < "3.14"