|
@@ -5,9 +5,10 @@ from collections import defaultdict
|
|
|
from datetime import timedelta
|
|
|
|
|
|
import toml
|
|
|
-from flask import Flask, jsonify, render_template_string
|
|
|
+from flask import Flask, jsonify, render_template
|
|
|
|
|
|
IDLE_TIMEOUT = timedelta(minutes=5)
|
|
|
+REFRESH_RATE = 60 # seconds
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
@@ -21,14 +22,10 @@ def parse_ts_response(response):
|
|
|
return [{k: v for k, v in pr} for pr in pairs]
|
|
|
|
|
|
|
|
|
+def query_ts(host, port, username, password):
|
|
|
+ login = f"login {username} {password}\n".encode("utf-8")
|
|
|
|
|
|
-def get_users():
|
|
|
- with open("secret.toml") as infile:
|
|
|
- cfg = toml.load(infile)
|
|
|
-
|
|
|
- login = ("login %s %s\n" % (cfg["user"], cfg["pass"])).encode("utf-8")
|
|
|
-
|
|
|
- with Telnet(cfg["host"], cfg["port"], 5) as tn:
|
|
|
+ with Telnet(host, port, 5) as tn:
|
|
|
print("connection")
|
|
|
print(tn.read_until(b"\n").decode("utf-8"))
|
|
|
print(tn.read_until(b"\n").decode("utf-8"))
|
|
@@ -83,6 +80,14 @@ def get_users():
|
|
|
print("after quit")
|
|
|
print(tn.read_until(b"\n").decode("utf-8"))
|
|
|
|
|
|
+ return client_info, channels
|
|
|
+
|
|
|
+
|
|
|
+def get_users():
|
|
|
+ with open("secret.toml") as infile:
|
|
|
+ cfg = toml.load(infile)
|
|
|
+
|
|
|
+ client_info, channels = query_ts(cfg["host"], cfg["port"], cfg["user"], cfg["pass"])
|
|
|
|
|
|
users = []
|
|
|
channel_users = defaultdict(list)
|
|
@@ -113,98 +118,12 @@ def get_status():
|
|
|
|
|
|
@app.route("/page")
|
|
|
def get_status_page():
|
|
|
- # JS adapted from
|
|
|
- # https://stackoverflow.com/questions/6152522/how-can-i-make-a-paragraph-bounce-around-in-a-div
|
|
|
- return render_template_string("""
|
|
|
- <!doctype html>
|
|
|
- <title>Teamspeak Server Status</title>
|
|
|
- <style>
|
|
|
- body {
|
|
|
- margin: 0px 0px 0px 0px;
|
|
|
- padding: 0px 0px 0px 0px;
|
|
|
- font-family: verdana, arial, helvetica, sans-serif;
|
|
|
- color: #ccc;
|
|
|
- background-color: #333;
|
|
|
- }
|
|
|
- h1 {
|
|
|
- font-size: 24px;
|
|
|
- line-height: 44px;
|
|
|
- font-weight: bold;
|
|
|
- margin-top: 0;
|
|
|
- margin-bottom: 0;
|
|
|
- }
|
|
|
- h2 {
|
|
|
- font-size: 18px;
|
|
|
- line-height: 20px;
|
|
|
- margin-top: 0;
|
|
|
- margin-left: 15px;
|
|
|
- margin-bottom: -10px;
|
|
|
- }
|
|
|
- #bounceBox {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- left: 0;
|
|
|
- }
|
|
|
- #bouncer {
|
|
|
- position: absolute;
|
|
|
- }
|
|
|
- </style>
|
|
|
- <script>
|
|
|
- let vx = 3;
|
|
|
- let vy = 2;
|
|
|
- const buffer = 5;
|
|
|
-
|
|
|
- const hitLR = (el, bounding) => {
|
|
|
- if (el.offsetLeft <= buffer && vx < 0) {
|
|
|
- vx = -1 * vx;
|
|
|
- }
|
|
|
- if ((el.offsetLeft + el.offsetWidth) >= (bounding.offsetWidth - buffer)) {
|
|
|
- vx = -1 * vx;
|
|
|
- }
|
|
|
- if (el.offsetTop <= buffer && vy < 0) {
|
|
|
- vy = -1 * vy;
|
|
|
- }
|
|
|
- if ((el.offsetTop + el.offsetHeight) >= (bounding.offsetHeight - buffer)) {
|
|
|
- vy = -1 * vy;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const mover = (el, bounding) => {
|
|
|
- hitLR(el, bounding);
|
|
|
- el.style.left = el.offsetLeft + vx + 'px';
|
|
|
- el.style.top = el.offsetTop + vy + 'px';
|
|
|
- setTimeout(function() {
|
|
|
- mover(el, bounding);
|
|
|
- }, 30);
|
|
|
- }
|
|
|
-
|
|
|
- setTimeout(() => mover(
|
|
|
- document.getElementById("bouncer"),
|
|
|
- document.getElementById("bounceBox")
|
|
|
- ), 30);
|
|
|
- </script>
|
|
|
- <body>
|
|
|
- <div id="bounceBox">
|
|
|
- <div id="bouncer">
|
|
|
- <h1>TeamSpeak Server Status</h1>
|
|
|
- {% if users|length == 0 %}
|
|
|
- No one in teamspeak!
|
|
|
- {% else %}
|
|
|
- {% for channel, people in users.items() %}
|
|
|
- <h2>{{ channel }}</h2>
|
|
|
- <ul>
|
|
|
- {% for user in people %}
|
|
|
- <li>{{ user }}</li>
|
|
|
- {% endfor %}
|
|
|
- </ul>
|
|
|
- {% endfor %}
|
|
|
- {% endif %}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </body>
|
|
|
- """, users=get_users()[1])
|
|
|
+ return render_template("main_page.html")
|
|
|
+
|
|
|
+
|
|
|
+@app.route("/page_body")
|
|
|
+def get_page_body():
|
|
|
+ return render_template("embedded_body.html", users=get_users()[1], refresh_rate=REFRESH_RATE)
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|