diff options
| -rw-r--r-- | app.py | 86 | ||||
| -rw-r--r-- | static/style/mgmt.css | 37 | ||||
| -rw-r--r-- | templates/index.html | 1 | ||||
| -rw-r--r-- | templates/login.html | 4 | ||||
| -rw-r--r-- | templates/mgmt.html | 39 |
5 files changed, 153 insertions, 14 deletions
@@ -3,6 +3,7 @@ from hashlib import scrypt from os import urandom from hmac import compare_digest import sqlite3 +from colorsys import rgb_to_hsv from flask import ( Flask, @@ -14,7 +15,8 @@ from flask import ( g, flash, ) -from werkzeug.exceptions import HTTPException, NotImplemented +from werkzeug.exceptions import HTTPException, NotImplemented, BadRequest +import requests from captcha import Captcha from presets import GUEST_CAPTCHA, GUIDE_CAPTCHAS @@ -123,6 +125,19 @@ def index(): return render_template("index.html", news=results) +@app.route("/captcha") +def captcha(): + size = request.args.get("size", "") + label = request.args.get("label", "") + lock = request.args.get("lock", "") + answer = request.args.get("answer", "") + captcha = Captcha.safe_validate(size, label, lock, answer) + if captcha: + add_captcha(captcha.id) + return {"valid": True}, 200 + return {"valid": False}, 400 + + @app.route("/login", methods=["GET", "POST"]) def login(): db = get_db() @@ -206,17 +221,64 @@ def news(): return render_template("news.html", news=results) -@app.route("/captcha") -def captcha(): - size = request.args.get("size", "") - label = request.args.get("label", "") - lock = request.args.get("lock", "") - answer = request.args.get("answer", "") - captcha = Captcha.safe_validate(size, label, lock, answer) - if captcha: - add_captcha(captcha.id) - return {"valid": True}, 200 - return {"valid": False}, 400 +@app.route("/mgmt", methods=["GET", "POST"]) +def management(): + if request.method == "POST": + try: + lid_key = request.form.get("lid", "custom") + if lid_key == "custom": + lid = int(request.form.get("custom", "5")) + else: + lid = int(lid_key) + except ValueError: + raise BadRequest + set_key = request.form.get("set") + match set_key: + case "off": + tool_disable_light(lid) + case "on": + tool_enable_light(lid) + case "color": + tool_color_light(lid, request.form.get("color", "#FF00AA")) + case _: + raise BadRequest + return render_template("mgmt.html") + + +def tool_disable_light(light: int): + requests.put( + f"{LIGHT_URL}/lights/{light}/state", + json={"on": False}, + timeout=5, + ) + + +def tool_enable_light(light: int): + requests.put( + f"{LIGHT_URL}/lights/{light}/state", + json={"on": True, "ct": 366}, + timeout=5, + ) + + +def tool_color_light(light: int, color: str): + if color[0] == "#": + color = color[1:] + color = color.upper() + if len(color) != 6 or not all(c in HEX_CHARS for c in color): + color = "FF00AA" + rgb = [int(color[i : i + 2], 16) / 255 for i in range(0, 6, 2)] + hsv = rgb_to_hsv(*rgb) + requests.put( + f"{LIGHT_URL}/lights/{light}/state", + json={ + "on": True, + "hue": int(hsv[0] * 65535), + "sat": int(hsv[1] * 254), + "bri": int(hsv[2] * 254), + }, + timeout=5, + ) @app.route("/permits") diff --git a/static/style/mgmt.css b/static/style/mgmt.css new file mode 100644 index 0000000..9ec93ef --- /dev/null +++ b/static/style/mgmt.css @@ -0,0 +1,37 @@ +h3 { + display: inline; + font-size: inherit; +} + +form { + display: grid; + grid-template-columns: auto 1fr; + gap: 0.5em; + margin: 0.5em; +} + +label[for="light"], +label[for="color"], +input[type="radio"] { + align-content: center; + justify-self: end; +} + +input[type="color"] { + padding: 0; + height: 2em; +} + +button { + grid-column: 1 / span 2; + border: 1px solid black; +} + +hr { + grid-column: 1 / span 2; + width: 100%; +} + +input { + border: 1px solid black; +}
\ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 8126ae1..ad884cf 100644 --- a/templates/index.html +++ b/templates/index.html @@ -24,6 +24,7 @@ <nav> {% if session.username %} <a href="/logout">Log Off</a> + <a href="/mgmt">Hotel Management</a> {% else %} <a href="/login">Resident Portal</a> <a href="/guest">Guest Access</a> diff --git a/templates/login.html b/templates/login.html index f0b450e..ea9748e 100644 --- a/templates/login.html +++ b/templates/login.html @@ -9,9 +9,9 @@ <h2>D.S. Resident Login</h2> <form method="post"> <label for="username">Username: </label> - <input type="text" name="username" autocomplete="username"> + <input type="text" name="username" id="username" autocomplete="username" /> <label for="password">Password: </label> - <input type="password" name="password" autocomplete="current-password"> + <input type="password" name="password" id="password" autocomplete="current-password" /> <button type="submit">Log In</button> <input type="hidden" name="register" value="0"> </form> diff --git a/templates/mgmt.html b/templates/mgmt.html new file mode 100644 index 0000000..e07cc11 --- /dev/null +++ b/templates/mgmt.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block head %} +<link rel="stylesheet" href="{{ url_for('static', filename='style/mgmt.css') }}"> +{% endblock %} + +{% block content %} +<main class="centered"> + <h2>Hotel Management</h2> + <details name="mgmt" open> + <summary> + <h3>Lighting Controls</h3> + </summary> + <form method="post" name="lighting"> + <input type="hidden" name="action" value="lighting" /> + <input type="radio" id="lid_5" name="lid" value="5" checked /> + <label for="lid_5">Target Primary Light</label> + <input type="radio" id="lid_19" name="lid" value="19" /> + <label for="lid_19">Target Auxiliary Light</label> + <input type="radio" id="lid_20" name="lid" value="20" /> + <label for="lid_20">Target Alex's Light</label> + <input type="radio" id="lid_custom" name="lid" value="custom" /> + <label for="lid_custom">Target Custom Light</label> + <label for="custom">LID: </label> + <input type="number" id="custom" name="custom" value="5" /> + <hr> + <input type="radio" id="set_off" name="set" value="off" checked /> + <label for="set_off">Set Lights to Off</label> + <input type="radio" id="set_on" name="set" value="on" /> + <label for="set_on">Set Lights to Normal</label> + <input type="radio" id="set_color" name="set" value="color" /> + <label for="set_color">Set Lights to Color</label> + <label for="color">Color: </label> + <input type="color" id="color" name="color" value="#FF00AA" /> + <button type="submit">Apply Effects</button> + </form> + </details> +</main> +{% endblock %}
\ No newline at end of file |