summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.py86
-rw-r--r--static/style/mgmt.css37
-rw-r--r--templates/index.html1
-rw-r--r--templates/login.html4
-rw-r--r--templates/mgmt.html39
5 files changed, 153 insertions, 14 deletions
diff --git a/app.py b/app.py
index 484656c..4bd5d3f 100644
--- a/app.py
+++ b/app.py
@@ -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