restructure session management

This commit is contained in:
matthias@matsewe.de
2024-05-24 11:58:18 +02:00
parent d05f1f6760
commit fe4dafb560
6 changed files with 109 additions and 17 deletions

View File

@@ -1,8 +1,11 @@
import app.models as models
from sqlalchemy import func
from sqlalchemy.orm.attributes import flag_modified
def get_songs_and_vote_for_user(db, user_id) -> list[models.Song]:
votes = db.query(models.Vote).filter(models.Vote.user_id == user_id).subquery()
def get_songs_and_vote_for_session(db, session_name) -> list[models.Song]:
session_entry = activate_session(db, session_name)
votes = db.query(models.Vote).filter(models.Vote.session_id == session_entry.id).subquery()
songs_and_votes = db.query(
models.Song, votes.c.vote
@@ -58,12 +61,38 @@ def create_song(db,
db.commit()
def create_or_update_vote(db, song_id, user_id, vote):
def create_or_update_vote(db, song_id, session_name, vote):
session_entry = activate_session(db, session_name)
vote_entry = db.query(models.Vote).filter(
(models.Vote.user_id == user_id) & (models.Vote.song_id == song_id)).first()
(models.Vote.session_id == session_entry.id) & (models.Vote.song_id == song_id)).first()
if vote_entry:
vote_entry.vote = str(vote) # type: ignore
else:
vote_entry = models.Vote(song_id=song_id, user_id=user_id, vote=vote)
vote_entry = models.Vote(song_id=song_id, session_id=session_entry.id, vote=vote)
db.add(vote_entry)
db.commit()
def activate_session(db, session_name):
session_entry = db.query(models.Session).filter(
(models.Session.session_name == session_name)).first()
if session_entry:
session_entry.active = True
else:
session_entry = models.Session(session_name=session_name, active=True)
db.add(session_entry)
flag_modified(session_entry, "active")
db.commit()
return session_entry
def deactivate_session(db, session_name):
session_entry = db.query(models.Session).filter(
(models.Session.session_name == session_name)).first()
if session_entry:
session_entry.active = False
else:
session_entry = models.Session(session_name=session_name, active=False)
db.add(session_entry)
db.commit()

View File

@@ -1,10 +1,10 @@
from fastapi import FastAPI, Request, Depends
from app.routers import admin, user, songs
from app.routers import admin, user, songs, session
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from app.database import engine, Base, get_db
from app.crud import get_songs_and_vote_for_user
from app.crud import get_songs_and_vote_for_session
from sqlalchemy.orm import Session
from typing import Annotated
from app.schemas import Song
@@ -16,6 +16,7 @@ app = FastAPI()
app.include_router(admin.router)
app.include_router(user.router)
app.include_router(songs.router)
app.include_router(session.router)
app.mount("/static", StaticFiles(directory="static"), name="static")
@@ -28,7 +29,7 @@ async def root(request: Request, session_id : str = "", db: Annotated[Session, D
request=request, name="landing.html"
)
else:
songs = [Song(**s.__dict__, vote=v) for s, v in get_songs_and_vote_for_user(db, session_id)]
songs = [Song(**s.__dict__, vote=v) for s, v in get_songs_and_vote_for_session(db, session_id)]
songs_by_category = {}
all_categories = set()

View File

@@ -25,11 +25,20 @@ class Song(Base):
singable: Mapped[Optional[bool]]
class Session(Base):
__tablename__ = 'sessions'
id: Mapped[int] = mapped_column(primary_key=True)
session_name: Mapped[int]
active: Mapped[bool]
time_created: Mapped[datetime] = mapped_column(server_default=func.now())
time_updated: Mapped[Optional[datetime]
] = mapped_column(onupdate=func.now())
class Vote(Base):
__tablename__ = 'votes'
id: Mapped[int] = mapped_column(primary_key=True)
song_id: Mapped[int] = mapped_column(Integer, ForeignKey("songs.id"))
user_id: Mapped[int]
session_id: Mapped[int] = mapped_column(Integer, ForeignKey("sessions.id"))
vote: Mapped[Optional[int]]
time_created: Mapped[datetime] = mapped_column(server_default=func.now())
time_updated: Mapped[Optional[datetime]

27
app/routers/session.py Normal file
View File

@@ -0,0 +1,27 @@
from typing import Annotated
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
import app.models as models
from app.database import get_db
from app.schemas import Song
import app.crud as crud
router = APIRouter(
prefix="/session",
# dependencies=[Security(get_current_user, scopes=["public"])],
responses={404: {"description": "Not found"}},
)
@router.put("/{session_id}")
async def activate_session(session_id: str = "", db: Annotated[Session, Depends(get_db)] = None):
crud.activate_session(db, session_id)
@router.delete("/{session_id}")
async def deactivate_session(session_id: str = "", db: Annotated[Session, Depends(get_db)] = None):
crud.deactivate_session(db, session_id)
#@router.get("/{session_id}")
#async def get_session(session_id: str = "", db: Annotated[Session, Depends(get_db)] = None):
# return "get " + session_id

View File

@@ -5,7 +5,7 @@ from sqlalchemy.orm import Session
import app.models as models
from app.database import get_db
from app.schemas import Song
from app.crud import get_songs_and_vote_for_user, create_or_update_vote, get_all_songs_and_votes
from app.crud import get_songs_and_vote_for_session, create_or_update_vote, get_all_songs_and_votes
router = APIRouter(
prefix="/songs",
@@ -15,13 +15,13 @@ router = APIRouter(
@router.get("/")
async def get_songs(user_id: str = "", db: Annotated[Session, Depends(get_db)] = None) -> list[Song]:
return [Song(**s.__dict__, vote=v) for s, v in get_songs_and_vote_for_user(db, user_id)]
async def get_songs(session_id: str = "", db: Annotated[Session, Depends(get_db)] = None) -> list[Song]:
return [Song(**s.__dict__, vote=v) for s, v in get_songs_and_vote_for_session(db, session_id)]
@router.post("/{song_id}/vote")
async def vote(song_id: str, user_id: str, vote: int, db: Annotated[Session, Depends(get_db)]):
create_or_update_vote(db, song_id, user_id, vote)
async def vote(song_id: str, session_id: str, vote: int, db: Annotated[Session, Depends(get_db)]):
create_or_update_vote(db, song_id, session_id, vote)
@router.get("/evaluation")