Some checks failed
Test Suite / test (push) Has been cancelled
- Introduced `/api/tmdb` and `/api/collection/missing-locations` endpoints to the backend for improved media management. - Added a new `get_media_by_country` function in the collection API to fetch media items based on country codes. - Updated configuration to allow overriding *arr base URLs via environment variables for better flexibility. - Enhanced frontend with a new `MissingLocations` component and integrated it into the routing structure. - Improved the `CollectionMap` component to handle country selection and display media items accordingly. - Added testing dependencies in `requirements.txt` and updated frontend configuration for testing support.
72 lines
2.5 KiB
Python
72 lines
2.5 KiB
Python
"""TMDB API endpoints for searching movies and TV shows"""
|
|
from fastapi import APIRouter, Query, HTTPException
|
|
from typing import Optional
|
|
import httpx
|
|
from app.core.config import settings
|
|
|
|
router = APIRouter()
|
|
|
|
TMDB_BASE_URL = "https://api.themoviedb.org/3"
|
|
|
|
|
|
@router.get("/search")
|
|
async def search_tmdb(
|
|
query: str = Query(..., description="Search query"),
|
|
type: str = Query("movie", description="Type: movie or tv")
|
|
):
|
|
"""
|
|
Search TMDB for movies or TV shows.
|
|
Returns a list of results with title, year, and other metadata.
|
|
"""
|
|
if not settings.tmdb_api_key:
|
|
raise HTTPException(status_code=503, detail="TMDB API key not configured")
|
|
|
|
if type not in ["movie", "tv"]:
|
|
raise HTTPException(status_code=400, detail="Type must be 'movie' or 'tv'")
|
|
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get(
|
|
f"{TMDB_BASE_URL}/search/{type}",
|
|
params={
|
|
"api_key": settings.tmdb_api_key,
|
|
"query": query,
|
|
"language": "en-US",
|
|
},
|
|
timeout=10.0
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
|
|
results = []
|
|
for item in data.get("results", [])[:10]: # Limit to 10 results
|
|
result = {
|
|
"id": item.get("id"),
|
|
"title": item.get("title") or item.get("name"),
|
|
"year": None,
|
|
"type": type,
|
|
"overview": item.get("overview"),
|
|
"poster_path": item.get("poster_path"),
|
|
}
|
|
|
|
# Extract year from release_date or first_air_date
|
|
date_str = item.get("release_date") or item.get("first_air_date")
|
|
if date_str:
|
|
try:
|
|
result["year"] = int(date_str.split("-")[0])
|
|
except (ValueError, AttributeError):
|
|
pass
|
|
|
|
results.append(result)
|
|
|
|
return {
|
|
"query": query,
|
|
"type": type,
|
|
"results": results
|
|
}
|
|
except httpx.HTTPStatusError as e:
|
|
raise HTTPException(status_code=e.response.status_code, detail=f"TMDB API error: {e.response.text[:200]}")
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to search TMDB: {str(e)}")
|
|
|