""" 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('/', 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('//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('//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('//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/', 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)