heystreamer/app/routers/settings.py
Bashy 6ad661c220 Initial commit — BashyOverlay v1
Twitch stream event platform with OBS browser source overlay.

Features:
- Twitch OAuth login (streamer + mod access)
- EventSub WebSocket for subs, gift subs, bits, channel points, follows, raids
- Chat commands via tmi.js in the overlay
- Gap audio — tone plays on new chat message after silence, volume/pitch scale with gap length
- Self-hosted media library (upload sounds and videos)
- Action configuration — map any event to sound, video, or alert
- Per-action cooldowns, test button, enable/disable toggle
- Multiple actions per event (all matching actions fire)
- Activity log dashboard with EventSub connection status
- Layout editor — iframe-based WYSIWYG with drag handles, live style preview
- Custom CSS and custom JS injection into overlay
- Custom DOM events (bashyoverlay:sub, bashyoverlay:raid, etc.) for custom JS hooks
- deploy.sh — one-shot setup and launch script

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 23:48:35 +03:00

64 lines
2.2 KiB
Python

from fastapi import APIRouter, Depends, Form, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from sqlmodel import Session, select
from app.auth import require_user
from app.database import get_session
from app.models import Settings
from app.templates import templates
router = APIRouter(prefix="/settings")
@router.get("", response_class=HTMLResponse)
async def settings_page(request: Request, session: Session = Depends(get_session), user=Depends(require_user)):
settings = session.exec(select(Settings)).first() or Settings()
return templates.TemplateResponse("settings.html", {
"request": request,
"user": user,
"settings": settings,
"overlay_url": str(request.base_url) + "overlay",
})
@router.post("", response_class=HTMLResponse)
async def save_settings(
request: Request,
twitch_channel: str = Form(...),
gap_silence_threshold: int = Form(default=30),
gap_scale_end: int = Form(default=120),
gap_pitch_scale_end: int = Form(default=300),
custom_css: str = Form(default=""),
custom_js: str = Form(default=""),
session: Session = Depends(get_session),
user=Depends(require_user),
):
settings = session.exec(select(Settings)).first()
if not settings:
settings = Settings()
settings.twitch_channel = twitch_channel.strip().lstrip("#")
settings.gap_silence_threshold = max(0, gap_silence_threshold)
settings.gap_scale_end = max(settings.gap_silence_threshold + 1, gap_scale_end)
settings.gap_pitch_scale_end = max(settings.gap_scale_end + 1, gap_pitch_scale_end)
settings.custom_css = custom_css
settings.custom_js = custom_js
session.add(settings)
session.commit()
return templates.TemplateResponse("settings.html", {
"request": request,
"user": user,
"settings": settings,
"overlay_url": str(request.base_url) + "overlay",
"saved": True,
})
@router.post("/reconnect")
async def reconnect_eventsub(user=Depends(require_user)):
from app.main import start_eventsub
import asyncio
asyncio.create_task(start_eventsub())
return RedirectResponse(url="/settings", status_code=303)