feat: US-009 - Autocomplete voci din catalog pentru /audio și /voice setvoice
- tools/tts.py: +list_voice_names(engine=None), sursă live din tts_voices.json - src/fast_commands.py: _VOICES statice -> _supertonic_voice_names() din catalog - discord_bot.py /audio și discord_voice.py /voice setvoice: choices statice -> autocomplete live - gates rulate: tests PASS (1043 passed, 22 eșecuri preexistente neschimbate), ui/backend review PASS manual
This commit is contained in:
@@ -140,6 +140,19 @@ def _parse_registered_voice_name(stdout: str) -> Optional[str]:
|
||||
return m.group(1) if m else None
|
||||
|
||||
|
||||
def _tts_voice_names() -> list[str]:
|
||||
"""Nume de voci din tts_voices.json (import lazy din tools/tts.py, catalog live)."""
|
||||
import sys as _sys
|
||||
tools_dir = str(PROJECT_ROOT / "tools")
|
||||
if tools_dir not in _sys.path:
|
||||
_sys.path.insert(0, tools_dir)
|
||||
try:
|
||||
import tts as _tts_mod
|
||||
return _tts_mod.list_voice_names()
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
|
||||
def _tts_synthesize_preview(text: str, voice: str) -> dict:
|
||||
"""Import tools/tts.py (nu e package, sys.path trick) și generează un preview audio."""
|
||||
import sys as _sys
|
||||
@@ -301,20 +314,27 @@ def register(tree: app_commands.CommandTree, bot: discord.Client) -> app_command
|
||||
log.warning("Presence reset skipped", exc_info=True)
|
||||
await interaction.followup.send("Plecat.", ephemeral=True)
|
||||
|
||||
_VOICE_CHOICES = [
|
||||
app_commands.Choice(name=v, value=v)
|
||||
for v in ("M1", "M2", "M3", "M4", "M5", "F1", "F2", "F3", "F4", "F5")
|
||||
]
|
||||
async def _voice_autocomplete(
|
||||
interaction: discord.Interaction, current: str
|
||||
) -> list[app_commands.Choice[str]]:
|
||||
current_low = (current or "").lower()
|
||||
names = [n for n in _tts_voice_names() if current_low in n.lower()]
|
||||
return [app_commands.Choice(name=n, value=n) for n in names[:25]]
|
||||
|
||||
@voice_group.command(name="setvoice", description="Schimbă vocea Echo (M1-M5 sau F1-F5)")
|
||||
@voice_group.command(name="setvoice", description="Schimbă vocea Echo (din catalogul tts_voices.json)")
|
||||
@app_commands.describe(voice="Voce nouă")
|
||||
@app_commands.choices(voice=_VOICE_CHOICES)
|
||||
@app_commands.autocomplete(voice=_voice_autocomplete)
|
||||
async def setvoice(
|
||||
interaction: discord.Interaction,
|
||||
voice: app_commands.Choice[str],
|
||||
voice: str,
|
||||
) -> None:
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
new_voice = voice.value
|
||||
if voice not in _tts_voice_names():
|
||||
await interaction.followup.send(
|
||||
f"Voce necunoscută: {voice!r}. Alege din autocomplete.", ephemeral=True
|
||||
)
|
||||
return
|
||||
new_voice = voice
|
||||
# Live-swap on the active session if Echo is in voice on this guild.
|
||||
guild_id = interaction.guild.id if interaction.guild else None
|
||||
session = _voice_sessions.get(guild_id) if guild_id is not None else None
|
||||
|
||||
Reference in New Issue
Block a user