Spaces:
Runtime error
Runtime error
Refactor VideoTemplateEditor component: remove AI editing features and related state management, streamline template loading, and update styles for improved layout. Enhance CSS for responsive design and visual consistency across various components, including dropdowns, sync stats, and quiz elements. Remove deprecated premium badge styles and adjust layout for chat components.
66de9c8 Download backend/app/services/notestack_voices.py from firebird-technologies/NoteStack-Test: direct link, hf CLI and curl.
- Browser
- Download file 2.67 kB
-
https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/app/services/notestack_voices.py
- Command line
-
hf download hf://spaces/firebird-technologies/NoteStack-Test/backend/app/services/notestack_voices.py
-
curl -L -o notestack_voices.py https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/app/services/notestack_voices.py
2.67 kB
| """The workspace's own ElevenLabs voices, made or added on the Voice page: its clone, designed voices, and voices added | |
| from the ElevenLabs library. They speak audio overviews; video_voices lists them with the workspace's saved voices.""" | |
| import uuid | |
| from sqlalchemy import delete, select | |
| from sqlalchemy.orm import Session | |
| from app.models import UserSavedVoice, VoiceConsent, VoiceProfile | |
| def notestack_voices(db: Session, workspace_id: uuid.UUID) -> list[dict]: | |
| """[{voice_id, name, kind}], kind: clone | designed | library. The clone first, no repeats.""" | |
| out: list[dict] = [] | |
| consent = db.scalar(select(VoiceConsent).where(VoiceConsent.workspace_id == workspace_id, | |
| VoiceConsent.revoked_at.is_(None)) | |
| .order_by(VoiceConsent.created_at.desc())) | |
| if consent and consent.elevenlabs_voice_id: | |
| out.append({"voice_id": consent.elevenlabs_voice_id, "name": "My voice", "kind": "clone"}) | |
| vp = db.scalar(select(VoiceProfile).where(VoiceProfile.workspace_id == workspace_id)) | |
| voices = (vp.host_voices if vp else None) or {} | |
| for kind, key in (("designed", "custom"), ("library", "added")): | |
| for v in voices.get(key) or []: | |
| if v.get("voice_id") and all(o["voice_id"] != v["voice_id"] for o in out): | |
| out.append({"voice_id": v["voice_id"], "name": v.get("name") or "Voice", "kind": kind}) | |
| return out | |
| def is_notestack_voice(db: Session, workspace_id: uuid.UUID, voice_id: str) -> bool: | |
| return any(v["voice_id"] == voice_id for v in notestack_voices(db, workspace_id)) | |
| def save_notestack_voice(db: Session, workspace_id: uuid.UUID, voice_id: str, name: str) -> UserSavedVoice: | |
| """Put a Notestack voice in the workspace's voices (the one list for audio and video), once. Saving needs no plan; it speaks audio | |
| overviews (a video uses the free built-in voices). No preview link: it is played through /api/voice/preview. | |
| The caller commits.""" | |
| row = db.get(UserSavedVoice, {"workspace_id": workspace_id, "voice_id": voice_id}) | |
| if row is None: | |
| row = UserSavedVoice(workspace_id=workspace_id, voice_id=voice_id, name=(name or "Voice")[:255], premium=True, | |
| is_custom=True) | |
| db.add(row) | |
| return row | |
| def forget_video_voice(db: Session, workspace_id: uuid.UUID, voice_id: str) -> None: | |
| """A Notestack voice that is gone (clone revoked) leaves the workspace's saved video voices too.""" | |
| db.execute(delete(UserSavedVoice).where(UserSavedVoice.workspace_id == workspace_id, | |
| UserSavedVoice.voice_id == voice_id)) | |