"""JustVitamin × QuikCue — AI Content Engine Live proposal site with real Gemini-powered demos.""" import os, json, time, traceback from pathlib import Path from flask import (Flask, render_template, jsonify, request, send_from_directory, redirect) from scraper import scrape_product, scrape_competitor from ai_engine import (generate_asset_pack, competitor_xray, pdp_surgeon, optimise_pdp_copy, generate_product_images) app = Flask(__name__, static_folder="static", template_folder="templates") GEN_DIR = Path(__file__).parent / "generated" GEN_DIR.mkdir(exist_ok=True) # ── Page routes ────────────────────────────────────────────── @app.route("/") def index(): return render_template("index.html") @app.route("/dashboard") def dashboard(): return send_from_directory("static/dashboard", "index.html") @app.route("/dashboard/jv_data.json") def dashboard_data(): return send_from_directory("static/dashboard", "jv_data.json") @app.route("/proposal") def proposal(): return send_from_directory("static/proposal", "index.html") @app.route("/offer") def offer(): return send_from_directory("static/offer", "index.html") @app.route("/generated/") def serve_generated(filename): return send_from_directory(GEN_DIR, filename) # ── API: Scrape ────────────────────────────────────────────── @app.route("/api/scrape", methods=["POST"]) def api_scrape(): """Scrape a JustVitamins product page.""" url = request.json.get("url", "").strip() if not url: return jsonify({"error": "No URL provided"}), 400 try: data = scrape_product(url) if not data.get("title"): return jsonify({"error": "Could not find product. Check URL."}), 400 return jsonify(data) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 @app.route("/api/scrape-competitor", methods=["POST"]) def api_scrape_competitor(): """Scrape any competitor product page.""" url = request.json.get("url", "").strip() if not url: return jsonify({"error": "No URL provided"}), 400 try: data = scrape_competitor(url) if not data.get("title"): return jsonify({"error": "Could not extract product data."}), 400 return jsonify(data) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 # ── API: Demo A — 12-Asset Pack ────────────────────────────── @app.route("/api/generate-pack", methods=["POST"]) def api_generate_pack(): """Generate a full 12-asset marketing pack from product data.""" product = request.json if not product: return jsonify({"error": "No product data"}), 400 try: t0 = time.time() pack = generate_asset_pack(product) pack["_generation_time"] = f"{time.time()-t0:.1f}s" pack["_product_title"] = product.get("title", "") return jsonify(pack) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 # ── API: Demo B — Competitor X-Ray ─────────────────────────── @app.route("/api/competitor-xray", methods=["POST"]) def api_competitor_xray(): """Scrape competitor + run AI analysis.""" url = request.json.get("url", "").strip() if not url: return jsonify({"error": "No URL provided"}), 400 try: t0 = time.time() comp_data = scrape_competitor(url) if not comp_data.get("title"): return jsonify({"error": "Could not scrape competitor page."}), 400 analysis = competitor_xray(comp_data) analysis["_scrape_data"] = { "title": comp_data.get("title"), "price": comp_data.get("price"), "brand": comp_data.get("brand"), "url": url, } analysis["_generation_time"] = f"{time.time()-t0:.1f}s" return jsonify(analysis) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 # ── API: Demo C — PDP Surgeon ──────────────────────────────── @app.route("/api/pdp-surgeon", methods=["POST"]) def api_pdp_surgeon(): """Rewrite PDP copy in a given style.""" data = request.json or {} product = data.get("product") style = data.get("style", "balanced") if not product: return jsonify({"error": "No product data"}), 400 try: t0 = time.time() result = pdp_surgeon(product, style) result["_generation_time"] = f"{time.time()-t0:.1f}s" return jsonify(result) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 # ── API: Full PDP Optimise ─────────────────────────────────── @app.route("/api/optimise", methods=["POST"]) def api_optimise(): """Full PDP rewrite — scrape + AI copy.""" product = request.json if not product: return jsonify({"error": "No product data"}), 400 try: t0 = time.time() copy = optimise_pdp_copy(product) copy["_generation_time"] = f"{time.time()-t0:.1f}s" return jsonify(copy) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 # ── API: Image Generation ──────────────────────────────────── @app.route("/api/generate-images", methods=["POST"]) def api_generate_images(): """Generate AI product images via Nano Banana / Pro.""" product = request.json if not product: return jsonify({"error": "No product data"}), 400 try: t0 = time.time() images = generate_product_images(product) images["_generation_time"] = f"{time.time()-t0:.1f}s" return jsonify(images) except Exception as e: traceback.print_exc() return jsonify({"error": str(e)}), 500 # ── Health check ───────────────────────────────────────────── @app.route("/api/health") def health(): return jsonify({ "status": "ok", "gemini_key_set": bool(os.environ.get("GEMINI_API_KEY")), }) if __name__ == "__main__": app.run(host="0.0.0.0", port=5050, debug=True)