unified data - step 1
This commit is contained in:
parent
8b161ed410
commit
96c94fae57
2 changed files with 0 additions and 132 deletions
|
|
@ -14,7 +14,6 @@ from modules.features.workspace.datamodelFeatureWorkspace import WorkspaceUserSe
|
|||
from modules.interfaces.interfaceRbac import getRecordsetWithRBAC
|
||||
from modules.security.rbac import RbacClass
|
||||
from modules.shared.configuration import APP_CONFIG
|
||||
from modules.shared.timeUtils import getUtcTimestamp
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
|||
|
|
@ -1582,137 +1582,6 @@ async def synthesizeVoice(
|
|||
return JSONResponse({"audio": None, "note": "TTS via browser Speech Synthesis API recommended"})
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# Voice Settings Endpoints
|
||||
# =========================================================================
|
||||
|
||||
@router.get("/{instanceId}/settings/voice")
|
||||
@limiter.limit("120/minute")
|
||||
async def getVoiceSettings(
|
||||
request: Request,
|
||||
instanceId: str = Path(...),
|
||||
context: RequestContext = Depends(getRequestContext),
|
||||
):
|
||||
"""Load voice settings for the current user and instance."""
|
||||
_validateInstanceAccess(instanceId, context)
|
||||
wsInterface = _getWorkspaceInterface(context, instanceId)
|
||||
userId = str(context.user.id)
|
||||
try:
|
||||
vs = wsInterface.getVoiceSettings(userId)
|
||||
if not vs:
|
||||
logger.info(f"GET voice settings: not found for user={userId}, creating defaults")
|
||||
vs = wsInterface.getOrCreateVoiceSettings(userId)
|
||||
result = vs.model_dump() if vs else {}
|
||||
mapKeys = list(result.get("ttsVoiceMap", {}).keys()) if result else []
|
||||
logger.info(f"GET voice settings for user={userId}: ttsVoiceMap languages={mapKeys}")
|
||||
return JSONResponse(result)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load voice settings for user={userId}: {e}", exc_info=True)
|
||||
return JSONResponse({"ttsVoiceMap": {}}, status_code=200)
|
||||
|
||||
|
||||
@router.put("/{instanceId}/settings/voice")
|
||||
@limiter.limit("120/minute")
|
||||
async def updateVoiceSettings(
|
||||
request: Request,
|
||||
instanceId: str = Path(...),
|
||||
body: dict = Body(...),
|
||||
context: RequestContext = Depends(getRequestContext),
|
||||
):
|
||||
"""Update voice settings for the current user and instance."""
|
||||
_validateInstanceAccess(instanceId, context)
|
||||
wsInterface = _getWorkspaceInterface(context, instanceId)
|
||||
userId = str(context.user.id)
|
||||
|
||||
try:
|
||||
logger.info(f"PUT voice settings for user={userId}, instance={instanceId}, body keys={list(body.keys())}")
|
||||
vs = wsInterface.getVoiceSettings(userId)
|
||||
if not vs:
|
||||
logger.info(f"No existing voice settings, creating new for user={userId}")
|
||||
createData = {
|
||||
"userId": userId,
|
||||
"mandateId": str(context.mandateId) if context.mandateId else "",
|
||||
"featureInstanceId": instanceId,
|
||||
}
|
||||
createData.update(body)
|
||||
created = wsInterface.createVoiceSettings(createData)
|
||||
logger.info(f"Created voice settings for user={userId}, ttsVoiceMap keys={list((created or {}).get('ttsVoiceMap', {}).keys())}")
|
||||
return JSONResponse(created)
|
||||
|
||||
updateData = {k: v for k, v in body.items() if k not in ("id", "userId", "mandateId", "featureInstanceId", "creationDate")}
|
||||
logger.info(f"Updating voice settings for user={userId}, update keys={list(updateData.keys())}")
|
||||
updated = wsInterface.updateVoiceSettings(userId, updateData)
|
||||
logger.info(f"Updated voice settings for user={userId}, ttsVoiceMap keys={list((updated or {}).get('ttsVoiceMap', {}).keys())}")
|
||||
return JSONResponse(updated)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update voice settings for user={userId}: {e}", exc_info=True)
|
||||
return JSONResponse({"error": str(e)}, status_code=500)
|
||||
|
||||
|
||||
@router.get("/{instanceId}/voice/languages")
|
||||
@limiter.limit("120/minute")
|
||||
async def getVoiceLanguages(
|
||||
request: Request,
|
||||
instanceId: str = Path(...),
|
||||
context: RequestContext = Depends(getRequestContext),
|
||||
):
|
||||
"""Return available TTS languages."""
|
||||
mandateId, _ = _validateInstanceAccess(instanceId, context)
|
||||
from modules.interfaces.interfaceVoiceObjects import getVoiceInterface
|
||||
voiceInterface = getVoiceInterface(context.user, mandateId)
|
||||
languagesResult = await voiceInterface.getAvailableLanguages()
|
||||
languageList = languagesResult.get("languages", []) if isinstance(languagesResult, dict) else languagesResult
|
||||
return JSONResponse({"languages": languageList})
|
||||
|
||||
|
||||
@router.get("/{instanceId}/voice/voices")
|
||||
@limiter.limit("120/minute")
|
||||
async def getVoiceVoices(
|
||||
request: Request,
|
||||
instanceId: str = Path(...),
|
||||
language: str = Query("de-DE"),
|
||||
context: RequestContext = Depends(getRequestContext),
|
||||
):
|
||||
"""Return available TTS voices for a given language."""
|
||||
mandateId, _ = _validateInstanceAccess(instanceId, context)
|
||||
from modules.interfaces.interfaceVoiceObjects import getVoiceInterface
|
||||
voiceInterface = getVoiceInterface(context.user, mandateId)
|
||||
voicesResult = await voiceInterface.getAvailableVoices(language)
|
||||
voiceList = voicesResult.get("voices", []) if isinstance(voicesResult, dict) else voicesResult
|
||||
return JSONResponse({"voices": voiceList})
|
||||
|
||||
|
||||
@router.post("/{instanceId}/voice/test")
|
||||
@limiter.limit("30/minute")
|
||||
async def testVoice(
|
||||
request: Request,
|
||||
instanceId: str = Path(...),
|
||||
body: dict = Body(...),
|
||||
context: RequestContext = Depends(getRequestContext),
|
||||
):
|
||||
"""Test a specific voice with a sample text."""
|
||||
import base64
|
||||
mandateId, _ = _validateInstanceAccess(instanceId, context)
|
||||
text = body.get("text", "Hallo, das ist ein Stimmtest.")
|
||||
language = body.get("language", "de-DE")
|
||||
voiceId = body.get("voiceId")
|
||||
|
||||
from modules.interfaces.interfaceVoiceObjects import getVoiceInterface
|
||||
voiceInterface = getVoiceInterface(context.user, mandateId)
|
||||
|
||||
try:
|
||||
result = await voiceInterface.textToSpeech(text=text, languageCode=language, voiceName=voiceId)
|
||||
if result and isinstance(result, dict):
|
||||
audioContent = result.get("audioContent")
|
||||
if audioContent:
|
||||
audioB64 = base64.b64encode(
|
||||
audioContent if isinstance(audioContent, bytes) else audioContent.encode()
|
||||
).decode()
|
||||
return JSONResponse({"success": True, "audio": audioB64, "format": "mp3", "text": text})
|
||||
return JSONResponse({"success": False, "error": "TTS returned no audio"})
|
||||
except Exception as e:
|
||||
logger.error(f"Voice test failed: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"TTS test failed: {str(e)}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
|
|
|
|||
Loading…
Reference in a new issue