Spaces:
Sleeping
Sleeping
| import os | |
| import time | |
| from flask import Flask, render_template, request, jsonify, send_from_directory | |
| from werkzeug.utils import secure_filename | |
| # Import Services (We will create these next) | |
| # Note: Ensure empty __init__.py exists in services/ folder | |
| from services.studio import StudioService | |
| from services.vision import VisionService | |
| from services.ai_studio import AIStudioService | |
| from services.utilities import UtilitiesService | |
| # Initialize Flask App | |
| app = Flask(__name__) | |
| # --- Configuration --- | |
| UPLOAD_FOLDER = 'static/uploads' | |
| ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'webp', 'bmp'} | |
| app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
| app.config['MAX_CONTENT_LENGTH'] = 32 * 1024 * 1024 | |
| app.secret_key = 'radiant_secret_key_dev' | |
| # Ensure upload directory exists | |
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
| # Initialize Service Instances | |
| studio_service = StudioService() | |
| vision_service = VisionService() | |
| ai_service = AIStudioService() | |
| utilities_service = UtilitiesService() | |
| # --- Helpers --- | |
| def allowed_file(filename): | |
| return ( | |
| '.' in filename and | |
| filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | |
| ) | |
| def get_file_path(filename): | |
| return os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(filename)) | |
| def generate_output_filename(original_filename, prefix="processed"): | |
| timestamp = int(time.time()) | |
| name, ext = os.path.splitext(original_filename) | |
| return f"{prefix}_{timestamp}_{name}{ext}" | |
| # --- Page Routes (Frontend) --- | |
| def index(): | |
| return render_template('onboarding.html') | |
| def studio(): | |
| return render_template('studio.html') | |
| def vision(): | |
| return render_template('vision.html') | |
| def ai_studio(): | |
| return render_template('ai_studio.html') | |
| def utilities(): | |
| return render_template('utilities.html') | |
| def about(): | |
| return render_template('about.html') | |
| #@app.route('/products') | |
| #def products(): | |
| # return render_template('products.html') | |
| def docs(): | |
| return render_template('docs.html') | |
| def download(): | |
| return render_template('download.html') | |
| # --- API: Core Upload --- | |
| def upload_file(): | |
| if 'file' not in request.files: | |
| return jsonify({'success': False, 'error': 'No file part'}), 400 | |
| file = request.files['file'] | |
| if file.filename == '': | |
| return jsonify({'success': False, 'error': 'No selected file'}), 400 | |
| if file and allowed_file(file.filename): | |
| # Create unique filename | |
| filename = secure_filename(f"{int(time.time())}_{file.filename}") | |
| filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
| file.save(filepath) | |
| return jsonify({ | |
| 'success': True, | |
| 'filename': filename, | |
| 'url': f"/static/uploads/{filename}" | |
| }) | |
| return jsonify({'success': False, 'error': 'Invalid file type'}), 400 | |
| # --- API: Studio (Image Editing) --- | |
| def process_studio(): | |
| try: | |
| data = request.json | |
| filename = data.get('filename') | |
| options = data.get('options') # Contains brightness, contrast, filter, etc. | |
| if not filename or not options: | |
| return jsonify({'success': False, 'error': 'Missing parameters'}), 400 | |
| input_path = get_file_path(filename) | |
| output_filename = generate_output_filename(filename, "edit") | |
| output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename) | |
| # Call Service | |
| success, result = studio_service.process_request(input_path, output_path, options) | |
| if success: | |
| return jsonify({ | |
| 'success': True, | |
| 'url': f"/static/uploads/{output_filename}", | |
| 'filename': output_filename | |
| }) | |
| else: | |
| return jsonify({'success': False, 'error': str(result)}), 500 | |
| except Exception as e: | |
| return jsonify({'success': False, 'error': str(e)}), 500 | |
| # --- API: Vision (YOLO, BG Remove) --- | |
| def process_vision(): | |
| try: | |
| data = request.json | |
| filename = data.get('filename') | |
| task = data.get('task') | |
| # extra options like 'color' for bg replacement or 'value' for blur intensity | |
| options = data | |
| if not filename or not task: | |
| return jsonify({'success': False, 'error': 'Missing parameters'}), 400 | |
| input_path = get_file_path(filename) | |
| output_filename = generate_output_filename(filename, f"vision_{task}") | |
| output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename) | |
| success, result_meta = vision_service.process_request(input_path, output_path, task, options) | |
| if success: | |
| response = { | |
| 'success': True, | |
| 'url': f"/static/uploads/{output_filename}", | |
| 'filename': output_filename | |
| } | |
| # Add detections if they exist (for YOLO) | |
| if isinstance(result_meta, dict) and 'detections' in result_meta: | |
| response['detections'] = result_meta['detections'] | |
| return jsonify(response) | |
| else: | |
| return jsonify({'success': False, 'error': str(result_meta)}), 500 | |
| except Exception as e: | |
| return jsonify({'success': False, 'error': str(e)}), 500 | |
| # --- API: AI Studio (Colorize, Upscale) --- | |
| def process_ai(): | |
| try: | |
| data = request.json | |
| filename = data.get('filename') | |
| task = data.get('task') | |
| if not filename or not task: | |
| return jsonify({'success': False, 'error': 'Missing parameters'}), 400 | |
| input_path = get_file_path(filename) | |
| output_filename = generate_output_filename(filename, f"ai_{task}") | |
| output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename) | |
| success, result = ai_service.process_request(input_path, output_path, task) | |
| if success: | |
| return jsonify({ | |
| 'success': True, | |
| 'url': f"/static/uploads/{output_filename}", | |
| 'filename': output_filename | |
| }) | |
| else: | |
| return jsonify({'success': False, 'error': str(result)}), 500 | |
| except Exception as e: | |
| return jsonify({'success': False, 'error': str(e)}), 500 | |
| # --- API: Utilities (Convert, Resize) --- | |
| def process_utility(): | |
| try: | |
| data = request.json | |
| filename = data.get('filename') | |
| # Service handles specific logic internally | |
| input_path = get_file_path(filename) | |
| # Output directory is passed so service can generate name based on format | |
| output_dir = app.config['UPLOAD_FOLDER'] | |
| success, result = utilities_service.process_request(input_path, output_dir, data) | |
| if success: | |
| if data.get('action') == 'metadata': | |
| return jsonify({'success': True, 'metadata': result}) | |
| else: | |
| return jsonify({ | |
| 'success': True, | |
| 'url': f"/static/uploads/{result}", | |
| 'filename': result | |
| }) | |
| else: | |
| return jsonify({'success': False, 'error': str(result)}), 500 | |
| except Exception as e: | |
| return jsonify({'success': False, 'error': str(e)}), 500 | |
| # --- Serve Static Files (Images) --- | |
| def uploaded_file(filename): | |
| return send_from_directory(app.config['UPLOAD_FOLDER'], filename) | |
| if __name__ == '__main__': | |
| #print("Radiant AI Server (local dev)") | |
| app.run(host='0.0.0.0', port=7860) | |