81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
|
|
"""Shared web helpers: Jinja templates, redirects, Bosnian labels."""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from pathlib import Path
|
|||
|
|
from urllib.parse import quote
|
|||
|
|
|
|||
|
|
from fastapi.responses import RedirectResponse
|
|||
|
|
from fastapi.templating import Jinja2Templates
|
|||
|
|
|
|||
|
|
templates = Jinja2Templates(directory=str(Path(__file__).parent / "templates"))
|
|||
|
|
|
|||
|
|
STATUS_LABELS = {
|
|||
|
|
"pending": "na čekanju",
|
|||
|
|
"resolved_by_owner": "riješeno",
|
|||
|
|
"confirmed": "potvrđeno",
|
|||
|
|
"rejected": "odbijeno",
|
|||
|
|
"expired": "isteklo",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
OUTCOME_LABELS = {
|
|||
|
|
"human_answered": "javilo se osoblje",
|
|||
|
|
"request_created": "zahtjev kreiran",
|
|||
|
|
"info_only": "informacija",
|
|||
|
|
"message_taken": "poruka",
|
|||
|
|
"abandoned": "prekinut",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DAY_LABELS = [
|
|||
|
|
("mon", "Ponedjeljak"),
|
|||
|
|
("tue", "Utorak"),
|
|||
|
|
("wed", "Srijeda"),
|
|||
|
|
("thu", "Četvrtak"),
|
|||
|
|
("fri", "Petak"),
|
|||
|
|
("sat", "Subota"),
|
|||
|
|
("sun", "Nedjelja"),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
# Curated TTS voices (§10.5) — final list confirmed by the Phase-0 PoC bake-off.
|
|||
|
|
TTS_VOICES = [
|
|||
|
|
{"id": "azure:sr-RS-SophieNeural", "label": "Sofija — ženski, topao (Azure)"},
|
|||
|
|
{"id": "azure:sr-RS-NicholasNeural", "label": "Nikola — muški, smiren (Azure)"},
|
|||
|
|
{"id": "azure:hr-HR-GabrijelaNeural", "label": "Gabrijela — ženski, vedar (Azure)"},
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
|
|||
|
|
def redirect(url: str, msg: str = "", err: str = "") -> RedirectResponse:
|
|||
|
|
if msg:
|
|||
|
|
url += ("&" if "?" in url else "?") + "msg=" + quote(msg)
|
|||
|
|
if err:
|
|||
|
|
url += ("&" if "?" in url else "?") + "err=" + quote(err)
|
|||
|
|
return RedirectResponse(url, status_code=303)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def hours_to_text(working_hours: dict) -> dict[str, str]:
|
|||
|
|
"""{'mon': [['09:00','13:00'],['14:00','18:00']]} → {'mon': '09:00-13:00, 14:00-18:00'}"""
|
|||
|
|
out = {}
|
|||
|
|
for key, _label in DAY_LABELS:
|
|||
|
|
intervals = (working_hours or {}).get(key, [])
|
|||
|
|
out[key] = ", ".join(f"{a}-{b}" for a, b in intervals)
|
|||
|
|
return out
|
|||
|
|
|
|||
|
|
|
|||
|
|
def text_to_intervals(text: str) -> list[list[str]]:
|
|||
|
|
"""'09:00-13:00, 14:00-18:00' → [['09:00','13:00'],['14:00','18:00']]; '' → []"""
|
|||
|
|
import re
|
|||
|
|
|
|||
|
|
intervals = []
|
|||
|
|
for part in text.split(","):
|
|||
|
|
part = part.strip()
|
|||
|
|
if not part:
|
|||
|
|
continue
|
|||
|
|
m = re.match(r"^(\d{1,2})(?::(\d{2}))?\s*[-–]\s*(\d{1,2})(?::(\d{2}))?$", part)
|
|||
|
|
if not m:
|
|||
|
|
raise ValueError(f"Neispravan format: '{part}' (očekivano npr. 09:00-18:00)")
|
|||
|
|
h1, m1, h2, m2 = m.groups()
|
|||
|
|
a = f"{int(h1):02d}:{m1 or '00'}"
|
|||
|
|
b = f"{int(h2):02d}:{m2 or '00'}"
|
|||
|
|
intervals.append([a, b])
|
|||
|
|
return intervals
|