mirror of
https://github.com/hoshikawa2/rfp_response_automation.git
synced 2026-03-03 16:09:35 +00:00
110 lines
2.8 KiB
Python
110 lines
2.8 KiB
Python
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/<job_id>/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/<job_id>")
|
|
@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/<job_id>/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/<job_id>")
|
|
@requires_app_auth
|
|
def job_page(job_id):
|
|
return render_template("excel/job_status.html", job_id=job_id) |