favicon handling

This commit is contained in:
Jörn-Michael Miehe 2023-11-02 12:48:52 +00:00
parent 45ad00eaa6
commit 600ee99520
7 changed files with 76 additions and 11 deletions

View file

@ -27,6 +27,9 @@ class CalendarConfig(BaseModel):
# Dateiname Hintergrundbild # Dateiname Hintergrundbild
background: str = "adventskalender.jpg" background: str = "adventskalender.jpg"
# Dateiname Favicon
favicon: str = "favicon.png"
# Türen für die UI # Türen für die UI
doors: DoorsSaved = [] doors: DoorsSaved = []

View file

@ -114,9 +114,27 @@ async def load_image(file_name: str) -> Image.Image:
return Image.open(BytesIO(await WebDAV.read_bytes(file_name))) return Image.open(BytesIO(await WebDAV.read_bytes(file_name)))
async def api_return_image(img: Image.Image) -> StreamingResponse: async def api_return_ico(img: Image.Image) -> StreamingResponse:
""" """
Bild mit API zurückgeben ICO-Bild mit API zurückgeben
"""
# JPEG-Daten in Puffer speichern
img_buffer = BytesIO()
img.resize(size=(256, 256), resample=Image.LANCZOS)
img.save(img_buffer, format="ICO")
img_buffer.seek(0)
# zurückgeben
return StreamingResponse(
media_type="image/x-icon",
content=img_buffer,
)
async def api_return_jpeg(img: Image.Image) -> StreamingResponse:
"""
JPEG-Bild mit API zurückgeben
""" """
# JPEG-Daten in Puffer speichern # JPEG-Daten in Puffer speichern

View file

@ -44,6 +44,7 @@ class ConfigModel(BaseModel):
class __Calendar(BaseModel): class __Calendar(BaseModel):
config_file: str config_file: str
background: str background: str
favicon: str
class __Font(BaseModel): class __Font(BaseModel):
file: str file: str
@ -93,6 +94,7 @@ async def get_config_model(
"calendar": { "calendar": {
"config_file": cfg.calendar, "config_file": cfg.calendar,
"background": cal_cfg.background, "background": cal_cfg.background,
"favicon": cal_cfg.favicon,
}, },
"image": cfg.image, "image": cfg.image,
"fonts": [ "fonts": [

View file

@ -7,7 +7,7 @@ from PIL 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, get_config from ..core.config import Config, get_config
from ..core.depends import get_all_event_dates, get_day_image from ..core.depends import get_all_event_dates, get_day_image
from ..core.helpers import EventDates, api_return_image, 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 from ._security import user_can_view_day, user_is_admin, user_visible_days
router = APIRouter(prefix="/user", tags=["user"]) router = APIRouter(prefix="/user", tags=["user"])
@ -24,7 +24,29 @@ async def get_background_image(
Hintergrundbild laden Hintergrundbild laden
""" """
return await api_return_image(await load_image(f"files/{cal_cfg.background}")) return await api_return_jpeg(await load_image(f"files/{cal_cfg.background}"))
@router.get(
"/favicon",
response_class=StreamingResponse,
)
async def get_favicon(
cal_cfg: CalendarConfig = Depends(get_calendar_config),
) -> StreamingResponse:
"""
Favicon laden
"""
try:
return await api_return_ico(await load_image(f"files/{cal_cfg.favicon}"))
except RuntimeError:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
# - favicon
# - "user-config-model"
@router.get("/title") @router.get("/title")
@ -82,7 +104,7 @@ async def get_image_for_day(
status.HTTP_404_NOT_FOUND, "Ich habe heute leider kein Foto für dich." status.HTTP_404_NOT_FOUND, "Ich habe heute leider kein Foto für dich."
) )
return await api_return_image(image) return await api_return_jpeg(image)
@router.get("/next_door") @router.get("/next_door")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -79,6 +79,9 @@
<dt>Hintergrundbild</dt> <dt>Hintergrundbild</dt>
<dd>{{ config_model.calendar.background }}</dd> <dd>{{ config_model.calendar.background }}</dd>
<dt>Favicon</dt>
<dd>{{ admin_config_model.calendar.favicon }}</dd>
<dt>Türchen ({{ doors.length }} Stück)</dt> <dt>Türchen ({{ doors.length }} Stück)</dt>
<dd> <dd>
<template v-for="(door, index) in doors" :key="`door-${index}`"> <template v-for="(door, index) in doors" :key="`door-${index}`">
@ -194,7 +197,8 @@ export default class extends Vue {
}, },
calendar: { calendar: {
config_file: "lorem ipsum", config_file: "lorem ipsum",
background: "dolor sit amet", background: "dolor sit",
favicon: "sit amet",
}, },
image: { image: {
size: 500, size: 500,

View file

@ -9,11 +9,27 @@ const empty_creds = () => ["", ""] as Credentials;
export const advent22Store = defineStore({ export const advent22Store = defineStore({
id: "advent22", id: "advent22",
state: () => ({ state: () => {
ADVENT22.api_get_blob("user/favicon")
.then((favicon_src) => {
const link: HTMLLinkElement =
document.querySelector("link[rel*='icon']") ||
document.createElement("link");
link.rel = "shortcut icon";
link.type = "image/x-icon";
link.href = favicon_src;
if (link.parentElement === null)
document.getElementsByTagName("head")[0].appendChild(link);
})
.catch(() => {});
return {
api_creds: empty_creds(), api_creds: empty_creds(),
is_admin: false, is_admin: false,
is_touch_device: check_touch_device(), is_touch_device: check_touch_device(),
}), };
},
getters: { getters: {
axios_creds: (state): AxiosBasicCredentials => { axios_creds: (state): AxiosBasicCredentials => {