"""BFA Banana Dryer — HMI Design Collaboration Tool""" import os import json import time import uuid from flask import Flask, render_template, request, jsonify, redirect, make_response app = Flask(__name__) LAYOUT_DIR = os.path.join(os.path.dirname(__file__), "layouts") PHOTO_DIR = os.path.join(os.path.dirname(__file__), "static", "photos") os.makedirs(LAYOUT_DIR, exist_ok=True) os.makedirs(PHOTO_DIR, exist_ok=True) CURRENT_LAYOUT = os.path.join(LAYOUT_DIR, "current.json") def get_layout(): # V2: GrapesJS project JSON stored in current_v2.json v2_path = os.path.join(LAYOUT_DIR, "current_v2.json") if os.path.exists(v2_path): with open(v2_path) as f: return json.load(f) # No V2 layout yet — return empty so GrapesJS starts fresh return {} def get_v1_layout(): """Legacy V1 layout for reference""" if os.path.exists(CURRENT_LAYOUT): with open(CURRENT_LAYOUT) as f: return json.load(f) return {} def save_layout(layout): # V2: save GrapesJS project data v2_path = os.path.join(LAYOUT_DIR, "current_v2.json") with open(v2_path, "w") as f: json.dump(layout, f, indent=2) def save_v1_layout(layout): """Legacy V1 save""" with open(CURRENT_LAYOUT, "w") as f: json.dump(layout, f, indent=2) def get_user(): return request.cookies.get("bfa_user", "") @app.route("/") def index(): if not get_user(): return redirect("login") return render_template("editor.html", user=get_user()) @app.route("/login", methods=["GET", "POST"]) def login(): layout = get_layout() users = layout.get("users", ["Richard", "Rob", "Guido"]) if request.method == "POST": name = request.form.get("user", "").strip() if name: resp = make_response(redirect("./")) resp.set_cookie("bfa_user", name, max_age=86400*30) # Add user to layout if new if name not in users: layout.setdefault("users", []).append(name) save_layout(layout) return resp return render_template("login.html", users=users) @app.route("/logout") def logout(): resp = make_response(redirect("login")) resp.delete_cookie("bfa_user") return resp @app.route("/api/layout", methods=["GET"]) def api_get_layout(): return jsonify(get_layout()) @app.route("/api/layout", methods=["POST"]) def api_save_layout(): layout = request.json save_layout(layout) return jsonify({"ok": True}) @app.route("/api/comment", methods=["POST"]) def api_add_comment(): data = request.json layout = get_layout() comment = { "id": str(uuid.uuid4())[:8], "target": data["target"], "user": data.get("user", get_user()), "time": time.strftime("%Y-%m-%dT%H:%M:%S"), "text": data["text"] } layout.setdefault("comments", []).append(comment) save_layout(layout) return jsonify(comment) @app.route("/api/users", methods=["POST"]) def api_add_user(): name = request.json.get("name", "").strip() if not name: return jsonify({"error": "empty name"}), 400 layout = get_layout() if name not in layout.get("users", []): layout.setdefault("users", []).append(name) save_layout(layout) return jsonify({"ok": True, "users": layout["users"]}) @app.route("/api/photo", methods=["POST"]) def api_upload_photo(): if "file" not in request.files: return jsonify({"error": "no file"}), 400 f = request.files["file"] fname = f"{int(time.time())}_{f.filename}" f.save(os.path.join(PHOTO_DIR, fname)) return jsonify({"filename": fname, "url": f"static/photos/{fname}"}) @app.route("/api/photos", methods=["GET"]) def api_list_photos(): photos = sorted(os.listdir(PHOTO_DIR)) if os.path.exists(PHOTO_DIR) else [] return jsonify([{"filename": p, "url": f"static/photos/{p}"} for p in photos if not p.startswith(".")]) if __name__ == "__main__": app.run(host="0.0.0.0", port=5001, debug=True)