Browse Source

Adding the channel grouping functionality

Kirk Trombley 5 years ago
parent
commit
e2e62c78dc
1 changed files with 52 additions and 25 deletions
  1. 52 25
      app.py

+ 52 - 25
app.py

@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 
 from telnetlib import Telnet
+from collections import defaultdict
 
 import toml
 from flask import Flask, jsonify, render_template_string
@@ -8,6 +9,16 @@ from flask import Flask, jsonify, render_template_string
 app = Flask(__name__)
 
 
+def parse_ts_response(response):
+    # entries separated by |'s
+    entries = response.split("|")
+    # entries contain key=value pairs separated by spaces
+    pairs = [[pr.split("=", 1) for pr in ent.split()] for ent in entries]
+    # rearrange these into maps for convenience
+    return [{k: v for k, v in pr} for pr in pairs]
+
+
+
 def get_users():
     with open("secret.toml") as infile:
         cfg = toml.load(infile)
@@ -16,42 +27,48 @@ def get_users():
 
     with Telnet(cfg["host"], cfg["port"], 5) as tn:
         print("connection")
-        print(tn.read_until(b"\n").decode("ascii"))
-        print(tn.read_until(b"\n").decode("ascii"))
+        print(tn.read_until(b"\n").decode("utf-8"))
+        print(tn.read_until(b"\n").decode("utf-8"))
         print("----")
 
         tn.write(login)
         print("after login")
-        print(tn.read_until(b"\n").decode("ascii"))
+        print(tn.read_until(b"\n").decode("utf-8"))
         print("----")
 
         tn.write(b"use 1 -virtual\n")
         print("after use")
-        print(tn.read_until(b"\n").decode("ascii"))
+        print(tn.read_until(b"\n").decode("utf-8"))
         print("----")
 
+        tn.write(b"channellist\n")
+        response = tn.read_until(b"\n").decode("utf-8")
+        print("after channellist")
+        print(response)
+        print(tn.read_until(b"\n").decode("utf-8"))
+        print("----")
+
+        channel_maps = parse_ts_response(response)
+        # rearrange the maps into one large channel lookup map
+        channels = {info["cid"]: info["channel_name"].replace(r"\s", " ") for info in channel_maps}
+
         tn.write(b"clientlist\n")
-        response = tn.read_until(b"\n").decode("ascii")
+        response = tn.read_until(b"\n").decode("utf-8")
         print("after clientlist")
         print(response)
-        print(tn.read_until(b"\n").decode("ascii"))
+        print(tn.read_until(b"\n").decode("utf-8"))
         print("----")
 
-        # entries separated by |'s
-        entries = response.split("|")
-        # entries contain key=value pairs separated by spaces
-        pairs = [[pr.split("=", 1) for pr in ent.split()] for ent in entries]
-        # rearrange these into maps for convenience
-        entry_maps = [{k: v for k, v in pr} for pr in pairs]
+        entry_maps = parse_ts_response(response)
         # combine the maps into one large map, ignoring serveradmin query user
         client_info = {info["client_nickname"]: info for info in entry_maps if "serveradmin" not in info["client_nickname"]}
 
         for k, v in client_info.items():
             tn.write(f"clientinfo clid={v['clid']}\n".encode("utf-8"))
-            response = tn.read_until(b"\n").decode("ascii")
+            response = tn.read_until(b"\n").decode("utf-8")
             print(f"after clientinfo for {k}")
             print(response)
-            print(tn.read_until(b"\n").decode("ascii"))
+            print(tn.read_until(b"\n").decode("utf-8"))
             print("----")
 
             # info is key=value pairs separated by spaces
@@ -61,10 +78,11 @@ def get_users():
 
         tn.write(b"quit\n")
         print("after quit")
-        print(tn.read_until(b"\n").decode("ascii"))
+        print(tn.read_until(b"\n").decode("utf-8"))
 
 
     users = []
+    channel_users = defaultdict(list)
     for name, info in client_info.items():
         user_text = name
         audio_status = []
@@ -75,13 +93,14 @@ def get_users():
         if len(audio_status) > 0:
             user_text += f" ({', '.join(audio_status)})"
         users.append(user_text)
+        channel_users[channels[info["cid"]]].append(user_text)
 
-    return users
+    return sorted(users), {k: sorted(v) for k, v in channel_users.items()}
 
 
 @app.route("/")
 def get_status():
-    return jsonify({"users": get_users()})
+    return jsonify({"users": get_users()[0]})
 
 
 @app.route("/page")
@@ -106,6 +125,13 @@ def get_status_page():
             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;
@@ -157,19 +183,20 @@ def get_status_page():
                     <h1>TeamSpeak Server Status</h1>
                     {% if users|length == 0 %}
                     No one in teamspeak!
-                    {% elif users|length == 1 %}
-                    Only {{ users[0] }}
                     {% else %}
-                    <ul>
-                    {% for user in users %}
-                        <li>{{ user }}</li>
-                    {% endfor %}
-                    </ul>
+                        {% 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=sorted(get_users()))
+    """, users=get_users()[1])
 
 
 if __name__ == "__main__":