diff --git a/services/api/app/main.py b/services/api/app/main.py index e11fdfa..9010570 100644 --- a/services/api/app/main.py +++ b/services/api/app/main.py @@ -1,6 +1,7 @@ import asyncio import hashlib import json +import re import secrets import smtplib import ssl @@ -729,6 +730,17 @@ def get_tts_task(task_id: UUID, user: dict = Depends(current_user), connection: return task_view(connection, owned_task(task_id, user, connection)) +def tts_download_name(task: dict, voice_name: str | None, mime_type: str) -> str: + ext = "mp3" if mime_type == "audio/mpeg" else "wav" + raw = unicodedata.normalize("NFC", task["text"] or "") + raw = re.sub(r"\s+", "", raw) + raw = re.sub(r'[\\/:*?"<>|]', "", raw) + summary = raw[:16] or "tts" + voice = re.sub(r'[\\/:*?"<>|]', "", voice_name or "")[:16] or "voice" + date = task["created_at"].strftime("%Y%m%d") + return f"{summary}_{voice}_{date}.{ext}" + + def audio_response(task_id: UUID, user: dict, connection: Connection, download: bool): task = owned_task(task_id, user, connection) audio = connection.execute("SELECT * FROM audio_files WHERE task_id = %s AND status = 'available'", (task_id,)).fetchone() @@ -737,7 +749,10 @@ def audio_response(task_id: UUID, user: dict, connection: Connection, download: path = Path(settings.audio_storage_dir) / audio["storage_key"] if not path.is_file(): raise error("AUDIO_NOT_AVAILABLE", "音频文件不可用", 404) - filename = f"kaotings-{task_id}.{'mp3' if audio['mime_type'] == 'audio/mpeg' else 'wav'}" if download else None + filename = None + if download: + voice = connection.execute("SELECT name FROM tts_voices WHERE provider_voice_id = %s", (task["provider_voice_id"],)).fetchone() + filename = tts_download_name(task, voice["name"] if voice else None, audio["mime_type"]) return FileResponse(path, media_type=audio["mime_type"], filename=filename)