# ============================================================================== # S2V BACKEND API SYSTEM (Pure API - Based on your Original Logic) # UPDATE: Added 'story_mode' parsing and arguments for AI Editor strictness # ============================================================================== import os import uuid import threading import zipfile from io import BytesIO from datetime import datetime from flask import Flask, request, jsonify, send_from_directory, send_file from werkzeug.utils import secure_filename # आपके engine और core से इम्पोर्ट्स from engine import run_ai_engine_worker, generate_script_with_ai from core.constants import UPLOAD_FOLDER, OUTPUT_FOLDER from core.database import init_db, create_task, get_task app = Flask(__name__) # फ़ोल्डर्स सुनिश्चित करें os.makedirs(UPLOAD_FOLDER, exist_ok=True) os.makedirs(OUTPUT_FOLDER, exist_ok=True) # डेटाबेस शुरू करें init_db() # ========================================== # 0. ROOT / HEALTH CHECK (404 से बचने के लिए) # ========================================== @app.route('/', methods=['GET']) def index(): return jsonify({ "status": "success", "message": "Welcome to S2V Backend API System! Server is up and running. 🚀" }), 200 # ========================================== # 1. GENERATE SCRIPT # ========================================== @app.route('/generate-script', methods=['POST']) def generate_script(): data = request.get_json() # FIX: आपके ओरिजिनल कोड की तरह 'topic' का इस्तेमाल topic = data.get('topic') video_length = data.get('video_length') if not topic or not video_length: return jsonify({'error': 'Topic and video length are required.'}), 400 try: generated_script = generate_script_with_ai(topic, video_length) return jsonify({'script': generated_script}), 200 except Exception as e: return jsonify({'error': f"AI से संपर्क करने में विफल: {str(e)}"}), 500 # ========================================== # 2. MAIN PROCESS TASK # ========================================== @app.route('/process', methods=['POST']) def process_video(): task_id = str(uuid.uuid4()) create_task(task_id) script_text = request.form.get('script_text') script_file = request.files.get('script_file') orientation = request.form.get('orientation', 'horizontal') # 💡 FIX: API के लिए story_mode पार्सिंग (सपोर्ट्स 'true', '1', 'on') story_mode_str = str(request.form.get('story_mode', 'false')).lower() story_mode = story_mode_str in ['true', '1', 'on'] script_file_path = None if script_file and script_file.filename: filename = secure_filename(script_file.filename) task_upload_dir = os.path.join(UPLOAD_FOLDER, task_id) os.makedirs(task_upload_dir, exist_ok=True) script_file_path = os.path.join(task_upload_dir, filename) script_file.save(script_file_path) if not script_text and not script_file_path: return jsonify({"error": "Please provide a script text or an audio file."}), 400 # इंजन बैकग्राउंड में स्टार्ट करें (story_mode आर्गुमेंट के साथ) thread = threading.Thread( target=run_ai_engine_worker, args=(task_id, script_text, script_file_path, orientation, story_mode) ) thread.start() # चूँकि यह API है, HTML नहीं, हम JSON लौटाएंगे return jsonify({"task_id": task_id, "status": "processing"}), 202 # ========================================== # 3. TASK PROGRESS # ========================================== @app.route('/progress/') def progress(task_id): task = get_task(task_id) if not task: return jsonify({'status': 'error', 'log': 'Task not found.'}), 404 return jsonify(dict(task)), 200 # ========================================== # 4. SERVE OUTPUT FILES # ========================================== @app.route('/outputs/') def serve_output_file(filename): return send_from_directory(OUTPUT_FOLDER, filename) # ========================================== # 5. HISTORY (FILE BASED TIMESTAMPS) # ========================================== @app.route('/history') def history(): history_items = [] try: all_files = sorted(os.listdir(OUTPUT_FOLDER), reverse=True) for filename in all_files: if filename.endswith('_final_video.mp4'): task_id = filename.replace('_final_video.mp4', '') report_filename = f"{task_id}_report.json" # आपके ओरिजिनल कोड की तरह Timestamp निकालना filepath = os.path.join(OUTPUT_FOLDER, filename) time_sec = os.path.getmtime(filepath) timestamp_str = datetime.fromtimestamp(time_sec).strftime('%Y-%m-%d %H:%M:%S') item = { 'video': filename, 'task_id': task_id, 'report': report_filename if report_filename in all_files else None, 'timestamp': timestamp_str } history_items.append(item) except FileNotFoundError: pass return jsonify({'history': history_items}), 200 # ========================================== # 6. DELETE HISTORY # ========================================== @app.route('/history/delete', methods=['POST']) def delete_history(): data = request.get_json() task_ids = data.get('task_ids', []) for tid in task_ids: # वीडियो डिलीट करें vid_path = os.path.join(OUTPUT_FOLDER, f"{tid}_final_video.mp4") if os.path.exists(vid_path): os.remove(vid_path) # रिपोर्ट डिलीट करें rep_path = os.path.join(OUTPUT_FOLDER, f"{tid}_report.json") if os.path.exists(rep_path): os.remove(rep_path) return jsonify({'success': True}), 200 # ========================================== # 7. DOWNLOAD ZIP HISTORY # ========================================== @app.route('/history/download', methods=['POST']) def download_history(): data = request.get_json() task_ids = data.get('task_ids', []) memory_file = BytesIO() with zipfile.ZipFile(memory_file, 'w') as zf: for tid in task_ids: vid_path = os.path.join(OUTPUT_FOLDER, f"{tid}_final_video.mp4") if os.path.exists(vid_path): zf.write(vid_path, f"{tid}_video.mp4") memory_file.seek(0) return send_file(memory_file, download_name='Sparkling_Gyan_Videos.zip', as_attachment=True) if __name__ == '__main__': # Hugging Face Spaces default port app.run(host='0.0.0.0', port=7860)