generated from Labyricorn/labyricorn-project-template
Initial commit (forked from jamiepine/voicebox)
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""
|
||||
Server-side user settings — singleton rows persisted in SQLite so every
|
||||
client window, API consumer, and headless flow reads the same preferences.
|
||||
|
||||
Two domains live here: capture/refine defaults and long-form generation
|
||||
defaults. Each has a ``get_*`` that lazily creates the row with defaults and
|
||||
an ``update_*`` that accepts a partial payload.
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..database import CaptureSettings as DBCaptureSettings
|
||||
from ..database import GenerationSettings as DBGenerationSettings
|
||||
from ..utils.capture_chords import (
|
||||
default_push_to_talk_chord,
|
||||
default_toggle_to_talk_chord,
|
||||
)
|
||||
|
||||
|
||||
SINGLETON_ID = 1
|
||||
|
||||
|
||||
def _get_or_create_capture_row(db: Session) -> DBCaptureSettings:
|
||||
row = db.query(DBCaptureSettings).filter(DBCaptureSettings.id == SINGLETON_ID).first()
|
||||
if row is None:
|
||||
row = DBCaptureSettings(
|
||||
id=SINGLETON_ID,
|
||||
chord_push_to_talk_keys=default_push_to_talk_chord(),
|
||||
chord_toggle_to_talk_keys=default_toggle_to_talk_chord(),
|
||||
)
|
||||
db.add(row)
|
||||
db.commit()
|
||||
db.refresh(row)
|
||||
return row
|
||||
|
||||
|
||||
def _get_or_create_generation_row(db: Session) -> DBGenerationSettings:
|
||||
row = db.query(DBGenerationSettings).filter(DBGenerationSettings.id == SINGLETON_ID).first()
|
||||
if row is None:
|
||||
row = DBGenerationSettings(id=SINGLETON_ID)
|
||||
db.add(row)
|
||||
db.commit()
|
||||
db.refresh(row)
|
||||
return row
|
||||
|
||||
|
||||
def _apply_patch(row: Any, patch: dict[str, Any]) -> None:
|
||||
"""Apply a partial update to a settings row.
|
||||
|
||||
Values explicitly set to ``None`` are honored only for columns where the
|
||||
schema allows it — clearing ``default_playback_voice_id`` works, but a
|
||||
``None`` for a non-nullable field is dropped rather than crashing the
|
||||
request. Unknown keys are ignored.
|
||||
"""
|
||||
columns = type(row).__table__.columns
|
||||
for key, value in patch.items():
|
||||
col = columns.get(key)
|
||||
if col is None:
|
||||
continue
|
||||
if value is None and not col.nullable:
|
||||
continue
|
||||
setattr(row, key, value)
|
||||
|
||||
|
||||
def get_capture_settings(db: Session) -> DBCaptureSettings:
|
||||
"""Return the capture settings row, creating it with defaults if missing."""
|
||||
return _get_or_create_capture_row(db)
|
||||
|
||||
|
||||
def update_capture_settings(db: Session, patch: dict[str, Any]) -> DBCaptureSettings:
|
||||
row = _get_or_create_capture_row(db)
|
||||
_apply_patch(row, patch)
|
||||
db.commit()
|
||||
db.refresh(row)
|
||||
return row
|
||||
|
||||
|
||||
def get_generation_settings(db: Session) -> DBGenerationSettings:
|
||||
"""Return the generation settings row, creating it with defaults if missing."""
|
||||
return _get_or_create_generation_row(db)
|
||||
|
||||
|
||||
def update_generation_settings(db: Session, patch: dict[str, Any]) -> DBGenerationSettings:
|
||||
row = _get_or_create_generation_row(db)
|
||||
_apply_patch(row, patch)
|
||||
db.commit()
|
||||
db.refresh(row)
|
||||
return row
|
||||
Reference in New Issue
Block a user