206 lines
6.6 KiB
Python
206 lines
6.6 KiB
Python
"""
|
|
Video API routes
|
|
"""
|
|
from flask import Blueprint, request, jsonify, current_app
|
|
from bson import ObjectId
|
|
from app.services.video_service import VideoService
|
|
from app.services.analysis_service import AnalysisService
|
|
from app.config import Config
|
|
|
|
video_bp = Blueprint('videos', __name__)
|
|
config = Config()
|
|
video_service = VideoService(config)
|
|
analysis_service = AnalysisService(config)
|
|
|
|
def json_response(data=None, message=None, status_code=200):
|
|
"""Create JSON response"""
|
|
response = {'success': status_code < 400}
|
|
if data is not None:
|
|
response['data'] = data
|
|
if message:
|
|
response['message'] = message
|
|
return jsonify(response), status_code
|
|
|
|
def error_response(message, status_code=400):
|
|
"""Create error response"""
|
|
return json_response(message=message, status_code=status_code)
|
|
|
|
@video_bp.route('/upload', methods=['POST'])
|
|
def upload_video():
|
|
"""Upload video file"""
|
|
if 'file' not in request.files:
|
|
return error_response('No file provided', 400)
|
|
|
|
file = request.files['file']
|
|
if file.filename == '':
|
|
return error_response('No file selected', 400)
|
|
|
|
video, error = video_service.upload_video(file)
|
|
if error:
|
|
return error_response(error, 400)
|
|
|
|
return json_response({
|
|
'video_id': str(video._id),
|
|
'filename': video.filename,
|
|
'file_size': video.file_size,
|
|
'status': video.status,
|
|
'upload_time': video.upload_time.isoformat()
|
|
}, message='Video uploaded successfully', status_code=201)
|
|
|
|
@video_bp.route('', methods=['GET'])
|
|
def list_videos():
|
|
"""Get list of videos"""
|
|
limit = request.args.get('limit', 100, type=int)
|
|
skip = request.args.get('skip', 0, type=int)
|
|
|
|
videos = video_service.list_videos(limit=limit, skip=skip)
|
|
|
|
video_list = []
|
|
for video in videos:
|
|
video_list.append({
|
|
'id': str(video._id),
|
|
'filename': video.filename,
|
|
'file_size': video.file_size,
|
|
'status': video.status,
|
|
'upload_time': video.upload_time.isoformat()
|
|
})
|
|
|
|
return json_response(video_list)
|
|
|
|
@video_bp.route('/<video_id>', methods=['GET'])
|
|
def get_video(video_id):
|
|
"""Get video details"""
|
|
video = video_service.get_video(video_id)
|
|
if not video:
|
|
return error_response('Video not found', 404)
|
|
|
|
# Get analysis and summary if available
|
|
analysis = analysis_service.get_analysis(video_id)
|
|
summary = analysis_service.get_summary(video_id)
|
|
|
|
data = {
|
|
'id': str(video._id),
|
|
'filename': video.filename,
|
|
'file_path': video.file_path,
|
|
'file_size': video.file_size,
|
|
'mime_type': video.mime_type,
|
|
'status': video.status,
|
|
'upload_time': video.upload_time.isoformat()
|
|
}
|
|
|
|
if analysis:
|
|
data['analysis'] = {
|
|
'id': str(analysis._id),
|
|
'content': analysis.content,
|
|
'fps': analysis.fps,
|
|
'created_at': analysis.created_at.isoformat()
|
|
}
|
|
|
|
if summary:
|
|
data['summary'] = {
|
|
'id': str(summary._id),
|
|
'summary_text': summary.summary_text,
|
|
'created_at': summary.created_at.isoformat()
|
|
}
|
|
|
|
return json_response(data)
|
|
|
|
@video_bp.route('/<video_id>/analyze', methods=['POST'])
|
|
def analyze_video(video_id):
|
|
"""Analyze video content"""
|
|
prompt = None
|
|
if request.is_json and request.get_json():
|
|
prompt = request.get_json().get('prompt')
|
|
|
|
analysis, error = analysis_service.analyze_video(video_id, prompt)
|
|
if error:
|
|
current_app.logger.error(f"Video analysis failed for {video_id}: {error}")
|
|
return error_response(error, 400)
|
|
|
|
return json_response({
|
|
'id': str(analysis._id),
|
|
'video_id': video_id,
|
|
'content': analysis.content,
|
|
'fps': analysis.fps,
|
|
'created_at': analysis.created_at.isoformat()
|
|
}, message='Video analyzed successfully', status_code=201)
|
|
|
|
@video_bp.route('/<video_id>/summarize', methods=['POST'])
|
|
def summarize_video(video_id):
|
|
"""Generate video summary"""
|
|
summary, error = analysis_service.summarize_video(video_id)
|
|
if error:
|
|
current_app.logger.error(f"Video summarization failed for {video_id}: {error}")
|
|
return error_response(error, 400)
|
|
|
|
return json_response({
|
|
'id': str(summary._id),
|
|
'video_id': video_id,
|
|
'summary_text': summary.summary_text,
|
|
'created_at': summary.created_at.isoformat()
|
|
}, message='Summary generated successfully', status_code=201)
|
|
|
|
@video_bp.route('/<video_id>/summary', methods=['GET'])
|
|
def get_summary(video_id):
|
|
"""Get video summary"""
|
|
summary = analysis_service.get_summary(video_id)
|
|
if not summary:
|
|
return error_response('Summary not found', 404)
|
|
|
|
return json_response({
|
|
'id': str(summary._id),
|
|
'video_id': video_id,
|
|
'summary_text': summary.summary_text,
|
|
'created_at': summary.created_at.isoformat()
|
|
})
|
|
|
|
@video_bp.route('/compare', methods=['POST'])
|
|
def compare_videos():
|
|
"""Compare multiple videos"""
|
|
if not request.is_json:
|
|
return error_response('JSON body required', 400)
|
|
|
|
data = request.json
|
|
video_ids = data.get('video_ids', [])
|
|
|
|
if not isinstance(video_ids, list) or len(video_ids) < 2:
|
|
return error_response('At least two video IDs are required', 400)
|
|
|
|
comparison, error = analysis_service.compare_videos(video_ids)
|
|
if error:
|
|
current_app.logger.error(f"Video comparison failed: {error}")
|
|
return error_response(error, 400)
|
|
|
|
return json_response({
|
|
'id': str(comparison._id),
|
|
'video_ids': [str(vid) for vid in comparison.video_ids],
|
|
'comparison_result': comparison.comparison_result,
|
|
'created_at': comparison.created_at.isoformat()
|
|
}, message='Comparison completed successfully', status_code=201)
|
|
|
|
@video_bp.route('/compare/<comparison_id>', methods=['GET'])
|
|
def get_comparison(comparison_id):
|
|
"""Get comparison result"""
|
|
from app.models.comparison import Comparison
|
|
comparison = Comparison.find_by_id(comparison_id)
|
|
if not comparison:
|
|
return error_response('Comparison not found', 404)
|
|
|
|
return json_response({
|
|
'id': str(comparison._id),
|
|
'video_ids': [str(vid) for vid in comparison.video_ids],
|
|
'comparison_result': comparison.comparison_result,
|
|
'created_at': comparison.created_at.isoformat()
|
|
})
|
|
|
|
@video_bp.errorhandler(404)
|
|
def not_found(error):
|
|
"""Handle 404 errors"""
|
|
return error_response('Endpoint not found', 404)
|
|
|
|
@video_bp.errorhandler(500)
|
|
def internal_error(error):
|
|
"""Handle 500 errors"""
|
|
return error_response('Internal server error', 500)
|
|
|