import json from flask import Blueprint, Response, current_app, render_template from sqlalchemy import select from l4d2web.auth import current_user, require_admin, require_login from l4d2web.db import session_scope from l4d2web.models import Blueprint as BlueprintModel from l4d2web.models import BlueprintOverlay, Job, Overlay, Server bp = Blueprint("pages", __name__) @bp.get("/dashboard") @require_login def dashboard() -> str: return render_template("dashboard.html") @bp.get("/servers") @require_login def servers_page() -> str: user = current_user() assert user is not None with session_scope() as db: rows = db.execute( select(Server, BlueprintModel) .join(BlueprintModel, BlueprintModel.id == Server.blueprint_id) .where(Server.user_id == user.id) .order_by(Server.name) ).all() return render_template("servers.html", rows=rows) @bp.get("/servers/") @require_login def server_detail(server_id: int): user = current_user() assert user is not None with session_scope() as db: server = db.scalar(select(Server).where(Server.id == server_id, Server.user_id == user.id)) if server is None: return Response(status=404) blueprint = db.scalar(select(BlueprintModel).where(BlueprintModel.id == server.blueprint_id)) overlay_rows = db.execute( select(Overlay.name) .join(BlueprintOverlay, BlueprintOverlay.overlay_id == Overlay.id) .where(BlueprintOverlay.blueprint_id == server.blueprint_id) .order_by(BlueprintOverlay.position) ).all() latest_job = db.scalar( select(Job) .where(Job.server_id == server.id) .order_by(Job.created_at.desc()) .limit(1) ) return render_template( "server_detail.html", server=server, blueprint=blueprint, overlay_names=[row[0] for row in overlay_rows], arguments=json.loads(blueprint.arguments) if blueprint is not None else [], config_lines=json.loads(blueprint.config) if blueprint is not None else [], latest_job=latest_job, ) @bp.get("/overlays") @require_login def overlays() -> str: with session_scope() as db: overlays = db.scalars(select(Overlay).order_by(Overlay.name)).all() return render_template("overlays.html", overlays=overlays) @bp.get("/blueprints/") @require_login def blueprint_page(blueprint_id: int): user = current_user() assert user is not None with session_scope() as db: blueprint = db.scalar(select(BlueprintModel).where(BlueprintModel.id == blueprint_id)) if blueprint is None: return Response(status=404) if blueprint.user_id != user.id: return Response(status=403) overlay_rows = db.execute( select(Overlay.name) .join(BlueprintOverlay, BlueprintOverlay.overlay_id == Overlay.id) .where(BlueprintOverlay.blueprint_id == blueprint.id) .order_by(BlueprintOverlay.position) ).all() return render_template( "blueprints.html", blueprint=blueprint, overlay_names=[row[0] for row in overlay_rows], arguments=json.loads(blueprint.arguments), config_lines=json.loads(blueprint.config), )