コード例 #1
0
def join_room():
    """View to let user join a virtual room"""

    form = RoomForm()

    # if the form is submitted and valid
    if form.validate_on_submit():
        roomId = form.roomId.data.strip()
        password = form.password.data
        username = form.username.data.strip().replace(" ", "_")

        b = BigBlueButton(BBB_SERVER_URL, BBB_SERVER_SECRET)

        r = b.is_meeting_running(roomId)

        active_room = json.loads(r['xml']['running'].lower())

        # check if the meeting exists
        if not active_room:
            return render_template('conference/join_conference.html',
                                   form=form,
                                   existingId=True)
        else:
            # get room url
            room_url = b.get_join_meeting_url(username, roomId, password)

            # redirect to the room
            return redirect(room_url)

    return render_template('conference/join_conference.html', form=form)
コード例 #2
0
def create_room():
    """View to let user create a virtual room"""

    if current_user.is_authenticated:
        if ('admin' in current_user.roles) | ('roomCreator'
                                              in current_user.roles):
            form = RoomForm()

            # if the form is submitted and valid
            if form.validate_on_submit():
                roomId = form.roomId.data.strip()
                password = form.password.data
                username = form.username.data.strip().replace(" ", "_")
                modPassword = secrets.token_urlsafe(64)

                b = BigBlueButton(BBB_SERVER_URL, BBB_SERVER_SECRET)

                # params
                dict = {
                    'name': username,
                    'attendeePW': password,
                    'moderatorPW': modPassword,
                    'record': True
                }

                if os.getenv('CURRENT_HOST'):
                    dict['logoutURL'] = os.getenv('CURRENT_HOST')

                try:
                    # use create meeting
                    b.create_meeting(roomId, params=dict)
                except BBBException:
                    return render_template('conference/create_conference.html',
                                           form=form,
                                           existingId=True)

                # get room url
                room_url = b.get_join_meeting_url(username, roomId,
                                                  modPassword)

                # redirect to the created room
                return redirect(room_url)

            return render_template('conference/create_conference.html',
                                   form=form)
        else:
            return render_template('conference/info_create.html')
    else:
        return render_template('conference/info_create.html')
コード例 #3
0
class RoomUtil:
    logging.basicConfig(level=logging.DEBUG)

    def __init__(self, bbbUrl, bbbSecret):
        logging.info("setup BBB connection")
        self.bbb = BigBlueButton(bbbUrl, bbbSecret)

    def __existRoom(self, roomId):
        try:
            self.bbb.get_meeting_info(roomId)
            return True
        except:
            return False

    def getRoomUrl(self,
                   roomId,
                   username="******".format(str(uuid.uuid4())),
                   moderator=False):
        logging.info("getRoomUrl with roomId: {}".format(roomId))
        if not self.__existRoom(roomId):
            attendeePW = str(uuid.uuid4())
            moderatorPW = str(uuid.uuid4())
            dict = {'attendeePW': attendeePW, 'moderatorPW': moderatorPW}
            self.bbb.create_meeting(roomId, params=dict)
        else:
            meetingInfo = self.bbb.get_meeting_info(roomId).get_meetinginfo()
            attendeePW = meetingInfo.get_attendeepw()
            moderatorPW = meetingInfo.get_moderatorpw()

        if (moderator):
            userPw = moderatorPW
        else:
            userPw = attendeePW

        meetingInfoJson = self.bbb.get_meeting_info(meeting_id=roomId)
        logging.debug(json.dumps(meetingInfoJson, indent=1))

        return self.bbb.get_join_meeting_url(username, roomId, userPw)
コード例 #4
0
    def post(self, request, cid="", *args, **kwargs):
        try:
            campaign = CampaignModel.objects.get(id=cid)
        except CampaignModel.DoesNotExist:
            return Http404
        try:
            account = AccountModel.objects.get(user__username=request.user)
        except AccountModel.DoesNotExist:
            return Http404

        bbb = BigBlueButton(settings.BBB_HOST, settings.BBB_SECRET)
        # TODO: INSECURE AS SHIT
        attendee = hashlib.md5(
            (campaign.name + "mod").encode("utf-8")).hexdigest().replace(
                "&", "-")
        moderator = hashlib.md5(
            (campaign.name + "att").encode("utf-8")).hexdigest().replace(
                "&", "-")
        meeting_id = hashlib.md5(
            campaign.name.encode("utf-8")).hexdigest().replace("&", "-")

        try:
            bbb.create_meeting(meeting_id,
                               params={
                                   "attendeePW": attendee,
                                   "moderatorPW": moderator
                               })
        except Exception:
            pass

        is_moderator = request.user.id in [
            x.user.id for x in campaign.game_master.all()
        ] or request.user.is_superuser
        url = bbb.get_join_meeting_url(request.POST["name"], meeting_id,
                                       moderator if is_moderator else attendee)
        return redirect(url)
コード例 #5
0
class scheduLight:
    """ core functions for processing of commands and meetings  """

    # set startTime
    NOW = datetime.now()
    # prepare bbb
    bbb = None
    bbbUrl = None
    # keep status entris for n seconds
    keep_redis_cache = "31536000"
    # write to this logFile
    logFile = 'scheduLight.log'
    # define schemas
    meeting_schema = dataSchema.meetingSchema()
    server_schema = dataSchema.serverSchema()
    command_schema = dataSchema.commandSchema()
    command_rename_room_schema = dataSchema.commandRenameRoomSchema
    command_share_room_schema = dataSchema.commandShareRoomSchema
    command_create_room_schema = dataSchema.commandCreateRoomSchema
    command_create_user_schema = dataSchema.commandCreateUserSchema
    validate_schema = dataSchema.validate_schema

    def __init__(self, args={}):
        if 'keep_redis_cache' in args:
            self.keep_redis_cache = args.keep_redis_cache
        if 'logFile' in args:
            self.logFile = args.logFile

        ## create logger with 'scheduLight'
        self.logger = logging.getLogger('scheduLight')
        self.logger.setLevel(logging.DEBUG)
        ## create file handler which logs even debug messages
        fh = logging.handlers.RotatingFileHandler(self.logFile,
                                                  maxBytes=1000000,
                                                  backupCount=5)
        fh.setLevel(logging.DEBUG)
        ## create console handler with a higher log level
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ## create formatter and add it to the handlers
        formatter = logging.Formatter(
            '%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
            '%Y-%m-%d %H:%M:%S')
        fh.setFormatter(formatter)
        formatter2 = logging.Formatter('%(levelname)-8s %(message)s')
        ch.setFormatter(formatter2)
        ## add the handlers to the logger
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)
        #

        # connect to redis db
        self.r = redis.StrictRedis(host="localhost",
                                   port="6380",
                                   db=1,
                                   ssl=False,
                                   charset="utf-8",
                                   decode_responses=True)
        try:
            self.r.info()
        except redis.exceptions.ConnectionError as ERR:
            self.logger.error("Redis not ready: {}".format(ERR))
            sys.exit()
        # prepare mail queue
        try:
            #self.r.xgroup_destroy('mailStream', 'mailNotifications')
            self.r.xgroup_create('mailStream', 'mailNotifications', '0-0',
                                 True)
        except Exception as ERR:
            self.logger.debug("Redis stream warning: {}".format(ERR))
        #prepare command queue
        try:
            #self.r.xgroup_destroy('commandStream', 'commandNotifications')
            self.r.xgroup_create('commandStream', 'commandNotifications',
                                 '0-0', True)
        except Exception as ERR:
            self.logger.debug("Redis stream warning: {}".format(ERR))

    def init_bbb(self, server):
        servers = {}
        res = self.r.get("server:{}".format(server))
        if res:
            servers[server] = json.loads(res)
            BBB_URL = servers[server]['BBB_URL']
            BBB_SECRET = servers[server]['BBB_SECRET']
            self.bbb = BigBlueButton(BBB_URL, BBB_SECRET)
            self.bbbUrl = bbbUtil.UrlBuilder(BBB_URL, BBB_SECRET)
            self.logger.debug("connected to bbb server: {}".format(server))
            return True
        else:
            self.logger.error(
                "could not connect to bbb server: {}".format(server))
            return False

    def get_date(self, dateString):
        format_string = "%Y-%m-%d %H:%M"
        return datetime.strptime(dateString, format_string)

    def render_template(self, template, **kwargs):
        template_file = os.path.dirname(__file__) + '/templates/' + template
        if not os.path.exists(template_file):
            self.logger.error(
                "Mail Template {} not found!".format(template_file))
            sys.exit()
        templateLoader = jinja2.FileSystemLoader(
            searchpath=os.path.dirname(__file__) + '/templates/')
        templateEnv = jinja2.Environment(loader=templateLoader)
        templ = templateEnv.get_template(template)
        return templ.render(**kwargs)

    def config_exists(self, my_dict, my_list):
        for my_item in my_list:
            if my_item not in my_dict:
                return False
        return True

    def random_secret(self, stringLength=11):
        lettersAndDigits = string.ascii_letters + string.digits
        return ''.join(
            (random.choice(lettersAndDigits) for i in range(stringLength)))

    def get_status(self, base, path, displayType='returnCode', type='meeting'):
        search_base = "{}:{}:status".format(type, base)
        search_path = str.join("_", path)
        statusList = self.r.hget(search_base, search_path)
        if statusList == None:
            self.logger.debug("no status found for {} {}".format(
                base, search_path))
            return None
        statusList = json.loads(statusList)
        if not isinstance(statusList, list):
            self.logger.debug("corrupted status found for {}".format(base))
            return None
        self.r.touch(search_base)
        # return status
        if displayType == 'raw':
            return statusList
        (date, returnCode, message) = statusList[-1].split("|")
        self.logger.debug("status: {} {} {} ({})".format(
            returnCode, message, date, search_path))
        if displayType == 'date':
            return date
        elif displayType == 'returnCode':
            return returnCode
        else:
            return message

    def set_status(self, base, path, returnCode, message, type='meeting'):
        search_base = "{}:{}:status".format(type, base)
        search_path = str.join("_", path)
        oldStatus = self.get_status(base, path, 'raw', type)
        if oldStatus != None and oldStatus[-1].split('|')[1] == returnCode:
            self.logger.debug("status already set to {} {}".format(
                returnCode, message))
            return None
        else:
            if not isinstance(oldStatus, list):
                oldStatus = []
            oldStatus.append("{}|{}|{}".format(self.NOW, returnCode, message))
            self.r.hset(search_base, search_path, json.dumps(oldStatus))
            self.r.expire(search_base, self.keep_redis_cache)
            self.logger.debug("set status: {} {} ({})".format(
                returnCode, message, search_path))
            return True

    def meeting_info(self, bbb_id):
        try:
            minfo = self.bbb.get_meeting_info(bbb_id)
        except bbbexception.BBBException as ERR:
            return 0
        return minfo

    def end_meeting(self, bbb_id):
        try:
            minfo = self.bbb.get_meeting_info(bbb_id)
        except bbbexception.BBBException as ERR:
            return 0

        moderator_pw = minfo.get_meetinginfo().get_moderatorpw()
        try:
            meetingsXML = self.bbb.end_meeting(bbb_id, moderator_pw)
        except bbbexception.BBBException as ERR:
            return 0

        if meetingsXML.get_field('returncode') == 'SUCCESS':
            if meetingsXML.get_field('messageKey') == 'sentEndMeetingRequest':
                self.logger.debug("meeting {}: {}".format(
                    meetingName, meetingsXML.get_field('message')))
                return 1
        return 0

    def start_meeting(self,
                      bbb_id,
                      meetingTitle=None,
                      moderatorPassword=None,
                      attendeePassword=None,
                      muteOnStart=None,
                      welcome=None,
                      bannerText=None,
                      maxParticipants=None,
                      logoutURL=None,
                      record=None,
                      duration=None,
                      autoStartRecording=None,
                      allowStartStopRecording=None):
        create_params = {}
        if moderatorPassword:
            create_params['moderatorPW'] = moderatorPassword
        if attendeePassword:
            create_params['attendeePW'] = attendeePassword
        if muteOnStart:
            create_params['muteOnStart'] = muteOnStart
        if welcome:
            create_params['welcome'] = welcome
        if bannerText:
            create_params['bannerText'] = bannerText
        if maxParticipants:
            create_params['maxParticipants'] = maxParticipants
        if logoutURL:
            create_params['logoutURL'] = "https://{}".format(logoutURL)
        if record:
            create_params['record'] = record
        if duration:
            create_params['duration'] = duration
        if autoStartRecording:
            create_params['autoStartRecording'] = autoStartRecording
        if allowStartStopRecording:
            create_params['allowStartStopRecording'] = allowStartStopRecording
        if meetingTitle:
            create_params['name'] = meetingTitle
        try:
            meetingsXML = self.bbb.create_meeting(bbb_id, params=create_params)
        except bbbexception.BBBException as ERR:
            self.logger.error(ERR)
            return 0
        if meetingsXML.get_field('returncode') == 'SUCCESS':
            if meetingsXML.get_field('messageKey') == 'duplicateWarning':
                self.logger.debug("meeting already running: {}".format(
                    meetingsXML.get_field('message')))
            if meetingsXML.get_field('hasUserJoined') == 'false':
                self.logger.debug("no users have joined yet, keeping open")
                # keep open
                return 2
            # users have joined - stop processing
            self.logger.debug("users have joined stopping to process")
            return 1
        # failed to start meeting
        self.logger.debug("failed to start meeting")
        return 0

    def get_join_url(self, id, name, role='attendee', pw=None):
        pwd = None
        if pw:
            pwd = pw
        elif self.meeting_info(id):
            minfo = self.meeting_info(id)
            if role == 'moderator':
                pwd = minfo.get_meetinginfo().get_moderatorpw()
            elif role == 'attendee':
                pwd = minfo.get_meetinginfo().get_attendeepw()
        if pwd:
            return self.bbb.get_join_meeting_url(name, id, pwd)

    def get_meetings(self, server):
        self.logger.debug("fetching meetings from {}".format(server))
        try:
            meetingsXML = self.bbb.get_meetings()
            if meetingsXML.get_field('returncode') == 'SUCCESS':
                if meetingsXML.get_field('meetings') == '':
                    self.logger.debug(
                        "no meetings running on {}".format(server))
                    return []
                else:
                    rawMeetings = meetingsXML.get_field('meetings')['meeting']
                    if isinstance(rawMeetings, list):
                        self.logger.debug(
                            "meetings found on {}".format(server))
                        return json.loads(json.dumps(rawMeetings))
                    else:
                        self.logger.debug("meeting found on {}".format(server))
                        return [json.loads(json.dumps(rawMeetings))]
            else:
                self.logger.error("api request failed")
                return []
        except urllib.error.URLError as ERR:
            self.logger.error(ERR)
            return []

    def find_meeting(self, server, title, user='******'):
        meetings = self.get_meetings(server)
        for meeting in meetings:
            if title in meeting['meetingName']:
                meeting['joinAttendeeUrl'] = self.get_join_url(
                    meeting['meetingID'], user, 'attendee')
                meeting['joinModeratorUrl'] = self.get_join_url(
                    meeting['meetingID'], user, 'moderator')

                joinParams = {}
                joinParams['meetingID'] = meeting['meetingID']
                joinParams['fullName'] = user
                joinParams['password'] = meeting['attendeePW']
                joinParams['userdata-bbb_auto_join_audio'] = "true"
                joinParams['userdata-bbb_enable_video'] = 'false'
                joinParams['userdata-bbb_listen_only_mode'] = "false"
                joinParams['userdata-bbb_skip_check_audio'] = 'true'
                meeting['joinDirectWithMicUrl'] = self.bbbUrl.buildUrl(
                    "join", params=joinParams)
                return meeting

    def show_meetings(self, server, user='******'):
        meetings = self.get_meetings(server)
        for meeting in meetings:
            print(meeting['meetingName'])
            print("ID: {}".format(meeting['meetingID']))
            print("ATTENDEE_PASSWORD: {}".format(meeting['attendeePW']))
            joinAttendeeUrl = self.get_join_url(meeting['meetingID'], user,
                                                'attendee')
            print("JOIN_ATTENDEE_URL: {}".format(joinAttendeeUrl))
            print("MODERATOR_PASSWORD: {}".format(meeting['moderatorPW']))
            joinModeratorUrl = self.get_join_url(meeting['meetingID'], user,
                                                 'moderator')
            print("JOIN_MODERATOR_URL: {}".format(joinModeratorUrl))
            print("")