Compare commits

..

No commits in common. "4f603d3cb1333e1df5de2d1cfe86e2e379d2be76" and "af08917155107e8890800b966a35943818f3123e" have entirely different histories.

5 changed files with 30 additions and 62 deletions

View file

@ -1,4 +1,4 @@
[flake8]
max-line-length = 80
extend-select = B950
extend-ignore = E203,E501
select = C,E,F,W,B,B950
extend-ignore = E203, E501

View file

@ -1,3 +0,0 @@
[settings]
profile = black
line_length = 80

View file

@ -24,8 +24,6 @@ from .helpers import (
set_len,
)
RE_NUM = re.compile(r"/(\d+)\.", flags=re.IGNORECASE)
async def get_all_sorted_days(
cal_cfg: CalendarConfig = Depends(get_calendar_config),
@ -111,10 +109,11 @@ async def get_all_manual_image_names(
Bilder: "manual" zuordnen
"""
num_re = re.compile(r"/(\d+)\.", flags=re.IGNORECASE)
return {
int(num_match.group(1)): name
for name in manual_image_names
if (num_match := RE_NUM.search(name)) is not None
if (num_match := num_re.search(name)) is not None
}

View file

@ -1,4 +1,3 @@
import base64
import itertools
import random
import re
@ -6,9 +5,9 @@ from datetime import date, datetime, timedelta
from io import BytesIO
from typing import Any, Awaitable, Callable, Iterable, Self, Sequence, TypeVar
from fastapi.responses import StreamingResponse
from PIL import Image as PILImage
from PIL.Image import Image, Resampling
from pydantic import BaseModel
from .config import get_config
from .dav.webdav import WebDAV
@ -116,51 +115,25 @@ async def load_image(file_name: str) -> Image:
return PILImage.open(BytesIO(await WebDAV.read_bytes(file_name)))
class ImageData(BaseModel):
width: int
height: int
aspect_ratio: float
data_url: str
@classmethod
def create(
cls,
*,
media_type: str,
content: BytesIO,
width: int,
height: int,
) -> Self:
img_data = base64.b64encode(content.getvalue()).decode("utf-8")
return cls(
width=width,
height=height,
aspect_ratio=width / height,
data_url=f"data:{media_type};base64,{img_data}",
)
async def api_return_ico(img: Image) -> ImageData:
async def api_return_ico(img: Image) -> StreamingResponse:
"""
ICO-Bild mit API zurückgeben
"""
# ICO-Daten in Puffer speichern (256px)
# JPEG-Daten in Puffer speichern
img_buffer = BytesIO()
img.resize(size=(256, 256), resample=Resampling.LANCZOS)
img.save(img_buffer, format="ICO")
img_buffer.seek(0)
# zurückgeben
return ImageData.create(
return StreamingResponse(
media_type="image/x-icon",
content=img_buffer,
width=img.width,
height=img.height,
)
async def api_return_jpeg(img: Image) -> ImageData:
async def api_return_jpeg(img: Image) -> StreamingResponse:
"""
JPEG-Bild mit API zurückgeben
"""
@ -168,13 +141,12 @@ async def api_return_jpeg(img: Image) -> ImageData:
# JPEG-Daten in Puffer speichern
img_buffer = BytesIO()
img.save(img_buffer, format="JPEG", quality=85)
img_buffer.seek(0)
# zurückgeben
return ImageData.create(
return StreamingResponse(
media_type="image/jpeg",
content=img_buffer,
width=img.width,
height=img.height,
)

View file

@ -1,31 +1,25 @@
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import StreamingResponse
from PIL.Image import Image
from ..core.calendar_config import (
CalendarConfig,
DoorsSaved,
get_calendar_config,
)
from ..core.calendar_config import CalendarConfig, DoorsSaved, get_calendar_config
from ..core.config import Config, Site, get_config
from ..core.depends import get_all_event_dates, get_day_image
from ..core.helpers import (
EventDates,
ImageData,
api_return_ico,
api_return_jpeg,
load_image,
)
from ..core.helpers import EventDates, api_return_ico, api_return_jpeg, load_image
from ._security import user_can_view_day, user_is_admin, user_visible_days
router = APIRouter(prefix="/user", tags=["user"])
@router.get("/background_image")
@router.get(
"/background_image",
response_class=StreamingResponse,
)
async def get_background_image(
cal_cfg: CalendarConfig = Depends(get_calendar_config),
) -> ImageData:
) -> StreamingResponse:
"""
Hintergrundbild laden
"""
@ -33,10 +27,13 @@ async def get_background_image(
return await api_return_jpeg(await load_image(f"files/{cal_cfg.background}"))
@router.get("/favicon")
@router.get(
"/favicon",
response_class=StreamingResponse,
)
async def get_favicon(
cal_cfg: CalendarConfig = Depends(get_calendar_config),
) -> ImageData:
) -> StreamingResponse:
"""
Favicon laden
"""
@ -71,12 +68,15 @@ async def get_doors(
return [door for door in cal_cfg.doors if door.day in visible_days]
@router.get("/image_{day}")
@router.get(
"/image_{day}",
response_class=StreamingResponse,
)
async def get_image_for_day(
user_can_view: bool = Depends(user_can_view_day),
is_admin: bool = Depends(user_is_admin),
image: Image | None = Depends(get_day_image),
) -> ImageData:
) -> StreamingResponse:
"""
Bild für einen Tag erstellen
"""