107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
"""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("<h1>Loading...</h1>", 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"<h1>Error: {str(e)}</h1>", 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("<h1>Show not found</h1>", status_code=404)
|
|
except Exception as e:
|
|
logger.error(f"Error rendering show page: {e}")
|
|
return HTMLResponse(f"<h1>Error: {str(e)}</h1>", 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"<h1>Error: {str(e)}</h1>", 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("<h1>Loading...</h1>", 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"<h1>Error: {str(e)}</h1>", 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
|