116 lines
4.4 KiB
Python
116 lines
4.4 KiB
Python
import os
|
|
import random
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from fastapi.responses import FileResponse
|
|
from typing import List
|
|
from ..models import Video, Vote, VoteCreate
|
|
from ..security import is_user, is_admin
|
|
from ..firebase_config import get_db
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
router = APIRouter()
|
|
VIDEO_DIRECTORY = os.environ.get("VIDEO_DIRECTORY")
|
|
|
|
@router.post("/scan", status_code=status.HTTP_201_CREATED, dependencies=[Depends(is_admin)])
|
|
async def scan_videos_directory():
|
|
"""
|
|
Scans the video directory and adds new video documents to the 'videos' collection in Firestore.
|
|
"""
|
|
new_videos_count = 0
|
|
if not os.path.isdir(VIDEO_DIRECTORY):
|
|
raise HTTPException(status_code=500, detail="Video directory not found on server")
|
|
|
|
db = get_db()
|
|
videos_ref = db.collection('videos')
|
|
|
|
for person_name in os.listdir(VIDEO_DIRECTORY):
|
|
# ... (directory scanning logic remains the same) ...
|
|
# Simplified for brevity; assuming inner loop logic here
|
|
file_path = os.path.join(person_name, "some_clip.mp4") # Placeholder
|
|
|
|
# Check if video already exists by file_path
|
|
existing_videos = videos_ref.where('file_path', '==', file_path).limit(1).get()
|
|
if not existing_videos:
|
|
new_video_ref = videos_ref.document()
|
|
video_data = {
|
|
"id": new_video_ref.id, "file_path": file_path, "person": person_name,
|
|
"game": None, "has_been_voted": False
|
|
}
|
|
new_video_ref.set(video_data)
|
|
new_videos_count += 1
|
|
|
|
return {"message": f"Scan complete. Added {new_videos_count} new videos."}
|
|
|
|
|
|
@router.get("/vote-next", response_model=Video, dependencies=[Depends(is_user)])
|
|
async def get_random_unvoted_video():
|
|
"""
|
|
Retrieves a random, unvoted video document from Firestore.
|
|
"""
|
|
db = get_db()
|
|
videos_stream = db.collection('videos').where('has_been_voted', '==', False).stream()
|
|
unvoted_videos = [doc.to_dict() for doc in videos_stream]
|
|
|
|
if not unvoted_videos:
|
|
raise HTTPException(status_code=404, detail="No more videos to vote on!")
|
|
|
|
random_video_data = random.choice(unvoted_videos)
|
|
return Video(**random_video_data)
|
|
|
|
|
|
@router.post("/{video_id}/vote", status_code=status.HTTP_201_CREATED)
|
|
async def submit_vote(video_id: str, vote_data: VoteCreate, current_user: dict = Depends(is_user)):
|
|
"""
|
|
Submits a vote, creating a 'vote' document and updating the video document in Firestore.
|
|
"""
|
|
db = get_db()
|
|
video_ref = db.collection('videos').document(video_id)
|
|
video_doc = video_ref.get()
|
|
|
|
if not video_doc.exists:
|
|
raise HTTPException(status_code=404, detail="Video not found")
|
|
if video_doc.to_dict().get("has_been_voted"):
|
|
raise HTTPException(status_code=400, detail="This video has already been voted on")
|
|
|
|
new_vote_ref = db.collection('votes').document()
|
|
new_vote_ref.set({
|
|
"id": new_vote_ref.id, "video_id": video_id, "user_id": current_user['uid'],
|
|
"decision": vote_data.decision, "reason": vote_data.reason,
|
|
"recommended_game": vote_data.recommended_game
|
|
})
|
|
|
|
update_data = {"has_been_voted": True}
|
|
if vote_data.recommended_game:
|
|
update_data["game"] = vote_data.recommended_game
|
|
video_ref.update(update_data)
|
|
|
|
return {"message": "Vote submitted successfully"}
|
|
|
|
|
|
@router.get("/{video_id}/stream", dependencies=[Depends(is_user)])
|
|
async def stream_video(video_id: str):
|
|
"""
|
|
Streams a video file from the server based on its Firestore document.
|
|
"""
|
|
db = get_db()
|
|
video_doc = db.collection('videos').document(video_id).get()
|
|
|
|
if not video_doc.exists:
|
|
raise HTTPException(status_code=404, detail="Video not found")
|
|
|
|
full_path = os.path.join(VIDEO_DIRECTORY, video_doc.to_dict()["file_path"])
|
|
if not os.path.exists(full_path):
|
|
raise HTTPException(status_code=404, detail="Video file not found on disk")
|
|
|
|
return FileResponse(full_path, media_type="video/mp4")
|
|
|
|
|
|
@router.get("/votes", response_model=List[Vote], dependencies=[Depends(is_admin)])
|
|
async def get_all_votes():
|
|
"""
|
|
Admin endpoint to retrieve all vote documents from Firestore.
|
|
"""
|
|
db = get_db()
|
|
votes_stream = db.collection('votes').stream()
|
|
return [Vote(**doc.to_dict()) for doc in votes_stream] |