Spaces:
Sleeping
Sleeping
Tecnhotron commited on
Commit ·
9517d02
1
Parent(s): 7bc21ad
BIG CHANGES
Browse files- app.py +21 -3
- requirements.txt +0 -1
- templates/index.html +12 -3
app.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
| 1 |
import re
|
| 2 |
import subprocess
|
| 3 |
-
import asyncio
|
| 4 |
from google import genai
|
| 5 |
from google.genai import types
|
| 6 |
-
import aiofiles
|
| 7 |
import os, uuid
|
| 8 |
import time
|
| 9 |
import mimetypes
|
|
@@ -12,6 +10,7 @@ import threading
|
|
| 12 |
from pathlib import Path
|
| 13 |
from flask import Flask, render_template, request, send_file, jsonify
|
| 14 |
from werkzeug.utils import secure_filename
|
|
|
|
| 15 |
import traceback
|
| 16 |
import logging
|
| 17 |
from typing import Dict, Any, List, Optional
|
|
@@ -439,6 +438,7 @@ Guidelines:
|
|
| 439 |
|
| 440 |
raw_llm_output = answer
|
| 441 |
logger.info(f"Received editing plan (length: {len(raw_llm_output)}) [{request_id}]")
|
|
|
|
| 442 |
update_progress(request_id, "PLANNING", "Parsing editing plan...")
|
| 443 |
|
| 444 |
# Parse JSON
|
|
@@ -721,6 +721,7 @@ def process_video_request(request_id: str, form_data: Dict, file_paths: Dict, ap
|
|
| 721 |
'status': 'success',
|
| 722 |
'message': 'Clipchamp project saved successfully!',
|
| 723 |
'clipchamp_path': saved_path,
|
|
|
|
| 724 |
'project_name': project_name,
|
| 725 |
'request_id': request_id
|
| 726 |
}
|
|
@@ -922,7 +923,6 @@ def generate_video_post():
|
|
| 922 |
})
|
| 923 |
|
| 924 |
except Exception as e:
|
| 925 |
-
from werkzeug.exceptions import RequestEntityTooLarge
|
| 926 |
if isinstance(e, RequestEntityTooLarge):
|
| 927 |
logger.warning(f"Upload too large in /generate [{request_id}]")
|
| 928 |
return jsonify({'status': 'error', 'message': f'Upload too large. Max {MAX_UPLOAD_SIZE // (1024*1024)} MB.'}), 413
|
|
@@ -962,5 +962,23 @@ def download_file(filename):
|
|
| 962 |
return response
|
| 963 |
|
| 964 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 965 |
if __name__ == '__main__':
|
| 966 |
app.run(host='0.0.0.0', port=7860, debug=False, threaded=True)
|
|
|
|
| 1 |
import re
|
| 2 |
import subprocess
|
|
|
|
| 3 |
from google import genai
|
| 4 |
from google.genai import types
|
|
|
|
| 5 |
import os, uuid
|
| 6 |
import time
|
| 7 |
import mimetypes
|
|
|
|
| 10 |
from pathlib import Path
|
| 11 |
from flask import Flask, render_template, request, send_file, jsonify
|
| 12 |
from werkzeug.utils import secure_filename
|
| 13 |
+
from werkzeug.exceptions import RequestEntityTooLarge
|
| 14 |
import traceback
|
| 15 |
import logging
|
| 16 |
from typing import Dict, Any, List, Optional
|
|
|
|
| 438 |
|
| 439 |
raw_llm_output = answer
|
| 440 |
logger.info(f"Received editing plan (length: {len(raw_llm_output)}) [{request_id}]")
|
| 441 |
+
logger.info(f"Raw LLM response (first 500 chars): {raw_llm_output[:500]}... [{request_id}]")
|
| 442 |
update_progress(request_id, "PLANNING", "Parsing editing plan...")
|
| 443 |
|
| 444 |
# Parse JSON
|
|
|
|
| 721 |
'status': 'success',
|
| 722 |
'message': 'Clipchamp project saved successfully!',
|
| 723 |
'clipchamp_path': saved_path,
|
| 724 |
+
'clipchamp_url': f"/project/{os.path.basename(saved_path)}",
|
| 725 |
'project_name': project_name,
|
| 726 |
'request_id': request_id
|
| 727 |
}
|
|
|
|
| 923 |
})
|
| 924 |
|
| 925 |
except Exception as e:
|
|
|
|
| 926 |
if isinstance(e, RequestEntityTooLarge):
|
| 927 |
logger.warning(f"Upload too large in /generate [{request_id}]")
|
| 928 |
return jsonify({'status': 'error', 'message': f'Upload too large. Max {MAX_UPLOAD_SIZE // (1024*1024)} MB.'}), 413
|
|
|
|
| 962 |
return response
|
| 963 |
|
| 964 |
|
| 965 |
+
@app.route('/project/<path:filename>')
|
| 966 |
+
def download_project(filename):
|
| 967 |
+
"""Serves the generated .clipchamp project file."""
|
| 968 |
+
safe_filename = secure_filename(filename)
|
| 969 |
+
if safe_filename != filename or '/' in filename or '\\' in filename:
|
| 970 |
+
logger.warning(f"Attempt to access potentially unsafe project path rejected: {filename}")
|
| 971 |
+
return "Invalid filename", 400
|
| 972 |
+
|
| 973 |
+
file_path = os.path.join(app.config.get('CLIPCHAMP_FOLDER', 'clipchamp_projects'), safe_filename)
|
| 974 |
+
logger.info(f"Attempting to send project file: {file_path}")
|
| 975 |
+
|
| 976 |
+
if not os.path.exists(file_path):
|
| 977 |
+
logger.error(f"Project download request: File not found at {file_path}")
|
| 978 |
+
return "File not found", 404
|
| 979 |
+
|
| 980 |
+
return send_file(file_path, as_attachment=True, download_name=safe_filename)
|
| 981 |
+
|
| 982 |
+
|
| 983 |
if __name__ == '__main__':
|
| 984 |
app.run(host='0.0.0.0', port=7860, debug=False, threaded=True)
|
requirements.txt
CHANGED
|
@@ -2,4 +2,3 @@ Flask
|
|
| 2 |
gunicorn
|
| 3 |
google-genai
|
| 4 |
httpx[http2]
|
| 5 |
-
aiofiles
|
|
|
|
| 2 |
gunicorn
|
| 3 |
google-genai
|
| 4 |
httpx[http2]
|
|
|
templates/index.html
CHANGED
|
@@ -594,8 +594,8 @@
|
|
| 594 |
</div>
|
| 595 |
|
| 596 |
<div class="input-group">
|
| 597 |
-
<label for="output">
|
| 598 |
-
<input type="text" id="output" name="output" value="
|
| 599 |
</div>
|
| 600 |
|
| 601 |
<button type="submit" id="submit-button" class="generate-btn">
|
|
@@ -770,10 +770,19 @@
|
|
| 770 |
progressArea.style.display = 'none';
|
| 771 |
const resultData = data.result || {};
|
| 772 |
|
| 773 |
-
if (resultData.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 774 |
modalTitle.textContent = 'RENDER COMPLETE';
|
|
|
|
| 775 |
modalVideo.src = resultData.video_url;
|
| 776 |
modalDownloadLink.href = resultData.video_url;
|
|
|
|
| 777 |
modalDownloadLink.download = resultData.output_filename || 'velocity_edit.mp4';
|
| 778 |
modalVideo.load();
|
| 779 |
videoModal.style.display = 'flex';
|
|
|
|
| 594 |
</div>
|
| 595 |
|
| 596 |
<div class="input-group">
|
| 597 |
+
<label for="output">Project Name</label>
|
| 598 |
+
<input type="text" id="output" name="output" value="decor" required>
|
| 599 |
</div>
|
| 600 |
|
| 601 |
<button type="submit" id="submit-button" class="generate-btn">
|
|
|
|
| 770 |
progressArea.style.display = 'none';
|
| 771 |
const resultData = data.result || {};
|
| 772 |
|
| 773 |
+
if (resultData.clipchamp_url) {
|
| 774 |
+
modalTitle.textContent = 'PROJECT READY';
|
| 775 |
+
modalVideo.style.display = 'none'; // No video preview for .clipchamp files
|
| 776 |
+
modalDownloadLink.href = resultData.clipchamp_url;
|
| 777 |
+
modalDownloadLink.innerHTML = '<i class="fas fa-download"></i> DOWNLOAD .CLIPCHAMP';
|
| 778 |
+
modalDownloadLink.download = resultData.project_name + '.clipchamp';
|
| 779 |
+
videoModal.style.display = 'flex';
|
| 780 |
+
} else if (resultData.video_url) {
|
| 781 |
modalTitle.textContent = 'RENDER COMPLETE';
|
| 782 |
+
modalVideo.style.display = 'block';
|
| 783 |
modalVideo.src = resultData.video_url;
|
| 784 |
modalDownloadLink.href = resultData.video_url;
|
| 785 |
+
modalDownloadLink.innerHTML = '<i class="fas fa-download"></i> DOWNLOAD ASSET';
|
| 786 |
modalDownloadLink.download = resultData.output_filename || 'velocity_edit.mp4';
|
| 787 |
modalVideo.load();
|
| 788 |
videoModal.style.display = 'flex';
|