from flask import Blueprint, request, jsonify, current_app from flask_login import login_required, current_user from models import db, UrlContext from services.url_scraper import scrape_url from services import rag_service context_bp = Blueprint("context", __name__, url_prefix="/api/context") @context_bp.route("/urls", methods=["GET"]) @login_required def list_urls(): urls = UrlContext.query.filter_by(user_id=current_user.id).order_by(UrlContext.created_at.desc()).all() return jsonify([u.to_dict() for u in urls]) @context_bp.route("/urls", methods=["POST"]) @login_required def add_url(): data = request.get_json(silent=True) or {} url = (data.get("url") or "").strip() if not url: return jsonify({"error": "No URL provided"}), 400 if not url.startswith(("http://", "https://")): return jsonify({"error": "Invalid URL. Must start with http:// or https://"}), 400 # Check for duplicate per user existing = UrlContext.query.filter_by(user_id=current_user.id, url=url).first() if existing: return jsonify({"error": "URL already added"}), 409 url_ctx = UrlContext(user_id=current_user.id, url=url, indexed=False) db.session.add(url_ctx) db.session.commit() try: title, text = scrape_url(url) url_ctx.title = title[:500] rag_service.index_source( text=text, user_id=current_user.id, source_id=url_ctx.id, source_type="url", chunk_size=current_app.config["RAG_CHUNK_SIZE"], chunk_overlap=current_app.config["RAG_CHUNK_OVERLAP"], ) url_ctx.indexed = True db.session.commit() except Exception as e: current_app.logger.error(f"Scraping/indexing failed for url {url_ctx.id}: {e}") return jsonify(url_ctx.to_dict()), 201 @context_bp.route("/urls/", methods=["DELETE"]) @login_required def delete_url(url_id): url_ctx = UrlContext.query.filter_by(id=url_id, user_id=current_user.id).first_or_404() rag_service.delete_source(current_user.id, url_ctx.id, "url") db.session.delete(url_ctx) db.session.commit() return jsonify({"success": True})