Refine gameday bootstrap layout
This commit is contained in:
@@ -81,20 +81,3 @@ class GameAssignment(Base):
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, onupdate=utcnow)
|
||||
|
||||
clip: Mapped[AudioClip] = relationship()
|
||||
|
||||
|
||||
class PlaybackSession(Base):
|
||||
__tablename__ = "playback_sessions"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
external_team_id: Mapped[str] = mapped_column(String(128), index=True)
|
||||
external_game_id: Mapped[str] = mapped_column(String(128), index=True)
|
||||
gameday_session_id: Mapped[int | None] = mapped_column(ForeignKey("user_sessions.id"))
|
||||
current_assignment_id: Mapped[int | None] = mapped_column(ForeignKey("game_assignments.id"))
|
||||
state: Mapped[str] = mapped_column(String(32), default="idle")
|
||||
last_triggered_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, onupdate=utcnow)
|
||||
|
||||
gameday_session: Mapped[UserSession | None] = relationship()
|
||||
current_assignment: Mapped[GameAssignment | None] = relationship()
|
||||
|
||||
@@ -3,19 +3,16 @@ from __future__ import annotations
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy import select, update
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..auth import require_session
|
||||
from ..database import get_db
|
||||
from ..models import AudioClip, GameAssignment, PlaybackSession, UserSession
|
||||
from ..models import AudioClip, GameAssignment, UserSession
|
||||
from ..schemas import (
|
||||
GameAssignmentCreate,
|
||||
GameAssignmentResponse,
|
||||
GamePrepResponse,
|
||||
PlaybackAction,
|
||||
PlaybackSessionCreate,
|
||||
PlaybackSessionResponse,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/games", tags=["games"])
|
||||
@@ -133,7 +130,6 @@ def delete_assignment(
|
||||
if external_player_id is not None and assignment.external_player_id != external_player_id:
|
||||
raise HTTPException(status_code=403, detail="Pin does not belong to that player")
|
||||
|
||||
db.execute(update(PlaybackSession).where(PlaybackSession.current_assignment_id == assignment.id).values(current_assignment_id=None))
|
||||
db.delete(assignment)
|
||||
db.commit()
|
||||
|
||||
@@ -157,61 +153,3 @@ def prepare_game(
|
||||
prepared_at=datetime.now(timezone.utc),
|
||||
assignments=[assignment_to_response(assignment) for assignment in assignments],
|
||||
)
|
||||
|
||||
|
||||
@router.post("/{external_game_id}/gameday/session", response_model=PlaybackSessionResponse)
|
||||
def create_gameday_session(
|
||||
external_game_id: str,
|
||||
payload: PlaybackSessionCreate,
|
||||
session: UserSession = Depends(require_session),
|
||||
db: Session = Depends(get_db),
|
||||
) -> PlaybackSessionResponse:
|
||||
playback = PlaybackSession(
|
||||
external_team_id=payload.external_team_id,
|
||||
external_game_id=external_game_id,
|
||||
gameday_session_id=session.id,
|
||||
state="idle",
|
||||
)
|
||||
db.add(playback)
|
||||
db.commit()
|
||||
db.refresh(playback)
|
||||
return PlaybackSessionResponse.model_validate(playback, from_attributes=True)
|
||||
|
||||
|
||||
@router.post("/{external_game_id}/gameday/session/{playback_session_id}/trigger", response_model=PlaybackSessionResponse)
|
||||
def trigger_gameday(
|
||||
external_game_id: str,
|
||||
playback_session_id: int,
|
||||
payload: PlaybackAction,
|
||||
_: UserSession = Depends(require_session),
|
||||
db: Session = Depends(get_db),
|
||||
) -> PlaybackSessionResponse:
|
||||
playback = db.get(PlaybackSession, playback_session_id)
|
||||
if playback is None or playback.external_game_id != external_game_id:
|
||||
raise HTTPException(status_code=404, detail="Playback session not found")
|
||||
|
||||
if payload.assignment_id is None and payload.clip_id is None:
|
||||
raise HTTPException(status_code=422, detail="Provide a pin or clip to trigger")
|
||||
|
||||
if payload.assignment_id is not None:
|
||||
assignment = db.get(GameAssignment, payload.assignment_id)
|
||||
if assignment is None or assignment.external_game_id != external_game_id:
|
||||
raise HTTPException(status_code=404, detail="Pin not found")
|
||||
if assignment.clip.hidden:
|
||||
raise HTTPException(status_code=404, detail="Pin not found")
|
||||
playback.current_assignment_id = assignment.id
|
||||
else:
|
||||
clip = db.get(AudioClip, payload.clip_id)
|
||||
if clip is None or clip.asset.external_team_id != playback.external_team_id:
|
||||
raise HTTPException(status_code=404, detail="Clip not found")
|
||||
if clip.hidden:
|
||||
raise HTTPException(status_code=404, detail="Clip not found")
|
||||
if payload.external_player_id and clip.asset.owner_external_player_id != payload.external_player_id:
|
||||
raise HTTPException(status_code=403, detail="Clip does not belong to that player")
|
||||
playback.current_assignment_id = None
|
||||
|
||||
playback.state = payload.state
|
||||
playback.last_triggered_at = datetime.now(timezone.utc)
|
||||
db.commit()
|
||||
db.refresh(playback)
|
||||
return PlaybackSessionResponse.model_validate(playback, from_attributes=True)
|
||||
|
||||
@@ -6,12 +6,12 @@ from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
|
||||
from fastapi.responses import FileResponse
|
||||
from sqlalchemy import delete, func, select, update
|
||||
from sqlalchemy import delete, func, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..auth import require_session
|
||||
from ..database import get_db
|
||||
from ..models import AudioAsset, AudioClip, GameAssignment, PlaybackSession, UserSession
|
||||
from ..models import AudioAsset, AudioClip, GameAssignment, UserSession
|
||||
from ..schemas import (
|
||||
AudioAssetImportCreate,
|
||||
AudioAssetResponse,
|
||||
@@ -239,14 +239,7 @@ def delete_asset(
|
||||
clips = db.scalars(select(AudioClip).where(AudioClip.asset_id == asset.id)).all()
|
||||
clip_ids = [clip.id for clip in clips]
|
||||
if clip_ids:
|
||||
assignment_ids = db.scalars(select(GameAssignment.id).where(GameAssignment.clip_id.in_(clip_ids))).all()
|
||||
db.execute(delete(GameAssignment).where(GameAssignment.clip_id.in_(clip_ids)))
|
||||
if assignment_ids:
|
||||
db.execute(
|
||||
update(PlaybackSession)
|
||||
.where(PlaybackSession.current_assignment_id.in_(assignment_ids))
|
||||
.values(current_assignment_id=None)
|
||||
)
|
||||
for clip in clips:
|
||||
if clip.normalized_path:
|
||||
storage.delete_relative_path(clip.normalized_path)
|
||||
@@ -361,14 +354,7 @@ def delete_clip(
|
||||
if not can_manage_asset(session, clip.asset, owner_external_player_id):
|
||||
raise HTTPException(status_code=403, detail="You can only delete clips from your own uploads")
|
||||
|
||||
assignment_ids = db.scalars(select(GameAssignment.id).where(GameAssignment.clip_id == clip.id)).all()
|
||||
db.execute(delete(GameAssignment).where(GameAssignment.clip_id == clip.id))
|
||||
if assignment_ids:
|
||||
db.execute(
|
||||
update(PlaybackSession)
|
||||
.where(PlaybackSession.current_assignment_id.in_(assignment_ids))
|
||||
.values(current_assignment_id=None)
|
||||
)
|
||||
if clip.normalized_path:
|
||||
storage.delete_relative_path(clip.normalized_path)
|
||||
db.delete(clip)
|
||||
|
||||
@@ -126,21 +126,7 @@ class AudioClipReorder(BaseModel):
|
||||
clip_ids: list[int] = Field(min_length=1)
|
||||
|
||||
|
||||
class PlaybackSessionCreate(BaseModel):
|
||||
external_team_id: str
|
||||
|
||||
|
||||
class PlaybackAction(BaseModel):
|
||||
assignment_id: int | None = None
|
||||
clip_id: int | None = None
|
||||
external_player_id: str | None = None
|
||||
state: str = "playing"
|
||||
|
||||
|
||||
class PlaybackSessionResponse(BaseModel):
|
||||
id: int
|
||||
external_team_id: str
|
||||
external_game_id: str
|
||||
current_assignment_id: int | None
|
||||
state: str
|
||||
last_triggered_at: datetime | None
|
||||
|
||||
Reference in New Issue
Block a user