Spaces:
Sleeping
Sleeping
fix: Wrap global Hugging Face upload block to bypass blind JavaScript rejection and print precise tracebacks
f6b055d | import os | |
| from flask_caching import Cache | |
| import uuid | |
| import json | |
| from ai_agent import process_room_design | |
| from cv_analyzer import analyze_room_image | |
| from flask import Flask, render_template, request, redirect, url_for, flash, session | |
| from config import Config | |
| from models import db, User, Design, Furniture, Booking | |
| # 1. Create the app first | |
| app = Flask(__name__) | |
| # Configure Redis Caching | |
| app.config['CACHE_TYPE'] = 'SimpleCache' | |
| app.config['CACHE_REDIS_HOST'] = 'localhost' | |
| app.config['CACHE_REDIS_PORT'] = 6379 | |
| app.config['CACHE_DEFAULT_TIMEOUT'] = 3600 # Cache results for 1 hour | |
| cache = Cache(app) | |
| # 3. Apply the rest of the configurations | |
| app.config.from_object(Config) | |
| db.init_app(app) | |
| # Ensure upload directory exists | |
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
| def allowed_file(filename): | |
| return '.' in filename and \ | |
| filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS'] | |
| # 1. Update your app_context to add dummy furniture data | |
| with app.app_context(): | |
| db.create_all() | |
| # Force recreate furniture catalog dynamically without sticking to old local DB bounds | |
| Furniture.query.delete() | |
| sample_items = [ | |
| # Modern Theme | |
| Furniture(name="Sleek Leather Sofa", category="Modern", price=45000, image_url="https://images.unsplash.com/photo-1555041469-a586c61ea9bc?w=500&q=80"), | |
| Furniture(name="Glass Center Table", category="Modern", price=15000, image_url="https://images.unsplash.com/photo-1533090481720-856c6e3c1fdc?w=500&q=80"), | |
| Furniture(name="Minimalist Shelf", category="Modern", price=9500, image_url="https://images.unsplash.com/photo-1595514535415-842273ac3299?w=500&q=80"), | |
| Furniture(name="Floating Wall Canvas", category="Modern", price=5500, image_url="https://images.unsplash.com/photo-1579762715111-a6c40cb81ed0?w=500&q=80"), | |
| # Bohemian Theme | |
| Furniture(name="Rattan Lounge Chair", category="Bohemian", price=8500, image_url="https://images.unsplash.com/photo-1567538096630-e0c55bd6374c?w=500&q=80"), | |
| Furniture(name="Vintage Persian Rug", category="Bohemian", price=12000, image_url="https://images.unsplash.com/photo-1600166898405-da9535204843?w=500&q=80"), | |
| Furniture(name="Handwoven Macrame", category="Bohemian", price=2500, image_url="https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=500&q=80"), | |
| Furniture(name="Tropical Potted Monstera", category="Bohemian", price=1500, image_url="https://images.unsplash.com/photo-1614594975525-e45190c55d0b?w=500&q=80"), | |
| # Industrial Theme | |
| Furniture(name="Exposed Metal Lamp", category="Industrial", price=3500, image_url="https://images.unsplash.com/photo-1513506003901-1e6a229e2d15?w=500&q=80"), | |
| Furniture(name="Steel Frame Rack", category="Industrial", price=18000, image_url="https://images.unsplash.com/photo-1595526114035-0d45ed16cfbf?w=500&q=80"), | |
| Furniture(name="Distressed Leather Chair", category="Industrial", price=28000, image_url="https://images.unsplash.com/photo-1581539250439-c96689b516dd?w=500&q=80") | |
| ] | |
| db.session.add_all(sample_items) | |
| db.session.commit() | |
| def index(): | |
| return render_template('index.html') | |
| def register(): | |
| if request.method == 'POST': | |
| username = request.form.get('username') | |
| email = request.form.get('email') | |
| password = request.form.get('password') | |
| # Check if user already exists | |
| user = User.query.filter_by(email=email).first() | |
| if user: | |
| flash('Email address already exists.', 'error') | |
| return redirect(url_for('register')) | |
| # Create and save the new user | |
| new_user = User(username=username, email=email) | |
| new_user.set_password(password) | |
| db.session.add(new_user) | |
| db.session.commit() | |
| flash('Registration successful! Please log in.', 'success') | |
| return redirect(url_for('login')) | |
| return render_template('register.html') | |
| def login(): | |
| if request.method == 'POST': | |
| email = request.form.get('email') | |
| password = request.form.get('password') | |
| # Verify credentials | |
| user = User.query.filter_by(email=email).first() | |
| if user and user.check_password(password): | |
| session['user_id'] = user.user_id | |
| session['username'] = user.username | |
| flash('Logged in successfully!', 'success') | |
| return redirect(url_for('design')) | |
| else: | |
| flash('Invalid email or password.', 'error') | |
| return render_template('login.html') | |
| def logout(): | |
| session.clear() | |
| return redirect(url_for('index')) | |
| def design(): | |
| if 'user_id' not in session: | |
| flash("Please log in to create a design.", "error") | |
| return redirect(url_for('login')) | |
| return render_template('design.html') | |
| def upload(): | |
| try: | |
| if 'user_id' not in session: | |
| return {"error": "Unauthorized. Please log in."}, 401 | |
| if 'image' not in request.files: | |
| return {"error": "No image provided."}, 400 | |
| file = request.files['image'] | |
| theme = request.form.get('theme', 'Modern') | |
| language = request.form.get('language', 'en') | |
| if file and allowed_file(file.filename): | |
| ext = file.filename.rsplit('.', 1)[1].lower() | |
| filename = f"{uuid.uuid4().hex}.{ext}" | |
| filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
| file.save(filepath) | |
| # Analyze image with CV Analyzer | |
| cv_result = analyze_room_image(filepath) | |
| if not cv_result.get("is_room"): | |
| return {"error": cv_result.get("error", "Image is not recognized as a valid room.")}, 400 | |
| # Trigger the AI pipeline | |
| ai_text, audio_file, ai_image = process_room_design(filename, theme, language) | |
| # Update database | |
| new_design = Design( | |
| user_id=session['user_id'], | |
| image_path=filename, | |
| selected_theme=theme, | |
| ai_output=ai_text | |
| ) | |
| db.session.add(new_design) | |
| db.session.commit() | |
| return {"redirect": url_for('result', design_id=new_design.id)}, 200 | |
| return {"error": "Invalid file type."}, 400 | |
| except Exception as e: | |
| return {"error": f"Server crash: {str(e)}"}, 500 | |
| def book(furniture_id): | |
| if 'user_id' not in session: | |
| flash("Please log in to book items.", "error") | |
| return redirect(url_for('login')) | |
| # Create a new booking | |
| new_booking = Booking( | |
| user_id=session['user_id'], | |
| furniture_id=furniture_id, | |
| status='Confirmed' | |
| ) | |
| db.session.add(new_booking) | |
| db.session.commit() | |
| flash("Item successfully booked via Buddy AI!", "success") | |
| # Send them back to the results page they were just on | |
| return redirect(request.referrer or url_for('index')) | |
| def dashboard(): | |
| if 'user_id' not in session: | |
| flash("Please log in to view your dashboard.", "error") | |
| return redirect(url_for('login')) | |
| user_id = session['user_id'] | |
| # Fetch designs and bookings for the logged-in user, newest first | |
| user_designs = Design.query.filter_by(user_id=user_id).order_by(Design.id.desc()).all() | |
| user_bookings = Booking.query.filter_by(user_id=user_id).order_by(Booking.id.desc()).all() | |
| return render_template('dashboard.html', designs=user_designs, bookings=user_bookings) | |
| # 2. Update your result route to fetch recommendations | |
| def result(design_id): | |
| if 'user_id' not in session: | |
| flash("Please log in.", "error") | |
| return redirect(url_for('login')) | |
| design = Design.query.get_or_404(design_id) | |
| # NEW: Parse the AI JSON string safely | |
| try: | |
| ai_data = json.loads(design.ai_output) | |
| display_text = ai_data.get('recommendations', design.ai_output) | |
| except: | |
| display_text = design.ai_output | |
| recommendations = Furniture.query.filter_by(category=design.selected_theme).all() | |
| return render_template('result.html', design=design, furniture=recommendations, ai_text=display_text) | |
| if __name__ == '__main__': | |
| app.run(debug=True) |