File size: 5,049 Bytes
74cf6bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from fastapi import APIRouter, HTTPException, Query
from typing import List, Optional
from app.models.video import Video, SearchResult, VideoSegment
from app.services.video_service import (
    process_video,
    search_video_segments,
    get_all_segments,
    get_processed_videos,
    get_video_by_id,
)
from pydantic import BaseModel

router = APIRouter()


class VideoRequest(BaseModel):
    url: str


class VideoResponse(BaseModel):
    """Response model for video processing with additional status information."""

    video: Video
    newly_processed: bool = False


@router.post("/process", response_model=VideoResponse)
async def process_video_endpoint(video_request: VideoRequest) -> VideoResponse:
    """Process a YouTube video to extract and store transcript segments.
    If the video has already been processed, returns the existing data without reprocessing."""
    try:
        import logging

        # Get the video ID first
        from app.services.video_service import extract_video_id, get_video_by_id

        video_id = extract_video_id(video_request.url)

        # Check if already processed
        existing_video = get_video_by_id(video_id)
        already_processed = existing_video is not None and existing_video.processed

        if already_processed:
            logging.info(f"Video {video_id} already processed, returning existing data")
            return VideoResponse(video=existing_video, newly_processed=False)

        # Process the video if needed
        result = process_video(video_request.url)
        return VideoResponse(video=result, newly_processed=True)

    except Exception as e:
        import logging
        import traceback

        logging.error(f"Error processing video URL {video_request.url}: {str(e)}")
        logging.error(traceback.format_exc())
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/search")
async def search_video_endpoint(
    query: str = Query(..., description="Search query for video content"),
    video_id: Optional[str] = Query(
        None, description="Optional YouTube video ID to limit search"
    ),
    limit: int = Query(5, description="Maximum number of results to return"),
) -> List[SearchResult]:
    """Search for video segments based on the provided query."""
    import logging

    # Check for invalid video_id
    if video_id and (video_id.lower() == "undefined" or video_id.lower() == "null"):
        logging.warning(f"Invalid video_id in search request: '{video_id}'")
        video_id = None  # Clear invalid video_id to perform a global search instead

    try:
        results = search_video_segments(query, video_id, limit)
        return results
    except Exception as e:
        logging.error(
            f"Error searching for query '{query}' with video_id '{video_id}': {str(e)}"
        )
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/segments/{video_id}")
async def get_segments_endpoint(video_id: str) -> List[VideoSegment]:
    """Get all segments for a specific video, ordered by start time."""
    import logging

    # Check for invalid video ID
    if not video_id or video_id.lower() == "undefined" or video_id.lower() == "null":
        logging.warning(f"Invalid video ID requested: '{video_id}'")
        return []  # Return empty list for invalid IDs to avoid frontend errors

    try:
        segments = get_all_segments(video_id)
        if not segments:
            # Return an empty list instead of 404 to allow frontend to handle gracefully
            return []
        return segments
    except Exception as e:
        # Log the exception for debugging
        logging.error(f"Error getting segments for video {video_id}: {str(e)}")
        raise HTTPException(
            status_code=500, detail=f"Could not retrieve video segments: {str(e)}"
        )


@router.get("/recent")
async def get_recent_videos_endpoint(
    limit: int = Query(10, description="Maximum number of videos to return"),
) -> List[Video]:
    """Get recently processed videos ordered by creation time."""
    try:
        videos = get_processed_videos(limit=limit)
        return videos
    except Exception as e:
        # Log the exception for debugging
        import logging

        logging.error(f"Error getting recent videos: {str(e)}")
        raise HTTPException(
            status_code=500, detail=f"Could not retrieve recent videos: {str(e)}"
        )


@router.get("/info/{video_id}")
async def get_video_info_endpoint(video_id: str) -> Video:
    """Get metadata for a specific video."""
    try:
        video = get_video_by_id(video_id)
        if not video:
            # Return a basic video object if not found in database
            return Video(video_id=video_id, title=f"Video {video_id}")
        return video
    except Exception as e:
        import logging

        logging.error(f"Error getting video info for {video_id}: {str(e)}")
        raise HTTPException(
            status_code=500, detail=f"Could not retrieve video info: {str(e)}"
        )