mirror of
https://code.lenaisten.de/Lenaisten/advent22.git
synced 2024-12-23 13:13:00 +00:00
updated font handling
This commit is contained in:
parent
7951363be8
commit
8a254d2958
6 changed files with 67 additions and 25 deletions
|
@ -92,14 +92,6 @@ class Puzzle(BaseModel):
|
|||
close_after: int = 90
|
||||
|
||||
|
||||
class TTFont(BaseModel):
|
||||
# Dateiname (in "/files")
|
||||
file: str
|
||||
|
||||
# Schriftgröße für den Font
|
||||
size: int = 50
|
||||
|
||||
|
||||
class Image(BaseModel):
|
||||
# Quadrat, Seitenlänge in px
|
||||
size: int = 1000
|
||||
|
@ -107,10 +99,6 @@ class Image(BaseModel):
|
|||
# Rand in px, wo keine Buchstaben untergebracht werden
|
||||
border: int = 60
|
||||
|
||||
# Schriftarten
|
||||
# TODO
|
||||
fonts: list[TTFont]
|
||||
|
||||
|
||||
class Config(BaseModel):
|
||||
# Login-Daten für Admin-Modus
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import re
|
||||
from dataclasses import dataclass
|
||||
from datetime import date
|
||||
from io import BytesIO
|
||||
from typing import cast
|
||||
|
@ -11,8 +12,10 @@ from .calendar_config import CalendarConfig, get_calendar_config
|
|||
from .config import Config, get_config
|
||||
from .dav.webdav import WebDAV
|
||||
from .helpers import (
|
||||
RE_TTF,
|
||||
EventDates,
|
||||
Random,
|
||||
list_fonts,
|
||||
list_images_auto,
|
||||
list_images_manual,
|
||||
load_image,
|
||||
|
@ -109,11 +112,46 @@ async def get_all_image_names(
|
|||
return auto_image_names
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class TTFont:
|
||||
# Dateiname
|
||||
file_name: str
|
||||
|
||||
# Schriftgröße für den Font
|
||||
size: int = 50
|
||||
|
||||
@property
|
||||
async def font(self) -> "ImageFont._Font":
|
||||
return ImageFont.truetype(
|
||||
font=BytesIO(await WebDAV.read_bytes(self.file_name)),
|
||||
size=100,
|
||||
)
|
||||
|
||||
|
||||
async def get_all_ttfonts(
|
||||
font_names: list[str] = Depends(list_fonts),
|
||||
) -> list[TTFont]:
|
||||
result = []
|
||||
|
||||
for name in font_names:
|
||||
assert (size_match := RE_TTF.search(name)) is not None
|
||||
|
||||
result.append(
|
||||
TTFont(
|
||||
file_name=name,
|
||||
size=int(size_match.group(1)),
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
async def gen_day_auto_image(
|
||||
day: int,
|
||||
cfg: Config,
|
||||
auto_image_names: dict[int, str],
|
||||
day_parts: dict[int, str],
|
||||
ttfonts: list[TTFont],
|
||||
) -> Image.Image:
|
||||
"""
|
||||
Automatisch generiertes Bild erstellen
|
||||
|
@ -125,18 +163,14 @@ async def gen_day_auto_image(
|
|||
|
||||
rnd = await Random.get(day)
|
||||
|
||||
font = ImageFont.truetype(
|
||||
font=BytesIO(await WebDAV.read_bytes("files/Lena.ttf")), # TODO
|
||||
size=100,
|
||||
)
|
||||
|
||||
# Buchstaben verstecken
|
||||
for letter in day_parts[day]:
|
||||
xy_range = range(cfg.image.border, (cfg.image.size - cfg.image.border))
|
||||
|
||||
await image.hide_text(
|
||||
xy=cast(_XY, tuple(rnd.choices(xy_range, k=2))),
|
||||
text=letter,
|
||||
font=font,
|
||||
font=await rnd.choice(ttfonts).font,
|
||||
)
|
||||
|
||||
return image.img
|
||||
|
@ -148,6 +182,7 @@ async def get_day_image(
|
|||
cfg: Config = Depends(get_config),
|
||||
auto_image_names: dict[int, str] = Depends(get_all_auto_image_names),
|
||||
day_parts: dict[int, str] = Depends(get_all_parts),
|
||||
ttfonts: list[TTFont] = Depends(get_all_ttfonts),
|
||||
) -> Image.Image | None:
|
||||
"""
|
||||
Bild für einen Tag abrufen
|
||||
|
@ -167,5 +202,9 @@ async def get_day_image(
|
|||
except RuntimeError:
|
||||
# Erstelle automatisch generiertes Bild
|
||||
return await gen_day_auto_image(
|
||||
day=day, cfg=cfg, auto_image_names=auto_image_names, day_parts=day_parts
|
||||
day=day,
|
||||
cfg=cfg,
|
||||
auto_image_names=auto_image_names,
|
||||
day_parts=day_parts,
|
||||
ttfonts=ttfonts,
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@ from .dav.webdav import WebDAV
|
|||
|
||||
T = TypeVar("T")
|
||||
RE_IMG = re.compile(r"\.(gif|jpe?g|tiff?|png|bmp)$", flags=re.IGNORECASE)
|
||||
RE_TTF = re.compile(r"\.(ttf)$", flags=re.IGNORECASE)
|
||||
RE_TTF = re.compile(r"_(\d+)\.ttf$", flags=re.IGNORECASE)
|
||||
|
||||
|
||||
class Random(random.Random):
|
||||
|
|
|
@ -7,7 +7,13 @@ from advent22_api.core.helpers import EventDates
|
|||
|
||||
from ..core.calendar_config import CalendarConfig, DoorsSaved, get_calendar_config
|
||||
from ..core.config import Config, Image, get_config
|
||||
from ..core.depends import get_all_event_dates, get_all_image_names, get_all_parts
|
||||
from ..core.depends import (
|
||||
TTFont,
|
||||
get_all_event_dates,
|
||||
get_all_image_names,
|
||||
get_all_parts,
|
||||
get_all_ttfonts,
|
||||
)
|
||||
from ..core.settings import SETTINGS, RedisSettings
|
||||
from ._security import require_admin, user_is_admin
|
||||
|
||||
|
@ -39,6 +45,10 @@ class ConfigModel(BaseModel):
|
|||
config_file: str
|
||||
background: str
|
||||
|
||||
class __Font(BaseModel):
|
||||
file: str
|
||||
size: int
|
||||
|
||||
class __WebDAV(BaseModel):
|
||||
url: str
|
||||
cache_ttl: int
|
||||
|
@ -48,6 +58,7 @@ class ConfigModel(BaseModel):
|
|||
puzzle: __Puzzle
|
||||
calendar: __Calendar
|
||||
image: Image
|
||||
fonts: list[__Font]
|
||||
redis: RedisSettings
|
||||
webdav: __WebDAV
|
||||
|
||||
|
@ -58,6 +69,7 @@ async def get_config_model(
|
|||
cfg: Config = Depends(get_config),
|
||||
cal_cfg: CalendarConfig = Depends(get_calendar_config),
|
||||
event_dates: EventDates = Depends(get_all_event_dates),
|
||||
ttfonts: list[TTFont] = Depends(get_all_ttfonts),
|
||||
) -> ConfigModel:
|
||||
"""
|
||||
Kombiniert aus privaten `settings`, `config` und `calendar_config`
|
||||
|
@ -83,6 +95,9 @@ async def get_config_model(
|
|||
"background": cal_cfg.background,
|
||||
},
|
||||
"image": cfg.image,
|
||||
"fonts": [
|
||||
{"file": ttfont.file_name, "size": ttfont.size} for ttfont in ttfonts
|
||||
],
|
||||
"redis": SETTINGS.redis,
|
||||
"webdav": {
|
||||
"url": SETTINGS.webdav.url,
|
||||
|
|
|
@ -101,10 +101,10 @@
|
|||
|
||||
<dt>Schriftarten</dt>
|
||||
<dd
|
||||
v-for="(font, index) in config_model.image.fonts"
|
||||
v-for="(font, index) in config_model.fonts"
|
||||
:key="`font-${index}`"
|
||||
>
|
||||
{{ font.file }} (Größe {{ font.size }})
|
||||
{{ font.file }} ({{ font.size }} pt)
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -200,8 +200,8 @@ export default class extends Vue {
|
|||
image: {
|
||||
size: 500,
|
||||
border: 0,
|
||||
fonts: [{ file: "consetetur", size: 0 }],
|
||||
},
|
||||
fonts: [{ file: "consetetur", size: 0 }],
|
||||
redis: {
|
||||
host: "0.0.0.0",
|
||||
port: 6379,
|
||||
|
|
|
@ -19,8 +19,8 @@ export interface ConfigModel {
|
|||
image: {
|
||||
size: number;
|
||||
border: number;
|
||||
fonts: { file: string; size: number }[];
|
||||
};
|
||||
fonts: { file: string; size: number }[];
|
||||
redis: {
|
||||
host: string;
|
||||
port: number;
|
||||
|
|
Loading…
Reference in a new issue