import json from flask import Blueprint, Response, jsonify, request from sqlalchemy import delete, func, select from l4d2web.auth import current_user, require_login from l4d2web.db import session_scope from l4d2web.models import Blueprint as BlueprintModel from l4d2web.models import BlueprintOverlay, Server bp = Blueprint("blueprint", __name__) @bp.post("/blueprints") @require_login def create_blueprint() -> Response: payload = request.get_json(silent=True) or {} user = current_user() assert user is not None name = str(payload.get("name", "")).strip() if not name: return Response("name is required", status=400) with session_scope() as db: blueprint = BlueprintModel( user_id=user.id, name=name, arguments=json.dumps(payload.get("arguments", [])), config=json.dumps(payload.get("config", [])), ) db.add(blueprint) db.flush() for position, overlay_id in enumerate(payload.get("overlay_ids", [])): db.add( BlueprintOverlay( blueprint_id=blueprint.id, overlay_id=int(overlay_id), position=position, ) ) blueprint_id = blueprint.id return jsonify({"id": blueprint_id}), 201 @bp.delete("/blueprints/") @require_login def delete_blueprint(blueprint_id: int) -> Response: user = current_user() assert user is not None with session_scope() as db: blueprint = db.scalar( select(BlueprintModel).where( BlueprintModel.id == blueprint_id, BlueprintModel.user_id == user.id, ) ) if blueprint is None: return Response(status=404) linked_count = db.scalar( select(func.count(Server.id)).where(Server.blueprint_id == blueprint.id) ) or 0 if linked_count > 0: return Response("blueprint is in use", status=409) db.execute(delete(BlueprintOverlay).where(BlueprintOverlay.blueprint_id == blueprint.id)) db.delete(blueprint) return Response(status=204)