Commit e9f612fe authored by David Huss's avatar David Huss 💬
Browse files

Refactor, add more leaderboards (incl. Duration)

parent ffd00922
......@@ -3,6 +3,7 @@
import os
import hashlib
from datetime import datetime, timedelta
import requests
import appdirs
from xml.etree import cElementTree as ElementTree
......@@ -10,13 +11,21 @@ from typing import NewType, Optional, Tuple, Iterable
# Default path
SERVER_PROPERTIES_FILE = "/usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties"
# Type definitions
Secret = NewType('Secret', str)
Url = NewType('Url', str)
FRIENDLY_KEYNAMES = {
"participantCount": "Participants",
"listenerCount": "only listening",
"voiceParticipantCount": "Mics on",
"videoCount": "Webcams on",
"moderatorCount": "Number of Moderators"
}
class XmlListConfig(list):
......@@ -116,7 +125,11 @@ def request_meetings(secret: Secret, bbb_url: Url) -> XmlDictConfig:
exit()
return xmldict
def get_meetings(secret: Secret, bbb_url: Url) -> Iterable[XmlDictConfig]:
"""
Request meetings and return a list of them. Sorted by biggest first
"""
meetings = []
d = request_meetings(secret, bbb_url)
......@@ -143,6 +156,32 @@ def get_presenter(meeting: XmlDictConfig) -> Optional[XmlDictConfig]:
return None
def get_duration(meeting: XmlDictConfig) -> timedelta:
"""
Return the duration of a meeting
"""
timestamp = int(meeting["startTime"][:-3])
start_time = datetime.fromtimestamp(timestamp)
duration = datetime.now() - start_time
return duration
def strfdelta(duration: timedelta, fmt: str) -> str:
"""
Helper function for datetime.timedelta formatting, use like this:
strfdelta(delta_obj, "{days} days {hours}:{minutes}:{seconds}")
"""
d = {"days": duration.days}
d["hours"], remainder = divmod(duration.seconds, 3600)
d["minutes"], d["seconds"] = divmod(remainder, 60)
return fmt.format(**d)
def format_duration(meeting: XmlDictConfig) -> str:
duration = get_duration(meeting)
return strfdelta(duration, "{hours}:{minutes}")
def get_formated_presenter_name(meeting: XmlDictConfig) -> str:
"""
......@@ -150,42 +189,51 @@ def get_formated_presenter_name(meeting: XmlDictConfig) -> str:
"""
presenter = get_presenter(meeting)
if presenter is not None:
return "{} ({})".format(presenter["fullName"], presenter["userID"])
return "{:<30} ({})".format(presenter["fullName"], presenter["userID"])
else:
return "no Presenter"
def print_leaderboard(meetings: Iterable[XmlDictConfig], key: str):
"""
Print a leaderboard of all meetings sorted by a given key (e.g.
participantCount)
"""
print("LEADERBOARD ({})".format(FRIENDLY_KEYNAMES[key]))
for m in meetings:
print("{:>5} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name(m)))
def print_duration_leaderboard(meetings: Iterable[XmlDictConfig]):
"""
Print a leaderboard of all meetings sorted by a given key (e.g.
participantCount)
"""
print("LEADERBOARD (Duration)")
by_duration = sorted([m for m in meetings], key=lambda x:int(get_duration(x).total_seconds()), reverse=True)
for m in by_duration:
print("{:>5} {:<45} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name(m)))
def print_overview(secret: Secret, bbb_url: Url):
d = request_meetings(secret, bbb_url)
"""
Get the meetings and print out an overview of the current bbb-usage
"""
meetings = get_meetings(secret, bbb_url)
# If there is more than one meeting the type is XmlListConfig otherwise XmlDictConfig
if type(d["meetings"]["meeting"]) is XmlListConfig:
n_running = len([m for m in d["meetings"]["meeting"] if m["running"] == "true"])
n_recording = len([m for m in d["meetings"]["meeting"] if m["recording"] == "true"])
n_participants = sum([int(m["participantCount"]) for m in d["meetings"]["meeting"] if m["running"] == "true"])
n_listeners = sum([int(m["listenerCount"]) for m in d["meetings"]["meeting"] if m["running"] == "true"])
n_voice = sum([int(m["voiceParticipantCount"]) for m in d["meetings"]["meeting"] if m["running"] == "true"])
n_video = sum([int(m["videoCount"]) for m in d["meetings"]["meeting"] if m["running"] == "true"])
n_moderator = sum([int(m["moderatorCount"]) for m in d["meetings"]["meeting"] if m["running"] == "true"])
biggest_room = max([m for m in d["meetings"]["meeting"] if m["running"] == "true"], key=lambda x:int(x['participantCount']))
rooms_by_size = sorted([m for m in d["meetings"]["meeting"] if m["running"] == "true"], key=lambda x:int(x['participantCount']), reverse=True)
elif type(d["meetings"]["meeting"]) is XmlDictConfig:
m = d["meetings"]["meeting"][0]
n_running = 1
if m["recording"] == "true":
n_recording = 1
else:
n_recording = 0
n_participants = int(m["participantCount"])
n_listeners = int(m["listenerCount"])
n_voice = int(m["voiceParticipantCount"])
n_video = int(m["videoCount"])
n_moderator = int(m["moderatorCount"])
biggest_room = m
else:
print("It appears there are no rooms running.")
if len(meetings) == 0:
print("There are no meetings running now.")
exit()
n_running = len(meetings)
n_recording = len([m for m in meetings if m["recording"] == "true"])
n_participants = sum([int(m["participantCount"]) for m in meetings])
n_listeners = sum([int(m["listenerCount"]) for m in meetings])
n_voice = sum([int(m["voiceParticipantCount"]) for m in meetings])
n_video = sum([int(m["videoCount"]) for m in meetings])
n_moderator = sum([int(m["moderatorCount"]) for m in meetings])
print("MEETINGS on {}:".format(bbb_url))
print(" ├─── {:>4} running".format(n_running))
print(" └─── {:>4} recording".format(n_recording))
......@@ -198,12 +246,13 @@ def print_overview(secret: Secret, bbb_url: Url):
print(" └─ {:>4} moderators".format(n_moderator))
print()
print("Most participants ({}): {}, Presenter: {}".format(biggest_room["participantCount"], biggest_room["meetingName"], get_formated_presenter_name(biggest_room)))
print_leaderboard(meetings, "participantCount")
print()
print_leaderboard(meetings, "videoCount")
print()
print_leaderboard(meetings, "voiceParticipantCount")
print()
print("LEADERBOARD (Participants)")
for m in rooms_by_size:
print("{:>5} {:<45} {}".format(m["participantCount"], m["meetingName"], get_formated_presenter_name(m)))
print_duration_leaderboard(meetings)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment