Initial commit: Video metadata registration service
- Add FastAPI server for video metadata registration - PostgreSQL database models for videos, video_streams, audio_streams, subtitle_streams - Batch registration script for .probe.json files - RESTful API endpoints for CRUD operations - Search functionality by title, artist, codec, resolution
This commit is contained in:
1
app/api/routes/__init__.py
Normal file
1
app/api/routes/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# routes package
|
||||
66
app/api/routes/videos.py
Normal file
66
app/api/routes/videos.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import os
|
||||
from typing import Optional
|
||||
from uuid import UUID
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from app.database import get_db
|
||||
from app.models.schemas import VideoSchema, VideoListResponse, RegisterRequest
|
||||
from app.services.video_register import VideoRegisterService
|
||||
|
||||
router = APIRouter(prefix="/videos", tags=["videos"])
|
||||
|
||||
|
||||
@router.post("", response_model=VideoSchema)
|
||||
def register_video(request: RegisterRequest, db: Session = Depends(get_db)):
|
||||
if not os.path.exists(request.probe_json_path):
|
||||
raise HTTPException(status_code=404, detail="Probe JSON file not found")
|
||||
|
||||
if not os.path.exists(request.absolute_file_path):
|
||||
raise HTTPException(status_code=404, detail="Video file not found")
|
||||
|
||||
service = VideoRegisterService(db)
|
||||
video = service.register_video(request.probe_json_path, request.absolute_file_path)
|
||||
|
||||
return video
|
||||
|
||||
|
||||
@router.get("/{video_id}", response_model=VideoSchema)
|
||||
def get_video(video_id: UUID, db: Session = Depends(get_db)):
|
||||
service = VideoRegisterService(db)
|
||||
video = service.get_video_by_id(video_id)
|
||||
|
||||
if not video:
|
||||
raise HTTPException(status_code=404, detail="Video not found")
|
||||
|
||||
return video
|
||||
|
||||
|
||||
@router.get("", response_model=VideoListResponse)
|
||||
def search_videos(
|
||||
title: Optional[str] = Query(None, description="Search by title"),
|
||||
artist: Optional[str] = Query(None, description="Search by artist"),
|
||||
codec_name: Optional[str] = Query(None, description="Search by video codec"),
|
||||
min_width: Optional[int] = Query(None, description="Minimum video width"),
|
||||
max_width: Optional[int] = Query(None, description="Maximum video width"),
|
||||
min_height: Optional[int] = Query(None, description="Minimum video height"),
|
||||
max_height: Optional[int] = Query(None, description="Maximum video height"),
|
||||
format_name: Optional[str] = Query(None, description="Search by format name"),
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
service = VideoRegisterService(db)
|
||||
total, videos = service.search_videos(
|
||||
title=title,
|
||||
artist=artist,
|
||||
codec_name=codec_name,
|
||||
min_width=min_width,
|
||||
max_width=max_width,
|
||||
min_height=min_height,
|
||||
max_height=max_height,
|
||||
format_name=format_name,
|
||||
skip=skip,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
return {"total": total, "videos": videos}
|
||||
Reference in New Issue
Block a user