101 lines
3.6 KiB
Python
101 lines
3.6 KiB
Python
from typing import List
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlmodel import Session, select
|
|
from database import get_session
|
|
from models import Show, Tag, EntityTag
|
|
from schemas import ShowCreate, ShowRead, ShowUpdate, TagRead
|
|
from auth import get_current_user
|
|
|
|
router = APIRouter(prefix="/shows", tags=["shows"])
|
|
|
|
@router.post("/", response_model=ShowRead)
|
|
def create_show(show: ShowCreate, session: Session = Depends(get_session), current_user = Depends(get_current_user)):
|
|
db_show = Show.model_validate(show)
|
|
session.add(db_show)
|
|
session.commit()
|
|
session.refresh(db_show)
|
|
return db_show
|
|
|
|
@router.get("/", response_model=List[ShowRead])
|
|
def read_shows(
|
|
offset: int = 0,
|
|
limit: int = Query(default=2000, le=5000),
|
|
venue_id: int = None,
|
|
tour_id: int = None,
|
|
year: int = None,
|
|
session: Session = Depends(get_session)
|
|
):
|
|
query = select(Show)
|
|
if venue_id:
|
|
query = query.where(Show.venue_id == venue_id)
|
|
if tour_id:
|
|
query = query.where(Show.tour_id == tour_id)
|
|
if year:
|
|
from sqlalchemy import extract
|
|
query = query.where(extract('year', Show.date) == year)
|
|
|
|
shows = session.exec(query.offset(offset).limit(limit)).all()
|
|
return shows
|
|
|
|
@router.get("/recent", response_model=List[ShowRead])
|
|
def read_recent_shows(
|
|
limit: int = Query(default=10, le=50),
|
|
session: Session = Depends(get_session)
|
|
):
|
|
"""Get the most recent shows ordered by date descending"""
|
|
from datetime import datetime
|
|
query = select(Show).where(Show.date <= datetime.now()).order_by(Show.date.desc()).limit(limit)
|
|
shows = session.exec(query).all()
|
|
return shows
|
|
|
|
@router.get("/{show_id}", response_model=ShowRead)
|
|
def read_show(show_id: str, session: Session = Depends(get_session)):
|
|
if show_id.isdigit():
|
|
show = session.get(Show, int(show_id))
|
|
else:
|
|
show = session.exec(select(Show).where(Show.slug == show_id)).first()
|
|
|
|
if not show:
|
|
raise HTTPException(status_code=404, detail="Show not found")
|
|
|
|
tags = session.exec(
|
|
select(Tag)
|
|
.join(EntityTag, Tag.id == EntityTag.tag_id)
|
|
.where(EntityTag.entity_type == "show")
|
|
.where(EntityTag.entity_id == show.id)
|
|
).all()
|
|
|
|
# Manually populate performances to ensure nicknames are filtered if needed
|
|
# (Though for now we just return all, or filter approved in schema if we had a custom getter)
|
|
# The relationship `show.performances` is already loaded if we access it, but we might want to sort.
|
|
|
|
# Re-fetch show with relationships if needed, or just rely on lazy loading + validation
|
|
# But for nicknames, we only want "approved" ones usually.
|
|
# Let's let the frontend filter or do it here.
|
|
# Doing it here is safer.
|
|
|
|
show_data = ShowRead.model_validate(show)
|
|
show_data.tags = tags
|
|
|
|
# Sort performances by position
|
|
sorted_perfs = sorted(show.performances, key=lambda p: p.position)
|
|
|
|
# Filter nicknames for each performance
|
|
for perf in sorted_perfs:
|
|
perf.nicknames = [n for n in perf.nicknames if n.status == "approved"]
|
|
|
|
show_data.performances = sorted_perfs
|
|
|
|
return show_data
|
|
|
|
@router.patch("/{show_id}", response_model=ShowRead)
|
|
def update_show(show_id: int, show: ShowUpdate, session: Session = Depends(get_session), current_user = Depends(get_current_user)):
|
|
db_show = session.get(Show, show_id)
|
|
if not db_show:
|
|
raise HTTPException(status_code=404, detail="Show not found")
|
|
show_data = show.model_dump(exclude_unset=True)
|
|
db_show.sqlmodel_update(show_data)
|
|
session.add(db_show)
|
|
session.commit()
|
|
session.refresh(db_show)
|
|
return db_show
|