Gjennomgang: Stopp under syntese, planstatus, waitress, tester på HTTP-laget
Sju ting fra en gjennomgang av det som ble bygd i går. Stopp virket ikke mens lyden ble laget. Player.stop() drepte self.proc, men under syntesen finnes ingen prosess ennå – det er de første sekundene av hver edge-tts-melding – så knappen gjorde ingenting, og meldingen gikk ut etterpå. Nå har køen statusen preparing, stop() setter stopped på den, og run_once() sjekker det før den starter avspilling. UI-et viser «Lager lyd …» i stedet for å late som det spilles i stillhet. Planlagte sendinger løy om status. De ble markert «sendt» idet de ble lagt i kø, og ble stående slik selv om avspillingen feilet. Player har fått en on_finished-callback, og planen følger nå meldingen helt i mål: sent, failed eller stopped – det som faktisk skjedde. Statusene i schedule.py er utvidet tilsvarende (queued er «lagt i kø», sent er «spilt ferdig»). Flask sin utviklingsserver er byttet ut med waitress. Én prosess med mange tråder, med vilje: Player og planleggeren er singletons, så gunicorn med flere workere ville gitt flere køer som snakker i munnen på hverandre. HTTP-laget hadde null tester. import announcer startet tråder og dro inn Piper, så rutene lot seg ikke prøve. Trådene startes nå i main(), og run_once() driver køen ett steg om gangen. tests/test_routes.py dekker rutene, valideringen, køen, Stopp i begge faser, revisjonsloggen og hele planleggingsflyten gjennom HTTP. 30 nye tester, 110 totalt. Kappløp i synthesize(): tmp-fila hadde fast navn, så to som forhåndslyttet samme tekst samtidig skrev til samme fil, og den ene rename feilet. Unik tmp-fil per kall. verify_signature = false er fjernet. Det var en felle: én feilskrevet linje i config, og alle tokens ble godtatt. Ingen trenger den. docker compose up uten install.sh krasjet kryptisk ved første utrop, fordi Docker lagde data/ som root. check_writable() sier nå klart fra ved oppstart, med hva som må gjøres. Verifisert live i container: Stopp under edge-tts-syntese gir stopped, ikke done. Server-headeren er waitress sin, ikke werkzeugs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
04b3712ef5
commit
eb27a162d5
9 changed files with 565 additions and 81 deletions
19
AGENTS.md
19
AGENTS.md
|
|
@ -22,7 +22,7 @@ Filer:
|
|||
| `index.html` | hele sida, inline CSS/JS, ingen byggesteg |
|
||||
| `config.example.toml` | kommentert mal; kopier til `config.toml` |
|
||||
| `docs/crew-integration.md` | kontrakten mot crew-panelet |
|
||||
| `tests/test_auth.py` + `test_schedule.py` | `uv run pytest` – 80 tester |
|
||||
| `tests/` | `uv run pytest` – 110 tester: auth, planlegging og HTTP-laget |
|
||||
| `Dockerfile` + `compose.yaml` | **drift** – appen kjøres i Docker |
|
||||
| `.env.example` | bruker-ID, portbinding og hemmeligheter |
|
||||
| `compose.test.yaml` | testoppsett med dummy-IdP, se under |
|
||||
|
|
@ -254,6 +254,12 @@ satt i gang.
|
|||
- `/api/announce` legger meldingen i én FIFO-kø; en bakgrunnstråd spiller én om
|
||||
gangen med `pw-play`. `/api/stop` dreper gjeldende avspilling, `/api/clear`
|
||||
tømmer køen.
|
||||
- En melding går `queued → preparing → playing → done | stopped | failed`.
|
||||
`preparing` er syntesen – de første sekundene av hver edge-tts-melding, der
|
||||
det er stille. Stopp virker også der: `Player.stop()` setter statusen, og
|
||||
`run_once()` sjekker den før den starter avspilling. En planlagt sending
|
||||
følger med helt i mål via `on_finished`, så planen viser `sent`, `failed`
|
||||
eller `stopped` – det som faktisk skjedde – ikke bare at den ble lagt i kø.
|
||||
- `/api/status` krever `view`. Den var åpen før, og lekket både meldingstekster
|
||||
og IP-ene til dem som hadde sendt noe. IP vises nå bare for den som har
|
||||
`clear`; alle andre ser navnet.
|
||||
|
|
@ -301,9 +307,14 @@ Vil Kent ha enda bedre lyd: ElevenLabs (nøkkel, best norsk) eller OpenAI
|
|||
- `pkill -f announcer.py` fra et skall som selv har `announcer.py` i
|
||||
kommandolinja dreper skallet. Gjelder utvikling med `uv run`; i drift er
|
||||
det `docker compose`.
|
||||
- `player = Player()` står på modulnivå, så avspillingstråden starter ved
|
||||
`import announcer` – også i `install.sh`, som importerer modulen for å laste
|
||||
ned stemmer. Harmløst, men greit å vite.
|
||||
- Trådene (`player.start()`, `start_scheduler()`) startes i `main()`, ikke
|
||||
ved import. Det er det som gjør at `tests/test_routes.py` kan kjøre rutene
|
||||
med en test_client og drive køen ett steg om gangen med
|
||||
`player.run_once()`. Starter du dem ved import igjen, mister du den
|
||||
muligheten.
|
||||
- **Én prosess.** `main()` kjører waitress med mange tråder, ikke gunicorn
|
||||
med flere workere: `Player` og planleggeren er singletons i prosessen, og
|
||||
flere workere ville gitt flere køer som snakker i munnen på hverandre.
|
||||
- **Oppgradering:** `schedule` er en ny handling. Har et oppsett et eksplisitt
|
||||
`[roles]` i `config.toml`, får `crew` den *ikke* automatisk – eksplisitt
|
||||
konfigurasjon overstyrer standardverdiene, og da blir svaret 403 «Rollen din
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue