Frontend-Aufnahme (MediaRecorder): - Aufnahme-Button im Upload-Form, große Touch-Targets - Start / Pause / Fortsetzen / Stop mit Live-Timer - Format-Auto-Detect (Opus/WebM, Safari nimmt M4A) - Wake Lock damit iOS nicht ins Sleep geht - Aufnahme-Datei landet als File-Objekt im Upload-Flow - Beim Submit: aufgenommene Datei bevorzugt vor File-Input PWA: - manifest.webmanifest, icon.svg + PNG-Icons (192/512) - apple-mobile-web-app-capable + theme-color - "Zum Home-Bildschirm" hinzufügen verwandelt Seite in App Mobile-Layout: - Single-Column ab 700px, größere Buttons - Header stapelt sich vertikal - Tabelle scrollt horizontal statt zu zerquetschen - Safe-Area-Insets für iPhone-Notch HTTPS (Pflicht für Mikrofon-Zugriff): - install.sh erzeugt selbst-signiertes Cert (4096 Bit, 825 Tage, mit SAN aus Hostname + LAN-IP) - Nginx: HTTP → HTTPS Redirect, Cert unter /ssl/voice-agent.crt ungesichert abrufbar (für bequemen iOS-Profil-Import) Backend: - ALLOWED_EXTS um 'webm' erweitert
35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
from pathlib import Path
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
app_name: str = "Voice-Agent"
|
|
app_host: str = "0.0.0.0"
|
|
app_port: int = 8000
|
|
|
|
upload_dir: Path = Path("/var/lib/voice-agent/uploads")
|
|
result_dir: Path = Path("/var/lib/voice-agent/results")
|
|
db_url: str = "sqlite:////var/lib/voice-agent/voice-agent.db"
|
|
|
|
mac_api_url: str = "http://192.168.85.10:8080"
|
|
mac_api_timeout: int = 1800
|
|
|
|
max_upload_mb: int = 500
|
|
allowed_exts: str = "mp3,wav,m4a,mp4,ogg,flac,webm"
|
|
|
|
# Wird beim Deploy automatisch generiert (siehe install.sh).
|
|
session_secret: str = "CHANGE-ME-SET-IN-ENV"
|
|
session_cookie_name: str = "voice_agent_session"
|
|
session_max_age: int = 60 * 60 * 24 * 14 # 14 Tage
|
|
|
|
@property
|
|
def allowed_ext_set(self) -> set[str]:
|
|
return {e.strip().lower().lstrip(".") for e in self.allowed_exts.split(",") if e.strip()}
|
|
|
|
|
|
settings = Settings()
|
|
settings.upload_dir.mkdir(parents=True, exist_ok=True)
|
|
settings.result_dir.mkdir(parents=True, exist_ok=True)
|