«Send denne kl. 18:00.» Engangs, ikke gjentakende. Dette er den første delen av appen som må ligge på disk. Kø og historikk har alltid bare levd i minnet, og det har gått bra fordi en melding spilles med en gang. En melding planlagt til 18:00 må overleve at containeren startes om 17:45, så schedule.py lagrer i data/scheduled.json – skrevet til side og flyttet på plass, så fila aldri er halvskrevet. Ingen database, med vilje: dette er en håndfull meldinger på et arrangement, og en fil man kan lese med cat er verdt mer her enn indekser. En ødelagt fil hindrer ikke oppstart; da er det bedre å miste planene og si det i loggen. Modulen vet ingenting om Flask eller avspilling. Den lagrer, og den svarer på «hva skal sendes nå?». _scheduler() i announcer.py eier tråden som spør hvert 20. sekund og legger forfalte meldinger i den vanlige køen – derfra oppfører de seg nøyaktig som en melding sendt for hånd. Gikk den glipp av, spilles den ikke. due() skiller på grace_seconds (120): innenfor den sendes meldingen, utenfor markeres den missed og vises som det. Nådefristen er slingringsmonn for at tråden våkner med mellomrom og for en kjapp omstart, ikke en policy om å ta igjen etterslep – «turneringen starter om ti minutter» skal ikke ut på anlegget en time etter at maskina kom tilbake. due() endrer ingenting selv; markeringen skjer først etter at meldingen faktisk er i kø, så ingenting kan stå som «sendt» uten å ha blitt det. Klienten sender absolutt tidspunkt (epoch), så tidssoner spiller ingen rolle for selve planleggingen. TZ settes likevel fra .env, ellers står loggen i UTC mens man selv står i CEST. Planlegging er låst til samme forhåndslytt-nøkkel som «Send ut»: man planlegger bare det man har hørt. Det gir en bonus – forhåndslytt varmer cache/, så WAV-en ligger ferdig på disk, og en planlagt edge-tts-melding spiller kl. 18:00 selv om nettet er nede da. Sine egne kan man alltid avbryte. Andres krever clear, samme rett som å tømme køen, siden det er samme slags inngrep i noe andre har satt i gang. 23 nye tester. Verifisert i container: sending fyrer og spiller, overlever en omstart av containeren, og en melding som forfalt mens maskina var av blir markert missed uten å bli spilt. Merk ved oppgradering: schedule er en ny handling, og et oppsett med eksplisitt [roles] i config.toml får den ikke automatisk. Den må legges inn selv. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
39 lines
1.1 KiB
TOML
39 lines
1.1 KiB
TOML
# Konfigurasjon for docker compose-testingen. Alle tre innloggingsmetodene er
|
||
# på samtidig, noe man nok ikke vil i virkeligheten, men her er poenget å
|
||
# kunne prøve dem.
|
||
#
|
||
# Hemmelighetene settes som miljøvariabler i compose.yaml, ikke her.
|
||
|
||
[app]
|
||
title = "Announcer Test"
|
||
subtitle = "Docker-oppsett – PIN, JWT og OIDC er alle slått på"
|
||
accent = "#f5a623"
|
||
quick_phrases = ["Dette er en test", "Pizzaen er kommet. Hent i kantina!"]
|
||
|
||
[auth]
|
||
providers = ["oidc", "jwt", "pin"]
|
||
|
||
[auth.pin]
|
||
pin = "1234"
|
||
role = "crew"
|
||
hint = "1234 i dette testoppsettet"
|
||
|
||
[auth.jwt]
|
||
issuer = "http://localhost:9000"
|
||
audience = "announcer"
|
||
role_claim = "roles"
|
||
|
||
[auth.oidc]
|
||
issuer = "http://localhost:9000"
|
||
client_id = "announcer"
|
||
label = "Logg inn med dummy-IdP"
|
||
# Delt horisont: nettleseren ser IdP-en som localhost:9000, mens announcer
|
||
# selv snakker med den som idp:9000 inne i compose-nettet. Derfor settes
|
||
# endepunktene manuelt istedenfor å bruke discovery.
|
||
authorization_endpoint = "http://localhost:9000/oauth/authorize"
|
||
token_endpoint = "http://idp:9000/oauth/token"
|
||
|
||
[roles]
|
||
anonymous = ["view"]
|
||
crew = ["view", "preview", "announce", "schedule"]
|
||
admin = ["*"]
|