Skip to content
Snippets Groups Projects
Commit e9f612fe authored by David Huss's avatar David Huss :speech_balloon:
Browse files

Refactor, add more leaderboards (incl. Duration)

parent ffd00922
Branches
No related tags found
No related merge requests found
No preview for this file type
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import os import os
import hashlib import hashlib
from datetime import datetime, timedelta
import requests import requests
import appdirs import appdirs
from xml.etree import cElementTree as ElementTree from xml.etree import cElementTree as ElementTree
...@@ -10,13 +11,21 @@ from typing import NewType, Optional, Tuple, Iterable ...@@ -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" SERVER_PROPERTIES_FILE = "/usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties"
# Type definitions
Secret = NewType('Secret', str) Secret = NewType('Secret', str)
Url = NewType('Url', 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): class XmlListConfig(list):
...@@ -116,7 +125,11 @@ def request_meetings(secret: Secret, bbb_url: Url) -> XmlDictConfig: ...@@ -116,7 +125,11 @@ def request_meetings(secret: Secret, bbb_url: Url) -> XmlDictConfig:
exit() exit()
return xmldict return xmldict
def get_meetings(secret: Secret, bbb_url: Url) -> Iterable[XmlDictConfig]: def get_meetings(secret: Secret, bbb_url: Url) -> Iterable[XmlDictConfig]:
"""
Request meetings and return a list of them. Sorted by biggest first
"""
meetings = [] meetings = []
d = request_meetings(secret, bbb_url) d = request_meetings(secret, bbb_url)
...@@ -143,6 +156,32 @@ def get_presenter(meeting: XmlDictConfig) -> Optional[XmlDictConfig]: ...@@ -143,6 +156,32 @@ def get_presenter(meeting: XmlDictConfig) -> Optional[XmlDictConfig]:
return None 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: def get_formated_presenter_name(meeting: XmlDictConfig) -> str:
""" """
...@@ -150,42 +189,51 @@ def get_formated_presenter_name(meeting: XmlDictConfig) -> str: ...@@ -150,42 +189,51 @@ def get_formated_presenter_name(meeting: XmlDictConfig) -> str:
""" """
presenter = get_presenter(meeting) presenter = get_presenter(meeting)
if presenter is not None: if presenter is not None:
return "{} ({})".format(presenter["fullName"], presenter["userID"]) return "{:<30} ({})".format(presenter["fullName"], presenter["userID"])
else: else:
return "no Presenter" 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): 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 len(meetings) == 0:
if type(d["meetings"]["meeting"]) is XmlListConfig: print("There are no meetings running now.")
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.")
exit() 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("MEETINGS on {}:".format(bbb_url))
print(" ├─── {:>4} running".format(n_running)) print(" ├─── {:>4} running".format(n_running))
print(" └─── {:>4} recording".format(n_recording)) print(" └─── {:>4} recording".format(n_recording))
...@@ -198,12 +246,13 @@ def print_overview(secret: Secret, bbb_url: Url): ...@@ -198,12 +246,13 @@ def print_overview(secret: Secret, bbb_url: Url):
print(" └─ {:>4} moderators".format(n_moderator)) print(" └─ {:>4} moderators".format(n_moderator))
print() 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()
print("LEADERBOARD (Participants)") print_duration_leaderboard(meetings)
for m in rooms_by_size:
print("{:>5} {:<45} {}".format(m["participantCount"], m["meetingName"], get_formated_presenter_name(m)))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment