elmeg-demo/backend/routers/search.py
fullsizemalt 49e025d3bf
Some checks are pending
Deploy Elmeg / deploy (push) Waiting to run
fix: commit all pending changes (home, leaderboard, slug cleanup)
2025-12-24 12:06:35 -08:00

101 lines
2.7 KiB
Python

from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session, select, col
from sqlalchemy.orm import selectinload
from database import get_session
from models import Show, Song, Venue, Tour, User, Group, Performance, PerformanceNickname, Comment, Review
from schemas import ShowRead, SongRead, VenueRead, TourRead, UserRead, GroupRead
router = APIRouter(prefix="/search", tags=["search"])
@router.get("/")
def global_search(
q: str,
session: Session = Depends(get_session),
limit: int = 5
):
if len(q) < 2:
return {}
q_str = f"%{q}%"
# Search Songs
songs = session.exec(
select(Song)
.where(col(Song.title).ilike(q_str))
.limit(limit)
).all()
# Search Venues
venues = session.exec(
select(Venue)
.where(col(Venue.name).ilike(q_str))
.limit(limit)
).all()
# Search Tours
tours = session.exec(
select(Tour)
.where(col(Tour.name).ilike(q_str))
.limit(limit)
).all()
# Search Groups
groups = session.exec(
select(Group)
.where(col(Group.name).ilike(q_str))
.limit(limit)
).all()
# Search Users (by username or email)
users = session.exec(
select(User)
.where((col(User.email).ilike(q_str)) | (col(User.username).ilike(q_str)))
.limit(limit)
).all()
# Search Nicknames
nicknames = session.exec(
select(PerformanceNickname)
.options(selectinload(PerformanceNickname.performance).selectinload(Performance.song))
.where(col(PerformanceNickname.nickname).ilike(q_str))
.where(PerformanceNickname.status == "approved")
.limit(limit)
).all()
# Search Performances
performances = session.exec(
select(Performance)
.options(selectinload(Performance.song), selectinload(Performance.show))
.where(col(Performance.notes).ilike(q_str))
.limit(limit)
).all()
# Search Reviews
reviews = session.exec(
select(Review)
.where(
(col(Review.blurb).ilike(q_str)) |
(col(Review.content).ilike(q_str))
)
.limit(limit)
).all()
# Search Comments
comments = session.exec(
select(Comment)
.where(col(Comment.content).ilike(q_str))
.limit(limit)
).all()
return {
"songs": songs,
"venues": venues,
"tours": tours,
"groups": groups,
"users": users,
"nicknames": nicknames,
"performances": performances,
"reviews": reviews,
"comments": comments
}