From e6294777a0c9ac01f99307ecc79ef5f97f718e4d Mon Sep 17 00:00:00 2001 From: atoav <dh@atoav.com> Date: Thu, 30 Apr 2020 13:30:13 +0200 Subject: [PATCH] Add --compact mode and -n --- bbbmon/bbbmon.py | 15 +++++++-- bbbmon/meetings.py | 34 ++++++++++++++------ bbbmon/printing.py | 80 ++++++++++++++++++++++++++++++++++++---------- pyproject.toml | 2 +- 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/bbbmon/bbbmon.py b/bbbmon/bbbmon.py index 01b8125..4124292 100755 --- a/bbbmon/bbbmon.py +++ b/bbbmon/bbbmon.py @@ -57,16 +57,18 @@ def main(userconfig): @click.option('--userconfig', '-u', is_flag=True, help="Use user config even if on server") @click.option('--endpoint', '-e', multiple=True, help="Filter by one or more endpoints as named in the user configuration (e.g. [servername]). Order is respected.") @click.option('--watch', '-w', help="Run repeatedly with the given interval in seconds", type=click.IntRange(2, 2147483647, clamp=True)) +@click.option('-n', help="The number of meetings to show in the leaderboards (Default: 5)", type=int) @click.option('--leaderboards/--no-leaderboards', default=True, show_default=True, help="Hide or show the meeting leaderboards") @click.option('--participants/--no-participants', default=True, show_default=True, help="Hide or show the participants") @click.option('--meetings/--no-meetings', default=True, show_default=True, help="Hide or show the meetings") @click.option('--presenter/--no-presenter', default=True, show_default=True, help="Hide or show the presenters") @click.option('--presenter-id/--no-presenter-id', default=False, show_default=True, help="Hide or show the presenter IDs") @click.option('--short', '-s', is_flag=True, help="Print less") +@click.option('--compact', '-c', is_flag=True, help="Print compactly") @click.option('--twolines', '-2', is_flag=True, help="Print essentials on two lines") @click.option('--all', '-a', 'all_', is_flag=True, help="Print all") @click.option('--fancy/--no-fancy', default=True, show_default=True, help="Use fancy headers") -def meetings(ctx, userconfig, short, all_, twolines, leaderboards, participants, presenter, watch, presenter_id, meetings, endpoint, fancy): +def meetings(ctx, userconfig, short, compact, n, all_, twolines, leaderboards, participants, presenter, watch, presenter_id, meetings, endpoint, fancy): """View currently active meetings""" if short: leaderboards = False @@ -76,6 +78,13 @@ def meetings(ctx, userconfig, short, all_, twolines, leaderboards, participants, presenter = True presenter_id = True meetings = True + if n is None: + n = 99999 + if compact: + if n is None: + n = 1 + if n is None: + n = 5 config = init_config(userconfig) config.filter_endpoints(endpoint) @@ -84,13 +93,13 @@ def meetings(ctx, userconfig, short, all_, twolines, leaderboards, participants, if twolines: meetings_twolines(config, watch, fancy) else: - list_meetings(config, leaderboards, participants, presenter, presenter_id, meetings, watch, fancy) + list_meetings(config, leaderboards, n, participants, presenter, presenter_id, meetings, watch, fancy, compact) time.sleep(watch) else: if twolines: meetings_twolines(config, watch, fancy) else: - list_meetings(config, leaderboards, participants, presenter, presenter_id, meetings, watch, fancy) + list_meetings(config, leaderboards, n, participants, presenter, presenter_id, meetings, watch, fancy, compact) diff --git a/bbbmon/meetings.py b/bbbmon/meetings.py index 15feba8..53e5c16 100644 --- a/bbbmon/meetings.py +++ b/bbbmon/meetings.py @@ -104,7 +104,7 @@ def get_duration(meeting: XmlDictConfig) -> timedelta: return duration -def list_meetings(config: Config, leaderboards: bool, participants: bool, presenter: bool, presenter_id: bool, show_meetings: bool, watch: int, fancy: bool): +def list_meetings(config: Config, leaderboards: bool, n: int, participants: bool, presenter: bool, presenter_id: bool, show_meetings: bool, watch: int, fancy: bool, compact: bool): """ For each endpoint in the configuration get the active meetings and print out an overview of the current bbb-usage @@ -143,13 +143,13 @@ def list_meetings(config: Config, leaderboards: bool, participants: bool, presen n_video = sum([int(m["videoCount"]) for m in meeting]) n_moderator = sum([int(m["moderatorCount"]) for m in meeting]) - if show_meetings: + if show_meetings and not compact: printing.print_header(endpoint.name, "MEETINGS", fancy) print(" ├─── {:>4} running".format(n_running)) print(" └─── {:>4} recording".format(n_recording)) print() - if participants: + if participants and not compact: printing.print_header(endpoint.name, "PARTICIPANTS across all {} rooms".format(n_running), fancy) print(" └─┬─ {:>4} total".format(n_participants)) print(" ├─ {:>4} listening only".format(n_listeners)) @@ -157,15 +157,29 @@ def list_meetings(config: Config, leaderboards: bool, participants: bool, presen print(" ├─ {:>4} video on".format(n_video)) print(" └─ {:>4} moderators".format(n_moderator)) + if compact: + h1 = printing.format_header(endpoint.name, "MEETINGS", fancy) + h2 = printing.format_header("", "PARTICIPANTS across all {} rooms".format(n_running), fancy) + s1 =" ├─── {:>4} running ".format(n_running) + s2 =" └─── {:>4} recording".format(n_recording) + p1 =" └─┬─ {:>4} total".format(n_participants) + p2 =" ├─ {:>4} listening only".format(n_listeners) + p3 =" ├─ {:>4} mic on".format(n_voice) + p4 =" ├─ {:>4} video on".format(n_video) + p5 =" └─ {:>4} moderators".format(n_moderator) + print("{:<20} {}".format(h1.rstrip(), h2)) + print("{:<22} {}".format(s1, p1)) + print("{:<22} {}".format(s2, p2)) + print("{:<22} {}".format("", p3)) + print("{:<22} {}".format("", p4)) + print("{:<22} {}".format("", p5)) + if leaderboards: print() - printing.print_leaderboard(meeting, "participantCount", endpoint.name, presenter, presenter_id, fancy) - print() - printing.print_leaderboard(meeting, "videoCount", endpoint.name, presenter, presenter_id, fancy) - print() - printing.print_leaderboard(meeting, "voiceParticipantCount", endpoint.name, presenter, presenter_id, fancy) - print() - printing.print_duration_leaderboard(meeting, endpoint.name, presenter, presenter_id, fancy) + printing.print_leaderboard(meeting, n, "participantCount", endpoint.name, presenter, presenter_id, fancy) + printing.print_leaderboard(meeting, n, "videoCount", endpoint.name, presenter, presenter_id, fancy) + printing.print_leaderboard(meeting, n, "voiceParticipantCount", endpoint.name, presenter, presenter_id, fancy) + printing.print_duration_leaderboard(meeting, n, endpoint.name, presenter, presenter_id, fancy) diff --git a/bbbmon/printing.py b/bbbmon/printing.py index 208fc11..9457c33 100644 --- a/bbbmon/printing.py +++ b/bbbmon/printing.py @@ -61,43 +61,91 @@ def get_formated_presenter_name(meeting: XmlDictConfig) -> str: return "no Presenter" -def print_leaderboard(meetings: Iterable[XmlDictConfig], key: str, endpoint_name: str, presenter: bool, presenter_id: bool, fancy: bool): +def print_leaderboard(meetings: Iterable[XmlDictConfig], n: int, key: str, endpoint_name: str, presenter: bool, presenter_id: bool, fancy: bool): """ Print a leaderboard of all meetings sorted by a given key (e.g. participantCount) """ - print_header(endpoint_name, "LEADERBOARD ({})".format(FRIENDLY_KEYNAMES[key]), fancy) + if n==1: + prefix = "Most" + else: + prefix = "By" + # Stay on same line if n == 1 + print_header(endpoint_name, "{} {}".format(prefix, FRIENDLY_KEYNAMES[key]), fancy, n != 1) sorted_by = sorted([m for m in meetings], key=lambda x:int(x[key]), reverse=True) - for m in sorted_by: + more = len(sorted_by[:n]) != len(sorted_by) + if n != 1: + for m in sorted_by[:n]: + if presenter: + if presenter_id: + print("{:>5} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name_id(m))) + else: + print("{:>5} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name(m))) + else: + print("{:>5} {}".format(m[key], m["meetingName"])) + if more: + print(" {}".format("."*(len(sorted_by)-len(sorted_by[:n])))) + print() + else: + m = sorted_by[0] if presenter: if presenter_id: - print("{:>5} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name_id(m))) + print("{:>8} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name_id(m))) else: - print("{:>5} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name(m))) + print("{:>8} {:<45} {}".format(m[key], m["meetingName"], get_formated_presenter_name(m))) else: - print("{:>5} {}".format(m[key], m["meetingName"])) + print("{:>8} {}".format(m[key], m["meetingName"])) -def print_duration_leaderboard(meetings: Iterable[XmlDictConfig], endpoint_name: str, presenter: bool, presenter_id: bool, fancy: bool): +def print_duration_leaderboard(meetings: Iterable[XmlDictConfig], n: int, endpoint_name: str, presenter: bool, presenter_id: bool, fancy: bool): """ Print a leaderboard of all meetings sorted by a given key (e.g. participantCount) """ - print_header(endpoint_name, "LEADERBOARD (Duration)", fancy) + if n==1: + prefix = "Most" + else: + prefix = "By" + # Stay on same line if n == 1 + print_header(endpoint_name, "{} Duration".format(prefix, ), fancy, n != 1) by_duration = sorted([m for m in meetings], key=lambda x:int(bbbmon.meetings.get_duration(x).total_seconds()), reverse=True) - - for m in by_duration: + more = len(by_duration[:n]) != len(by_duration) + if n != 1: + for m in by_duration[:n]: + if presenter: + if presenter_id: + print("{:>12} {:<38} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name_id(m))) + else: + print("{:>12} {:<38} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name(m))) + else: + print("{:>12} {}".format(format_duration(m), m["meetingName"])) + if more: + print(" {}".format("."*(len(by_duration)-len(by_duration[:n])))) + print() + else: + m = by_duration[0] if presenter: if presenter_id: - print("{:>12} {:<38} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name_id(m))) + print("{:>4} {:<45} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name_id(m))) else: - print("{:>12} {:<38} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name(m))) + print("{:>4} {:<45} {}".format(format_duration(m), m["meetingName"], get_formated_presenter_name(m))) else: - print("{:>12} {}".format(format_duration(m), m["meetingName"])) + print("{:>4} {}".format(format_duration(m), m["meetingName"])) + + +def print_header(endpoint_name: str, text: str, fancy=True, newline=True): + click.echo(format_header(endpoint_name, text, fancy), nl=newline) -def print_header(endpoint_name: str, text: str, fancy=True): +def format_header(endpoint_name: str, text: str, fancy=True) -> str: if fancy: - click.echo(click.style(" [{}] {} ".format(endpoint_name, text), fg='black', bg='white', bold=True)) + if len(endpoint_name) > 0: + block = click.style(" [{}] {} ".format(endpoint_name, text), fg='black', bg='white', bold=True) + else: + block = click.style(" {} {} ".format(endpoint_name, text), fg='black', bg='white', bold=True) else: - print("[{}] {}".format(endpoint_name, text)) \ No newline at end of file + if len(endpoint_name) > 0: + block = "[{}] {}".format(endpoint_name, text) + else: + block = "{} {}".format(endpoint_name, text) + return "{}{}".format(block, " "*(20-len(endpoint_name+text))) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index ce067b6..83d1f9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "bbbmon" -version = "0.1.18" +version = "0.1.19" description = "A small CLI utility to monitor bbb usage" authors = ["David Huss <david.huss@hfbk-hamburg.de>"] maintainers = ["David Huss <david.huss@hfbk-hamburg.de>"] -- GitLab