polish nouri 0.6.0 startup and desktop header
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+13
-1
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user