from flask import Blueprint, request, jsonify, send_file, render_template from pathlib import Path import uuid import json from config_loader import load_config from modules.core.audit import audit_log from modules.core.security import get_current_user from modules.core.security import requires_app_auth from .service import start_excel_job from .store import EXCEL_JOBS, EXCEL_LOCK excel_bp = Blueprint("excel", __name__) config = load_config() API_BASE_URL = f"{config.app_base}:{config.service_port}" UPLOAD_FOLDER = Path("./uploads") UPLOAD_FOLDER.mkdir(exist_ok=True) ALLOWED_EXTENSIONS = {"xlsx"} API_URL = API_BASE_URL + "/chat" def allowed_file(filename): return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS # ========================= # Upload + start processing # ========================= @excel_bp.route("/upload/excel", methods=["POST"]) @requires_app_auth def upload_excel(): file = request.files.get("file") email = request.form.get("email") if not file or not email: return jsonify({"error": "file and email required"}), 400 if not allowed_file(file.filename): return jsonify({"error": "invalid file type"}), 400 job_id = str(uuid.uuid4()) audit_log("UPLOAD_EXCEL", f"job_id={job_id}") job_dir = UPLOAD_FOLDER / job_id job_dir.mkdir(parents=True, exist_ok=True) input_path = job_dir / "input.xlsx" file.save(input_path) with EXCEL_LOCK: EXCEL_JOBS[job_id] = {"status": "RUNNING"} user = get_current_user() start_excel_job( job_id=job_id, input_path=input_path, email=email, auth_user=None, auth_pass=None, api_url=API_URL ) return jsonify({"status": "STARTED", "job_id": job_id}) # ========================= # Status # ========================= @excel_bp.route("/job//status") @requires_app_auth def job_status(job_id): status_file = UPLOAD_FOLDER / job_id / "status.json" if not status_file.exists(): return jsonify({"status": "PROCESSING"}) return jsonify(json.loads(status_file.read_text())) # ========================= # Download result # ========================= @excel_bp.route("/download/") @requires_app_auth def download(job_id): result_file = UPLOAD_FOLDER / job_id / "result.xlsx" if not result_file.exists(): return jsonify({"error": "not ready"}), 404 return send_file( result_file, as_attachment=True, download_name=f"RFP_result_{job_id}.xlsx" ) @excel_bp.route("/job//logs", methods=["GET"]) @requires_app_auth def excel_logs(job_id): with EXCEL_LOCK: job = EXCEL_JOBS.get(job_id, {}) return jsonify({"logs": job.get("logs", [])}) @excel_bp.route("/excel/job/") @requires_app_auth def job_page(job_id): return render_template("excel/job_status.html", job_id=job_id)