Compare commits

..

5 commits

6 changed files with 102 additions and 89 deletions

View file

@ -8,6 +8,7 @@
- api/ui: Türchen mit Tag "0" einem zufälligen Tag zuweisen - api/ui: Türchen mit Tag "0" einem zufälligen Tag zuweisen
- api/?: Option "custom Zuordnung Buchstaben" (standard leer) - api/?: Option "custom Zuordnung Buchstaben" (standard leer)
- ui: `confirm` durch bulma Komponente(n) ersetzen - ui: `confirm` durch bulma Komponente(n) ersetzen
- halbautomatischer Modus: Finde Bilder wie "a.jpg" und "Z.png" und weise diese den passenden Tagen zu
# Erledigt # Erledigt

View file

@ -1,13 +1,11 @@
import re
import tomllib import tomllib
from enum import Enum
from random import Random
from markdown import markdown from markdown import markdown
from pydantic import BaseModel, ConfigDict, field_validator from pydantic import BaseModel, ConfigDict, field_validator
from .dav.webdav import WebDAV from .dav.webdav import WebDAV
from .settings import SETTINGS from .settings import SETTINGS
from .transformed_string import TransformedString
class User(BaseModel): class User(BaseModel):
@ -15,88 +13,6 @@ class User(BaseModel):
password: str password: str
class TransformedString(BaseModel):
class __Whitespace(str, Enum):
# unverändert
KEEP = "KEEP"
# Leerzeichen an Anfang und Ende entfernen
STRIP = "STRIP"
# whitespace durch Leerzeichen ersetzen
SPACE = "SPACE"
# whitespace entfernen
REMOVE = "REMOVE"
class __SpecialChars(str, Enum):
# unverändert
KEEP = "KEEP"
# Sonderzeichen entfernen
REMOVE = "REMOVE"
class __Case(str, Enum):
# unverändert
KEEP = "KEEP"
# GROSSBUCHSTABEN
UPPER = "UPPER"
# kleinbuchstaben
LOWER = "LOWER"
# ZuFÄllIg
RANDOM = "RANDOM"
value: str
whitespace: __Whitespace = __Whitespace.REMOVE
special_chars: __SpecialChars = __SpecialChars.REMOVE
case: __Case = __Case.UPPER
@field_validator("whitespace", "case", mode="before")
def transform_from_str(cls, v) -> str:
return str(v).upper()
@property
def clean(self) -> str:
result = self.value
# Whitespace verarbeiten
if self.whitespace is TransformedString.__Whitespace.STRIP:
result = result.strip()
elif self.whitespace is TransformedString.__Whitespace.SPACE:
result = re.sub(string=result, pattern=r"\s+", repl=" ")
elif self.whitespace is TransformedString.__Whitespace.REMOVE:
result = re.sub(string=result, pattern=r"\s+", repl="")
# Sonderzeichen verarbeiten
if self.special_chars is TransformedString.__SpecialChars.REMOVE:
result = re.sub(string=result, pattern=r"[^a-zA-Z0-9\s]+", repl="")
# Groß-/Kleinschreibung verarbeiten
if self.case is TransformedString.__Case.UPPER:
result = result.upper()
elif self.case is TransformedString.__Case.LOWER:
result = result.lower()
elif self.case is TransformedString.__Case.RANDOM:
rnd = Random(self.value)
def randomcase(c: str) -> str:
if rnd.choice((True, False)):
return c.upper()
return c.lower()
result = "".join(randomcase(c) for c in result)
return result
class Site(BaseModel): class Site(BaseModel):
model_config = ConfigDict(validate_default=True) model_config = ConfigDict(validate_default=True)

View file

@ -1,4 +1,5 @@
import re import re
from collections import defaultdict
from dataclasses import dataclass from dataclasses import dataclass
from datetime import date from datetime import date
from io import BytesIO from io import BytesIO
@ -71,9 +72,8 @@ async def get_all_parts(
*rnd.sample(days, solution_length % num_days), *rnd.sample(days, solution_length % num_days),
] ]
result: dict[int, str] = {} result: defaultdict[int, str] = defaultdict(str)
for day, letter in zip(solution_days, cfg.solution.clean): for day, letter in zip(solution_days, cfg.solution.clean):
result[day] = result.get(day, "")
result[day] += letter result[day] += letter
result |= {missed_day: "" for missed_day in set(days) - set(result.keys())} result |= {missed_day: "" for missed_day in set(days) - set(result.keys())}

View file

@ -171,7 +171,7 @@ class EventDates:
@property @property
def next(self) -> date | None: def next(self) -> date | None:
"""Datum des nächsten Ereignisses""" """Datum des nächsten Ereignisses"""
return self.get_next(today=datetime.today().date()) return self.get_next(today=date.today())
@property @property
def last(self) -> date: def last(self) -> date:

View file

@ -0,0 +1,96 @@
import re
from enum import Enum
from random import Random
from pydantic import BaseModel, field_validator
RE_WHITESPACE = re.compile(
pattern=r"\s+",
flags=re.UNICODE | re.IGNORECASE,
)
RE_SPECIAL_CHARS = re.compile(
pattern=r"[^a-zA-Z0-9\s]+",
flags=re.UNICODE | re.IGNORECASE,
)
class TransformedString(BaseModel):
class __Whitespace(str, Enum):
# unverändert
KEEP = "KEEP"
# Leerzeichen an Anfang und Ende entfernen
STRIP = "STRIP"
# whitespace durch Leerzeichen ersetzen
SPACE = "SPACE"
# whitespace entfernen
REMOVE = "REMOVE"
class __SpecialChars(str, Enum):
# unverändert
KEEP = "KEEP"
# Sonderzeichen entfernen
REMOVE = "REMOVE"
class __Case(str, Enum):
# unverändert
KEEP = "KEEP"
# GROSSBUCHSTABEN
UPPER = "UPPER"
# kleinbuchstaben
LOWER = "LOWER"
# ZuFÄllIg
RANDOM = "RANDOM"
value: str
whitespace: __Whitespace = __Whitespace.REMOVE
special_chars: __SpecialChars = __SpecialChars.REMOVE
case: __Case = __Case.UPPER
@field_validator("whitespace", "case", mode="before")
def transform_from_str(cls, v) -> str:
return str(v).upper()
@property
def clean(self) -> str:
result = self.value
# Whitespace verarbeiten
if self.whitespace is TransformedString.__Whitespace.STRIP:
result = result.strip()
elif self.whitespace is TransformedString.__Whitespace.SPACE:
result = RE_WHITESPACE.sub(string=result, repl=" ")
elif self.whitespace is TransformedString.__Whitespace.REMOVE:
result = RE_WHITESPACE.sub(string=result, repl="")
# Sonderzeichen verarbeiten
if self.special_chars is TransformedString.__SpecialChars.REMOVE:
result = RE_SPECIAL_CHARS.sub(string=result, repl="")
# Groß-/Kleinschreibung verarbeiten
if self.case is TransformedString.__Case.UPPER:
result = result.upper()
elif self.case is TransformedString.__Case.LOWER:
result = result.lower()
elif self.case is TransformedString.__Case.RANDOM:
rnd = Random(self.value)
def randomcase(c: str) -> str:
if rnd.choice((True, False)):
return c.upper()
return c.lower()
result = "".join(randomcase(c) for c in result)
return result

View file

@ -6,7 +6,7 @@
</div> </div>
</section> </section>
<section class="section"> <section class="section px-3">
<div class="container"> <div class="container">
<AdminView v-if="store.is_admin" /> <AdminView v-if="store.is_admin" />
<UserView v-else /> <UserView v-else />