avorg/backend/main.py

139 lines
4.3 KiB
Python

from fastapi import FastAPI, HTTPException, Query, Depends
from fastapi.middleware.cors import CORSMiddleware
from typing import List
import os
from sqlalchemy.orm import Session
from models import Base, Video
from schemas import VideoCreate, VideoInDB
from database import engine, get_db
from video_scanner import scan_video_directory
from fastapi.responses import FileResponse
import json
# Create database tables
Base.metadata.create_all(bind=engine)
app = FastAPI(title="Video Organization API", version="0.1.0")
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# In-memory storage for video paths (in a real app, this would be in a database)
video_paths = []
@app.get("/")
def read_root():
return {"message": "Welcome to Video Organization API"}
@app.post("/video-paths/")
def add_video_path(path: str = Query(...)):
"""
Add a video path to the library
"""
if not os.path.exists(path):
raise HTTPException(status_code=404, detail="Path does not exist")
if path not in video_paths:
video_paths.append(path)
return {"message": f"Path {path} added successfully", "paths": video_paths}
else:
return {"message": f"Path {path} already exists", "paths": video_paths}
@app.get("/video-paths/")
def get_video_paths():
"""
Get all video paths in the library
"""
return {"paths": video_paths}
@app.delete("/video-paths/")
def delete_video_path(path: str = Query(...)):
"""
Delete a video path from the library
"""
if path in video_paths:
video_paths.remove(path)
return {"message": f"Path {path} removed successfully", "paths": video_paths}
else:
raise HTTPException(status_code=404, detail="Path not found")
@app.post("/scan-videos/")
def scan_videos(db: Session = Depends(get_db)):
"""
Scan all video paths and save the videos found to the database
"""
all_videos = []
for path in video_paths:
try:
videos = scan_video_directory(path)
all_videos.extend(videos)
except FileNotFoundError as e:
raise HTTPException(status_code=404, detail=str(e))
added_count = 0
for video_data in all_videos:
existing_video = db.query(Video).filter(Video.path == video_data['path']).first()
if not existing_video:
video = Video(**video_data)
db.add(video)
added_count += 1
db.commit()
return {"message": f"Scan complete. Added {added_count} new videos.", "count": added_count}
@app.get("/videos/", response_model=List[VideoInDB])
def get_videos(db: Session = Depends(get_db), search: str = Query(None)):
"""
Get all videos in the library, optionally filtered by search query
"""
query = db.query(Video)
if search:
query = query.filter(
(Video.title.ilike(f"%{search}%")) |
(Video.path.ilike(f"%{search}%"))
)
videos = query.all()
return videos
@app.delete("/videos/{video_id}")
def delete_video(video_id: int, db: Session = Depends(get_db)):
"""
Delete a video from the library by its ID
"""
video = db.query(Video).filter(Video.id == video_id).first()
if not video:
raise HTTPException(status_code=404, detail="Video not found")
db.delete(video)
db.commit()
return {"message": f"Video with ID {video_id} deleted successfully"}
@app.get("/videos/{video_id}/stream")
def stream_video(video_id: int, db: Session = Depends(get_db)):
"""
Stream a video file by its ID
"""
print(f"Attempting to stream video with ID: {video_id}") # Log
video = db.query(Video).filter(Video.id == video_id).first()
if not video:
print(f"Video with ID {video_id} not found in database.") # Log
raise HTTPException(status_code=404, detail="Video not found")
if not os.path.exists(video.path):
print(f"Video file not found on server: {video.path}") # Log
raise HTTPException(status_code=404, detail="Video file not found on server")
print(f"Streaming video from path: {video.path}") # Log
return FileResponse(video.path, media_type="video/mp4")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)