157 lines
4.7 KiB
Python
157 lines
4.7 KiB
Python
import logging
|
|
from enum import Enum
|
|
from typing import Optional
|
|
from uuid import uuid4
|
|
|
|
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.auth.dependencies import get_current_user
|
|
from app.iptv.stream_manager import StreamManager
|
|
from app.models.auth import CognitoUser
|
|
from app.utils.database import get_db_session
|
|
|
|
router = APIRouter(prefix="/playlist", tags=["playlist"])
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# In-memory store for validation processes
|
|
validation_processes: dict[str, dict] = {}
|
|
|
|
|
|
class ProcessStatus(str, Enum):
|
|
PENDING = "pending"
|
|
IN_PROGRESS = "in_progress"
|
|
COMPLETED = "completed"
|
|
FAILED = "failed"
|
|
|
|
|
|
class StreamValidationRequest(BaseModel):
|
|
"""Request model for stream validation endpoint"""
|
|
|
|
channel_id: Optional[str] = None
|
|
|
|
|
|
class ValidatedStream(BaseModel):
|
|
"""Model for a validated working stream"""
|
|
|
|
channel_id: str
|
|
stream_url: str
|
|
|
|
|
|
class ValidationProcessResponse(BaseModel):
|
|
"""Response model for validation process initiation"""
|
|
|
|
process_id: str
|
|
status: ProcessStatus
|
|
message: str
|
|
|
|
|
|
class ValidationResultResponse(BaseModel):
|
|
"""Response model for validation results"""
|
|
|
|
process_id: str
|
|
status: ProcessStatus
|
|
working_streams: Optional[list[ValidatedStream]] = None
|
|
error: Optional[str] = None
|
|
|
|
|
|
def run_stream_validation(process_id: str, channel_id: Optional[str], db: Session):
|
|
"""Background task to validate streams"""
|
|
try:
|
|
validation_processes[process_id]["status"] = ProcessStatus.IN_PROGRESS
|
|
manager = StreamManager(db)
|
|
|
|
if channel_id:
|
|
stream_url = manager.validate_and_select_stream(channel_id)
|
|
if stream_url:
|
|
validation_processes[process_id]["result"] = {
|
|
"working_streams": [
|
|
ValidatedStream(channel_id=channel_id, stream_url=stream_url)
|
|
]
|
|
}
|
|
else:
|
|
validation_processes[process_id]["error"] = (
|
|
f"No working streams found for channel {channel_id}"
|
|
)
|
|
else:
|
|
# TODO: Implement validation for all channels
|
|
validation_processes[process_id]["error"] = (
|
|
"Validation of all channels not yet implemented"
|
|
)
|
|
|
|
validation_processes[process_id]["status"] = ProcessStatus.COMPLETED
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error validating streams: {str(e)}")
|
|
validation_processes[process_id]["status"] = ProcessStatus.FAILED
|
|
validation_processes[process_id]["error"] = str(e)
|
|
|
|
|
|
@router.post(
|
|
"/validate-streams",
|
|
summary="Start stream validation process",
|
|
response_model=ValidationProcessResponse,
|
|
status_code=status.HTTP_202_ACCEPTED,
|
|
responses={202: {"description": "Validation process started successfully"}},
|
|
)
|
|
async def start_stream_validation(
|
|
request: StreamValidationRequest,
|
|
background_tasks: BackgroundTasks,
|
|
user: CognitoUser = Depends(get_current_user),
|
|
db: Session = Depends(get_db_session),
|
|
):
|
|
"""
|
|
Start asynchronous validation of streams.
|
|
|
|
- Returns immediately with a process ID
|
|
- Use GET /validate-streams/{process_id} to check status
|
|
"""
|
|
process_id = str(uuid4())
|
|
validation_processes[process_id] = {
|
|
"status": ProcessStatus.PENDING,
|
|
"channel_id": request.channel_id,
|
|
}
|
|
|
|
background_tasks.add_task(run_stream_validation, process_id, request.channel_id, db)
|
|
|
|
return {
|
|
"process_id": process_id,
|
|
"status": ProcessStatus.PENDING,
|
|
"message": "Validation process started",
|
|
}
|
|
|
|
|
|
@router.get(
|
|
"/validate-streams/{process_id}",
|
|
summary="Check validation process status",
|
|
response_model=ValidationResultResponse,
|
|
responses={
|
|
200: {"description": "Process status and results"},
|
|
404: {"description": "Process not found"},
|
|
},
|
|
)
|
|
async def get_validation_status(
|
|
process_id: str, user: CognitoUser = Depends(get_current_user)
|
|
):
|
|
"""
|
|
Check status of a stream validation process.
|
|
|
|
Returns current status and results if completed.
|
|
"""
|
|
if process_id not in validation_processes:
|
|
raise HTTPException(status_code=404, detail="Process not found")
|
|
|
|
process = validation_processes[process_id]
|
|
response = {"process_id": process_id, "status": process["status"]}
|
|
|
|
if process["status"] == ProcessStatus.COMPLETED:
|
|
if "error" in process:
|
|
response["error"] = process["error"]
|
|
else:
|
|
response["working_streams"] = process["result"]["working_streams"]
|
|
elif process["status"] == ProcessStatus.FAILED:
|
|
response["error"] = process["error"]
|
|
|
|
return response
|