diff --git a/plugins/bigbluebutton/bbb_usage b/plugins/bigbluebutton/bbb_usage new file mode 100755 index 000000000..730c57c89 --- /dev/null +++ b/plugins/bigbluebutton/bbb_usage @@ -0,0 +1,174 @@ +#!/usr/bin/env python3 +""" + +=head1 NAME + +bbb - monitor Bigbluebutton server (users, rooms, videostreams ...) + +=head1 APPLICABLE SYSTEMS + +Bigbluebutton server + +=head1 CONFIGURATION + +No configuration is needed. This script will fetch the secret from the local +bbb instance + +https://docs.bigbluebutton.org/dev/api.html + +=head1 AUTHOR + +Copyright 2021 Henning Rieger + +With many thanks to the original Author Bernd Wurst (bwurst.org) + +=head1 LICENSE +GNU General Public License v3.0 or later + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +=cut +""" + +import sys +import subprocess +import re +import hashlib +import urllib.request +from urllib.error import URLError, HTTPError +import os +from xml.etree import ElementTree + +bbbconf_path = "/usr/bin/bbb-conf" + + +def config(): + """ autoconfig values """ + print("graph_title BigBlueButton") + print("graph_vlabel Numbers") + print("graph_category other") + print("meetings.label Rooms") + print("users.label User") + print("videostreams.label Videostreams") + print("listeners.label Listeners") + print("speakers.label Speakers") + print("moderators.label Moderators") + + +def bbb_stats(): + URL = None + secret = None + + # find out url and secret from local bbb instance + if os.path.exists(bbbconf_path): + # Ubuntu 16.04 with Python 3.5 is recommended for bbb 2.2.x + if sys.version_info.major == 3 and sys.version_info.minor < 7: + tmp = subprocess.run([bbbconf_path, '--secret'], + stdout=subprocess.PIPE, universal_newlines=True) + else: + tmp = subprocess.run([bbbconf_path, '--secret'], capture_output=True, text=True) + output = tmp.stdout + + for line in output.splitlines(): + m = re.search('URL: (?P.*/bigbluebutton/)', line) + if m: + URL = m.group('URL') + continue + m = re.search('Secret: (?P.*)$', line) + if m: + secret = m.group('secret') + + if not URL or not secret: + print('error getting URL and/or secret. Is "bbb-conf --secret" returning it?') + sys.exit(1) + + # prepare api request + APIURL = URL + 'api/' + apimethod = 'getMeetings' + querystring = '' + + h = hashlib.sha1((apimethod + querystring + secret).encode('utf-8')) + checksum = h.hexdigest() + + if len(querystring) > 0: + querystring = querystring + '&' + + requesturl = APIURL + apimethod + '?' + querystring + 'checksum=' + checksum + + # make api request + response = urllib.request.urlopen(requesturl) + responsedata = response.read() + try: + tree = ElementTree.fromstring(responsedata) + except HTTPError as e: + print('There was an error with the recieved data from bbb api.') + print('Error code: ', e.code) + sys.exit(1) + except URLError as e: + print('There was an error with the recieved data from bbb api.') + print('Reason: ', e.reason) + sys.exit(1) + else: + if tree.find('returncode').text != 'SUCCESS': + print('There was an error within the API data') + sys.exit(1) + + meetings = tree.find('meetings') + + # get numbers from api response + num_meetings = 0 + num_users = 0 + num_video = 0 + num_listeners = 0 + num_speakers = 0 + num_moderators = 0 + + for m in meetings.iter('meeting'): + meetname = m.find('meetingName').text + participants = m.find('participantCount').text + video = m.find('videoCount').text + listeners = m.find('listenerCount').text + speakers = m.find('voiceParticipantCount').text + moderators = m.find('moderatorCount').text + + meta = m.find('metadata') + if meta.find('bbb-context') is not None: + meetname = meta.find('bbb-context').text + ' / ' + meetname + + num_meetings += 1 + num_users += int(participants) + num_video += int(video) + num_listeners += int(listeners) + num_speakers += int(speakers) + num_moderators += int(moderators) + + # finally print everything + print('meetings.value %2i' % (num_meetings)) + print('users.value %2i' % (num_users)) + print('videostreams.value %2i' % (num_video)) + print('listeners.value %2i' % (num_listeners)) + print('speakers.value %2i' % (num_speakers)) + print('moderators.value %2i' % (num_moderators)) + + +if __name__ == '__main__': + if len(sys.argv) > 1 and sys.argv[1] == 'autoconf': + if os.path.exists(bbbconf_path): + print("yes") + else: + print("no (%s not found)" % bbbconf_path) + elif len(sys.argv) > 1 and sys.argv[1] == 'config': + config() + else: + bbb_stats()