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() @app.route('/') def index(): return render_template('index.html') @app.route('/register', methods=['GET', 'POST']) @app.route('/register', methods=['GET', 'POST']) 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') @app.route('/login', methods=['GET', 'POST']) 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') @app.route('/logout') def logout(): session.clear() return redirect(url_for('index')) @app.route('/design') 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') @app.route('/upload', methods=['POST']) 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 @app.route('/book/', methods=['POST']) 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')) @app.route('/dashboard') 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 @app.route('/result/') 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)