"""Web UI Routes."""
import logging
from typing import Optional, Dict, Any
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
import config
import download
from core.cache import series_cache
logger = logging.getLogger("syllabus")
router = APIRouter(tags=["Web UI"])
@router.get("/", include_in_schema=False, response_class=HTMLResponse)
async def index_route(request: Request) -> HTMLResponse:
"""Home page showing list of shows."""
try:
data = series_cache.get()
if data is None:
series_cache.load_from_file(str(config.DROPOUT_JSON))
data = series_cache.get()
if data is None:
return HTMLResponse("
Loading...
", status_code=503)
return request.app.templates.TemplateResponse(
"index.html", {"request": request, "data": data}
)
except Exception as e:
logger.error(f"Error rendering index: {e}")
return HTMLResponse(f"Error: {str(e)}
", status_code=500)
@router.get("/show/{show}", include_in_schema=False, response_class=HTMLResponse)
async def show_route(request: Request, show: str) -> HTMLResponse:
"""Show page with download options."""
try:
item = await get_show_data(show)
if item:
return request.app.templates.TemplateResponse(
"show.html", {"request": request, "show": item}
)
else:
return HTMLResponse("Show not found
", status_code=404)
except Exception as e:
logger.error(f"Error rendering show page: {e}")
return HTMLResponse(f"Error: {str(e)}
", status_code=500)
@router.get("/ydl", include_in_schema=False, response_class=HTMLResponse)
async def ydl_page(request: Request) -> HTMLResponse:
"""YouTube downloader page."""
try:
return request.app.templates.TemplateResponse("ydl.html", {"request": request})
except Exception as e:
logger.error(f"Error rendering YDL page: {e}")
return HTMLResponse(f"Error: {str(e)}
", status_code=500)
@router.get("/dropout", include_in_schema=False, response_class=HTMLResponse)
async def dropout_page(request: Request) -> HTMLResponse:
"""Dropout downloader page."""
try:
data = series_cache.get()
if data is None:
series_cache.load_from_file(str(config.DROPOUT_JSON))
data = series_cache.get()
if data is None:
return HTMLResponse("Loading...
", status_code=503)
return request.app.templates.TemplateResponse(
"dropout.html", {"request": request, "data": data}
)
except Exception as e:
logger.error(f"Error rendering dropout page: {e}")
return HTMLResponse(f"Error: {str(e)}
", status_code=500)
# Helper functions
async def get_show_data(show: str, force: bool = False) -> Optional[Dict[str, Any]]:
"""Get data for a specific show by name or link."""
try:
cached = series_cache.get()
if cached is None:
series_cache.load_from_file(str(config.DROPOUT_JSON))
cached = series_cache.get()
if cached is None:
return None
for item in cached:
if show == item.get("SHOW") or show == item.get("LINK"):
if "SEASONS" not in item or force:
try:
item['SEASONS'] = download.grab.season(item['URL'])
except Exception as e:
logger.error(f"Failed to fetch seasons for {show}: {e}")
item['SEASONS'] = []
return item
return None
except Exception as e:
logger.error(f"Error getting show data: {e}")
return None