feat: Add On This Day endpoint (P2)
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
- GET /on-this-day - shows matching today's month/day in history - GET /on-this-day/highlights - top 5 for homepage widget - Supports ?vertical= filter and ?month=&day= override
This commit is contained in:
parent
35ce12bc84
commit
465017cda9
2 changed files with 127 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
import os
|
import os
|
||||||
from routers import auth, shows, venues, songs, social, tours, artists, preferences, reviews, badges, nicknames, moderation, attendance, groups, users, search, performances, notifications, feed, leaderboards, stats, admin, chase, gamification, videos, musicians, sequences, verticals, canon
|
from routers import auth, shows, venues, songs, social, tours, artists, preferences, reviews, badges, nicknames, moderation, attendance, groups, users, search, performances, notifications, feed, leaderboards, stats, admin, chase, gamification, videos, musicians, sequences, verticals, canon, on_this_day
|
||||||
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
|
@ -46,6 +46,7 @@ app.include_router(musicians.router)
|
||||||
app.include_router(sequences.router)
|
app.include_router(sequences.router)
|
||||||
app.include_router(verticals.router)
|
app.include_router(verticals.router)
|
||||||
app.include_router(canon.router)
|
app.include_router(canon.router)
|
||||||
|
app.include_router(on_this_day.router)
|
||||||
|
|
||||||
|
|
||||||
# Optional features - can be disabled via env vars
|
# Optional features - can be disabled via env vars
|
||||||
|
|
|
||||||
125
backend/routers/on_this_day.py
Normal file
125
backend/routers/on_this_day.py
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
"""
|
||||||
|
On This Day API endpoint - shows what happened on this date in history.
|
||||||
|
"""
|
||||||
|
from datetime import date
|
||||||
|
from typing import List, Optional
|
||||||
|
from fastapi import APIRouter, Depends, Query
|
||||||
|
from sqlmodel import Session, select
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from database import get_session
|
||||||
|
from models import Show, Venue, Vertical, Performance, Song
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/on-this-day", tags=["on-this-day"])
|
||||||
|
|
||||||
|
|
||||||
|
class ShowOnThisDay(BaseModel):
|
||||||
|
id: int
|
||||||
|
date: str
|
||||||
|
slug: str | None
|
||||||
|
venue_name: str | None
|
||||||
|
venue_city: str | None
|
||||||
|
vertical_name: str
|
||||||
|
vertical_slug: str
|
||||||
|
years_ago: int
|
||||||
|
|
||||||
|
|
||||||
|
class OnThisDayResponse(BaseModel):
|
||||||
|
month: int
|
||||||
|
day: int
|
||||||
|
shows: List[ShowOnThisDay]
|
||||||
|
total_shows: int
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/", response_model=OnThisDayResponse)
|
||||||
|
def get_on_this_day(
|
||||||
|
month: Optional[int] = None,
|
||||||
|
day: Optional[int] = None,
|
||||||
|
vertical: Optional[str] = None,
|
||||||
|
session: Session = Depends(get_session)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Get all shows that happened on this day in history.
|
||||||
|
Defaults to today's date if month/day not specified.
|
||||||
|
"""
|
||||||
|
today = date.today()
|
||||||
|
target_month = month or today.month
|
||||||
|
target_day = day or today.day
|
||||||
|
|
||||||
|
# Build query
|
||||||
|
query = select(Show).where(
|
||||||
|
Show.date.isnot(None)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Filter by vertical if specified
|
||||||
|
if vertical:
|
||||||
|
vertical_obj = session.exec(
|
||||||
|
select(Vertical).where(Vertical.slug == vertical)
|
||||||
|
).first()
|
||||||
|
if vertical_obj:
|
||||||
|
query = query.where(Show.vertical_id == vertical_obj.id)
|
||||||
|
|
||||||
|
# Execute and filter by month/day in Python (SQL date functions vary)
|
||||||
|
all_shows = session.exec(query.order_by(Show.date.desc())).all()
|
||||||
|
|
||||||
|
matching_shows = []
|
||||||
|
for show in all_shows:
|
||||||
|
if show.date and show.date.month == target_month and show.date.day == target_day:
|
||||||
|
venue = session.get(Venue, show.venue_id) if show.venue_id else None
|
||||||
|
vert = session.get(Vertical, show.vertical_id)
|
||||||
|
|
||||||
|
years_ago = today.year - show.date.year
|
||||||
|
|
||||||
|
matching_shows.append(ShowOnThisDay(
|
||||||
|
id=show.id,
|
||||||
|
date=show.date.strftime("%Y-%m-%d"),
|
||||||
|
slug=show.slug,
|
||||||
|
venue_name=venue.name if venue else None,
|
||||||
|
venue_city=venue.city if venue else None,
|
||||||
|
vertical_name=vert.name if vert else "Unknown",
|
||||||
|
vertical_slug=vert.slug if vert else "unknown",
|
||||||
|
years_ago=years_ago
|
||||||
|
))
|
||||||
|
|
||||||
|
# Sort by years ago (most recent anniversary first)
|
||||||
|
matching_shows.sort(key=lambda x: x.years_ago)
|
||||||
|
|
||||||
|
return OnThisDayResponse(
|
||||||
|
month=target_month,
|
||||||
|
day=target_day,
|
||||||
|
shows=matching_shows,
|
||||||
|
total_shows=len(matching_shows)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/highlights", response_model=List[ShowOnThisDay])
|
||||||
|
def get_on_this_day_highlights(
|
||||||
|
limit: int = 5,
|
||||||
|
session: Session = Depends(get_session)
|
||||||
|
):
|
||||||
|
"""Get highlighted shows for today across all bands (limited list for homepage)"""
|
||||||
|
today = date.today()
|
||||||
|
|
||||||
|
all_shows = session.exec(
|
||||||
|
select(Show).where(Show.date.isnot(None))
|
||||||
|
).all()
|
||||||
|
|
||||||
|
matching = []
|
||||||
|
for show in all_shows:
|
||||||
|
if show.date and show.date.month == today.month and show.date.day == today.day:
|
||||||
|
venue = session.get(Venue, show.venue_id) if show.venue_id else None
|
||||||
|
vert = session.get(Vertical, show.vertical_id)
|
||||||
|
|
||||||
|
matching.append(ShowOnThisDay(
|
||||||
|
id=show.id,
|
||||||
|
date=show.date.strftime("%Y-%m-%d"),
|
||||||
|
slug=show.slug,
|
||||||
|
venue_name=venue.name if venue else None,
|
||||||
|
venue_city=venue.city if venue else None,
|
||||||
|
vertical_name=vert.name if vert else "Unknown",
|
||||||
|
vertical_slug=vert.slug if vert else "unknown",
|
||||||
|
years_ago=today.year - show.date.year
|
||||||
|
))
|
||||||
|
|
||||||
|
# Sort by anniversary and return limited
|
||||||
|
matching.sort(key=lambda x: x.years_ago)
|
||||||
|
return matching[:limit]
|
||||||
Loading…
Add table
Reference in a new issue