tts_warm: forvarm menuens intro-replikker først i --budget-køen
Introen pr. spil (navn, tagline og trin, standardstemmen) er præcis den tekst, /host/intro/<spil> sender til tts.synth, så cache-nøglen passer. Den står først i budget-køen før Tegn og Gæts replikker og følger --budget, --reserve og --only (kun det valgte spils intro). Uden --budget siger kommandoen, hvor mange der mangler; --dry-run tæller dem. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ from django.conf import settings
|
||||
|
||||
from fupogfakta.engine import RULES, RULES_FEST
|
||||
from fupogfakta.models import Category, Question
|
||||
from party import tts
|
||||
from party import games, tts
|
||||
from party.narrator import LINES, TEASES, TEASES_FEST, Narrator, speakable_prompt
|
||||
from party.tegn import warm_texts as tegn_texts
|
||||
|
||||
@@ -24,7 +24,8 @@ class Command(BaseCommand):
|
||||
help = ("Genererer speakerens replikker på forhånd. Uden --budget: kun de faste replikker (gratis, når de findes). "
|
||||
"Med --budget N: derefter op til N tegn af spørgsmålenes oplæsning og forklaring (de mindst brugte først, "
|
||||
"dvs. dem der kommer næste gang) og kategori-replikkerne. Køres om natten, så kvoten fordeles. "
|
||||
"Tegn og Gæts replikker står først i budget-køen (de tæller med i --budget og --reserve).")
|
||||
"Menuens intro-replikker og Tegn og Gæts replikker står først i budget-køen (de tæller med i --budget "
|
||||
"og --reserve).")
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("--budget", type=int, default=0, help="højst så mange nye tegn ud over de faste replikker")
|
||||
@@ -42,7 +43,11 @@ class Command(BaseCommand):
|
||||
# (navn, tekster, stemme). Tegn og Gæt (almindelig speaker) laves kun under --budget, først i køen,
|
||||
# så forvarmningen aldrig bruger af reserven; i --dry-run tælles de med her.
|
||||
tegn = tegn_texts() if only != "fof" else []
|
||||
groups = [("faste Tegn og Gæt-replikker", tegn, None)] if tegn and dry_run else []
|
||||
# menuens intro pr. spil (standardstemmen, som /host/intro/<spil>); med --only kun det spils
|
||||
intros = [g.intro() for g in games.GAMES.values() if only in (None, g.key)]
|
||||
first = [("menuens intro-replikker", intros), ("Tegn og Gæt", tegn)]
|
||||
groups = [("menuens intro-replikker", intros, None)] if dry_run else []
|
||||
groups += [("faste Tegn og Gæt-replikker", tegn, None)] if tegn and dry_run else []
|
||||
if only != "tegn":
|
||||
static = [line for k, variants in LINES.items() if not k.endswith("_fest")
|
||||
for line in variants if not re.search(r"\{\w+\}", line)]
|
||||
@@ -67,9 +72,11 @@ class Command(BaseCommand):
|
||||
ok = sum(1 for line in texts if tts.synth_sync(line, voice))
|
||||
self.stdout.write(self.style.SUCCESS(f"{ok} af {len(texts)} {name} ligger i cachen."))
|
||||
if budget <= 0:
|
||||
if tegn:
|
||||
missing = sum(1 for t in tegn if not tts.is_cached(t))
|
||||
self.stdout.write(f"Tegn og Gæt: {missing} af {len(tegn)} replikker mangler; de laves kun med --budget.")
|
||||
for name, texts in first:
|
||||
if texts:
|
||||
missing = sum(1 for t in texts if not tts.is_cached(t))
|
||||
self.stdout.write(f"{name[0].upper() + name[1:]}: {missing} af {len(texts)} replikker mangler; "
|
||||
"de laves kun med --budget.")
|
||||
return
|
||||
left = tts.credits_left()
|
||||
if left is not None:
|
||||
@@ -78,7 +85,7 @@ class Command(BaseCommand):
|
||||
if budget <= 0:
|
||||
return
|
||||
|
||||
queue = [(t, None) for t in tegn] + (self._fof_queue(fest) if only != "tegn" else [])
|
||||
queue = [(t, None) for t in intros + tegn] + (self._fof_queue(fest) if only != "tegn" else [])
|
||||
|
||||
spent = made = cached = 0
|
||||
for text, voice in queue:
|
||||
|
||||
@@ -12,7 +12,7 @@ from django.core.management import call_command
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
|
||||
from fupogfakta.engine import RULES as FOF_RULES
|
||||
from party import tts
|
||||
from party import games, tts
|
||||
from tegnoggaet.engine import RULES as TEGN_RULES
|
||||
from party.narrator import LINES as FOF_LINES, TEASES, Narrator
|
||||
from party.tegn import COUNT_LINES, FIXED_LINES, LINES, THEME_LINES, TegnRoom, warm_texts
|
||||
@@ -131,6 +131,7 @@ class TegnWarmTextTests(SimpleTestCase):
|
||||
|
||||
|
||||
FOF_QUEUE = [("fup og fakta-spørgsmål", None)] # Fup og Fakta's budget-kø (kræver databasen; erstattes her)
|
||||
INTROS = [g.intro() for g in games.GAMES.values()] # menuens intro, én pr. spil
|
||||
|
||||
|
||||
@override_settings(ELEVENLABS_API_KEY="nøgle", ELEVENLABS_VOICE_ID="stemme", FEST_VOICE_ID="")
|
||||
@@ -158,15 +159,16 @@ class TtsWarmCommandTests(SimpleTestCase):
|
||||
self.assertEqual(calls, fof_static())
|
||||
self.assertIn(f"{len(fof_static())} af {len(fof_static())} faste replikker ligger i cachen.", out)
|
||||
self.assertIn(f"Tegn og Gæt: {len(warm_texts())} af {len(warm_texts())} replikker mangler; de laves kun med --budget.", out)
|
||||
self.assertIn(f"Menuens intro-replikker: {len(INTROS)} af {len(INTROS)} replikker mangler", out)
|
||||
|
||||
def test_budget_makes_tegn_first_then_the_fof_queue(self):
|
||||
def test_budget_makes_intros_and_tegn_first_then_the_fof_queue(self):
|
||||
calls, voices, out = self.run_cmd("--budget", "100000", credits=10**6)
|
||||
self.assertEqual(calls, fof_static() + warm_texts() + [t for t, _ in FOF_QUEUE])
|
||||
self.assertEqual(calls, fof_static() + INTROS + warm_texts() + [t for t, _ in FOF_QUEUE])
|
||||
self.assertEqual(voices, {None}) # samme stemme som rummet
|
||||
|
||||
def test_budget_stops_tegn_at_the_budget(self):
|
||||
calls, _, out = self.run_cmd("--only", "tegn", "--budget", "300", credits=10**6)
|
||||
tegn = warm_texts()
|
||||
tegn = [games.GAMES["tegn"].intro()] + warm_texts()
|
||||
self.assertEqual(calls, tegn[:len(calls)]) # i rækkefølge, fra starten
|
||||
self.assertLessEqual(sum(map(len, calls)), 300)
|
||||
self.assertGreater(sum(map(len, tegn[:len(calls) + 1])), 300)
|
||||
@@ -181,10 +183,10 @@ class TtsWarmCommandTests(SimpleTestCase):
|
||||
calls, _, out = self.run_cmd("--only", "tegn")
|
||||
self.assertEqual(calls, [])
|
||||
self.assertIn("laves kun med --budget", out)
|
||||
calls, _, _ = self.run_cmd("--only", "tegn", "--budget", "12000", credits=10**6)
|
||||
self.assertEqual(calls, warm_texts()) # 286 klip, 11771 tegn
|
||||
calls, _, _ = self.run_cmd("--only", "tegn", "--budget", "13000", credits=10**6)
|
||||
self.assertEqual(calls, [games.GAMES["tegn"].intro()] + warm_texts()) # 287 klip
|
||||
calls, _, out = self.run_cmd("--only", "fof", "--budget", "100000", credits=10**6)
|
||||
self.assertEqual(calls, fof_static() + [t for t, _ in FOF_QUEUE])
|
||||
self.assertEqual(calls, fof_static() + [games.GAMES["fof"].intro()] + [t for t, _ in FOF_QUEUE])
|
||||
self.assertNotIn("Tegn og Gæt", out)
|
||||
|
||||
@override_settings(ELEVENLABS_API_KEY="", ELEVENLABS_VOICE_ID="")
|
||||
@@ -193,6 +195,8 @@ class TtsWarmCommandTests(SimpleTestCase):
|
||||
self.assertEqual(calls, [])
|
||||
tegn = warm_texts()
|
||||
self.assertIn(f"faste Tegn og Gæt-replikker: {len(tegn)} klip, {sum(map(len, tegn))} tegn", out)
|
||||
tegn_intro = games.GAMES["tegn"].intro()
|
||||
self.assertIn(f"menuens intro-replikker: 1 klip, {len(tegn_intro)} tegn", out)
|
||||
calls, _, out = self.run_cmd("--dry-run", "--budget", "500")
|
||||
self.assertEqual(calls, [])
|
||||
self.assertIn(f"faste replikker: {len(fof_static())} klip", out)
|
||||
|
||||
Reference in New Issue
Block a user