s2v / app.py
diwash-barla1's picture
Initial commit with clean history
aa642ce
Raw
History Blame Contribute Delete
7.15 kB
# ==============================================================================
# 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/<task_id>')
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/<path:filename>')
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)