Spaces:
Running
Running
| # ============================================================================== | |
| # 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 से बचने के लिए) | |
| # ========================================== | |
| def index(): | |
| return jsonify({ | |
| "status": "success", | |
| "message": "Welcome to S2V Backend API System! Server is up and running. 🚀" | |
| }), 200 | |
| # ========================================== | |
| # 1. GENERATE SCRIPT | |
| # ========================================== | |
| 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 | |
| # ========================================== | |
| 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 | |
| # ========================================== | |
| 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 | |
| # ========================================== | |
| def serve_output_file(filename): | |
| return send_from_directory(OUTPUT_FOLDER, filename) | |
| # ========================================== | |
| # 5. HISTORY (FILE BASED TIMESTAMPS) | |
| # ========================================== | |
| 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 | |
| # ========================================== | |
| 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 | |
| # ========================================== | |
| 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) | |