Beispiel #1
0
    def update_room(self, vc_room, event):
        client = AdminClient(self.settings)

        try:
            room_obj = self.get_room(vc_room)
        except RoomNotFoundAPIException:
            raise VCRoomNotFoundError(_("This room has been deleted from Vidyo"))

        owner = retrieve_principal(vc_room.data['owner'], allow_groups=False, legacy=False)
        changed_owner = room_obj.ownerName not in iter_user_identities(owner)
        if changed_owner:
            login_gen = iter_user_identities(owner)
            login = next(login_gen, None)
            if login is None:
                raise VCRoomError(_("No valid Vidyo account found for this user"), field='owner_user')
            room_obj.ownerName = login

        room_obj.name = vc_room.name
        room_obj.description = vc_room.data['description']

        room_obj.RoomMode.hasPIN = vc_room.data['room_pin'] != ""
        room_obj.RoomMode.hasModeratorPIN = vc_room.data['moderation_pin'] != ""

        if room_obj.RoomMode.hasPIN:
            room_obj.RoomMode.roomPIN = vc_room.data['room_pin']
        if room_obj.RoomMode.hasModeratorPIN:
            room_obj.RoomMode.moderatorPIN = vc_room.data['moderation_pin']

        vidyo_id = vc_room.data['vidyo_id']
        while True:
            try:
                client.update_room(vidyo_id, room_obj)
            except RoomNotFoundAPIException:
                raise VCRoomNotFoundError(_("This room has been deleted from Vidyo"))
            except APIException as err:
                err_msg = err.message
                if err_msg.startswith('Room exist for name'):
                    raise VCRoomError(_("Room name already in use"), field='name')

                elif err_msg.startswith('Member not found for ownerName'):
                    if changed_owner:
                        login = next(login_gen, None)
                    if not changed_owner or login is None:
                        raise VCRoomError(_("No valid Vidyo account found for this user"), field='owner_user')
                    room_obj.ownerName = login

                else:
                    raise
            else:
                updated_room_obj = self.get_room(vc_room)

                update_room_from_obj(self.settings, vc_room, updated_room_obj)
                flag_modified(vc_room, 'data')

                client.set_automute(vidyo_id, vc_room.data['auto_mute'])
                break
Beispiel #2
0
def update_zoom_meeting(zoom_id, changes, is_webinar=False):
    """Update a meeting which already exists in the Zoom API.

    :param zoom_id: ID of the meeting
    :param changes: dictionary with new attribute values
    :param is_webinar: whether the call concerns a webinar (used to call the correct endpoint)
    """
    client = ZoomIndicoClient()
    try:
        if is_webinar:
            client.update_webinar(zoom_id, changes)
        else:
            client.update_meeting(zoom_id, changes)
    except HTTPError as e:
        from indico_vc_zoom.plugin import ZoomPlugin
        ZoomPlugin.logger.exception("Error updating meeting '%s': %s", zoom_id,
                                    e.response.content)

        if e.response.json()['code'] == 3001:
            # "Meeting does not exist"
            raise VCRoomNotFoundError(_('Room no longer exists in Zoom'))

        raise VCRoomError(
            _("Can't update meeting. Please contact support if the error persists."
              ))
Beispiel #3
0
def get_alt_host_emails(identifiers):
    """Convert a list of identities into a list of enterprise e-mails."""
    emails = [
        find_enterprise_email(principal_from_identifier(ident))
        for ident in identifiers
    ]
    if None in emails:
        raise VCRoomError(_('Could not find Zoom user for alternative host'))
    return emails
Beispiel #4
0
 def delete_room(self, vc_room, event):
     client = ZoomIndicoClient()
     zoom_id = vc_room.data['zoom_id']
     is_webinar = vc_room.data['meeting_type'] == 'webinar'
     try:
         if is_webinar:
             client.delete_webinar(zoom_id)
         else:
             client.delete_meeting(zoom_id)
     except HTTPError as e:
         # if there's a 404, there is no problem, since the room is supposed to be gone anyway
         if e.response.status_code == 404:
             if has_request_context():
                 flash(_("Room didn't exist in Zoom anymore"), 'warning')
         elif e.response.status_code == 400:
             # some sort of operational error on Zoom's side, deserves a specific error message
             raise VCRoomError(
                 _('Zoom Error: "{}"').format(e.response.json()['message']))
         else:
             self.logger.error("Can't delete room")
             raise VCRoomError(_('Problem deleting room'))
Beispiel #5
0
 def _process(self):
     if not session.user:
         return redirect_to_login(next_url=url_for_plugin(
             'vc_bbb.start_and_join', self.event_vc_room),
                                  reason='Please, identify yourself')
     create_url = get_create_meeting_url(self.vc_room, self.event_vc_room)
     is_moderator = list(
         session.user.as_principal) in self.event_vc_room.data['moderators']
     join_url = get_join_url(self.vc_room, is_moderator)
     if is_meeting_running(self.vc_room):
         return redirect(join_url)
     if not is_moderator:
         return redirect(url_for('vc.event_videoconference', self.event))
     try:
         files = self.event_vc_room.data['file']
     except KeyError:
         files = None
     if files and len(files):
         xml = "<?xml version='1.0' encoding='UTF-8'?><modules>"
         for f in files:
             xml += "<module name=\"presentation\"><document name=\"" + f[
                 'filename'] + "\">" + f['content'] + "</document></module>"
         xml += "</modules>"
         r = requests.put(create_url,
                          data=xml,
                          headers={'Content-type': 'application/xml'})
     else:
         r = requests.get(create_url)
     root = ET.fromstring(r.content)
     status = root.find('returncode').text
     if status == 'SUCCESS':
         internal_id = root.find('internalMeetingID').text
         try:
             running = internal_id in self.event_vc_room.data[
                 'internal_id_list']
         except KeyError:
             self.event_vc_room.data['internal_id_list'] = [internal_id]
             running = False
         else:
             if not running:
                 self.event_vc_room.data['internal_id_list'].append(
                     internal_id)
         flag_modified(self.event_vc_room, 'data')
         return redirect(join_url)
     else:
         raise VCRoomError(_("Cannot create room"))
         return jsonify_data(flash=False)
Beispiel #6
0
def fetch_zoom_meeting(vc_room, client=None, is_webinar=False):
    """Fetch a Zoom meeting from the Zoom API.

    :param vc_room: The `VCRoom` object
    :param client: a `ZoomIndicoClient` object, otherwise a fresh one will be created
    :param is_webinar: whether the call concerns a webinar (used to call the correct endpoint)
    """
    try:
        client = client or ZoomIndicoClient()
        if is_webinar:
            return client.get_webinar(vc_room.data['zoom_id'])
        return client.get_meeting(vc_room.data['zoom_id'])
    except HTTPError as e:
        if e.response.status_code in {400, 404}:
            # Indico will automatically mark this room as deleted
            raise VCRoomNotFoundError(
                _('This room has been deleted from Zoom'))
        else:
            from indico_vc_zoom.plugin import ZoomPlugin
            ZoomPlugin.logger.exception('Error getting Zoom Room: %s',
                                        e.response.content)
            raise VCRoomError(
                _('Problem fetching room from Zoom. Please contact support if the error persists.'
                  ))
Beispiel #7
0
    def create_room(self, vc_room, event):
        """Create a new Bluejeans room for an event, given a VC room.

        In order to create the Bluejeans room, the function will try to do so with
        all the available identities of the user based on the authenticators
        defined in Bluejeans plugin's settings, in that order.

        :param vc_room: VCRoom -- The VC room from which to create the Bluejeans
                        room
        :param event: Event -- The event to the Bluejeans room will be attached
        """

        client = AdminClient(self.settings)
        owner = retrieve_principal(vc_room.data['owner'])
        login_gen = iter_user_identities(owner)
        login = next(login_gen, None)
        if login is None:
            raise VCRoomError(
                _("No valid Bluejeans account found for this user"),
                field='owner_user')

        extension_gen = iter_extensions(
            self.settings.get('indico_room_prefix'), event.id)
        extension = next(extension_gen)

        while True:
            room_mode = {
                'isLocked': False,
                'hasPIN': bool(vc_room.data['room_pin']),
                'hasModeratorPIN': bool(vc_room.data['moderation_pin'])
            }
            if room_mode['hasPIN']:
                room_mode['roomPIN'] = vc_room.data['room_pin']
            if room_mode['hasModeratorPIN']:
                room_mode['moderatorPIN'] = vc_room.data['moderation_pin']

            room_obj = client.create_room_object(
                name=vc_room.name,
                RoomType='Public',
                ownerName=login,
                extension=extension,
                groupName=self.settings.get('room_group_name'),
                description=vc_room.data['description'],
                RoomMode=room_mode)

            if room_obj.RoomMode.hasPIN:
                room_obj.RoomMode.roomPIN = vc_room.data['room_pin']
            if room_obj.RoomMode.hasModeratorPIN:
                room_obj.RoomMode.moderatorPIN = vc_room.data['moderation_pin']

            try:
                client.add_room(room_obj)
            except APIException as err:
                err_msg = err.message

                if err_msg.startswith('Room exist for name'):
                    raise VCRoomError(_("Room name already in use"),
                                      field='name')
                elif err_msg.startswith('Member not found for ownerName'):
                    login = next(login_gen, None)
                    if login is None:
                        raise VCRoomError(_(
                            "No valid Bluejeans account found for this user"),
                                          field='owner_user')
                elif err_msg.startswith('Room exist for extension'):
                    extension = next(extension_gen)
                else:
                    raise

            else:
                # get room back, in order to fetch Bluejeans-set parameters
                created_room = client.find_room(extension)

                if not created_room:
                    raise VCRoomNotFoundError(
                        _("Could not find newly created room in Bluejeans"))
                vc_room.data.update({
                    'bluejeans_id':
                    unicode(created_room.roomID),
                    'url':
                    created_room.RoomMode.roomURL,
                    'owner_identity':
                    created_room.ownerName
                })
                flag_modified(vc_room, 'data')
                vc_room.bluejeans_extension = BluejeansExtension(
                    vc_room_id=vc_room.id,
                    extension=int(created_room.extension),
                    owned_by_user=owner)

                client.set_automute(created_room.roomID,
                                    vc_room.data['auto_mute'])
                break
Beispiel #8
0
    def create_room(self, vc_room, event):
        """Create a new Zoom room for an event, given a VC room.

        In order to create the Zoom room, the function will try to get
        a valid e-mail address for the user in question, which can be
        use with the Zoom API.

        :param vc_room: the VC room from which to create the Zoom room
        :param event: the event to the Zoom room will be attached
        """
        client = ZoomIndicoClient()
        host = principal_from_identifier(vc_room.data['host'])
        host_email = find_enterprise_email(host)

        # get the object that this booking is linked to
        vc_room_assoc = vc_room.events[0]
        link_obj = vc_room_assoc.link_object
        is_webinar = vc_room.data.setdefault('meeting_type',
                                             'regular') == 'webinar'
        scheduling_args = get_schedule_args(
            link_obj) if link_obj.start_dt else {}

        try:
            settings = {
                'host_video': not vc_room.data['mute_host_video'],
            }

            kwargs = {}
            if is_webinar:
                kwargs['type'] = (ZoomMeetingType.webinar
                                  if scheduling_args else
                                  ZoomMeetingType.recurring_webinar_no_time)
                settings['alternative_hosts'] = host_email
            else:
                kwargs = {
                    'type':
                    (ZoomMeetingType.scheduled_meeting if scheduling_args else
                     ZoomMeetingType.recurring_meeting_no_time),
                    'schedule_for':
                    host_email
                }
                settings.update({
                    'mute_upon_entry':
                    vc_room.data['mute_audio'],
                    'participant_video':
                    not vc_room.data['mute_participant_video'],
                    'waiting_room':
                    vc_room.data['waiting_room'],
                    'join_before_host':
                    self.settings.get('join_before_host'),
                })

            kwargs.update({
                'topic': vc_room.name,
                'agenda': vc_room.data['description'],
                'password': vc_room.data['password'],
                'timezone': event.timezone,
                'settings': settings
            })
            kwargs.update(scheduling_args)
            if is_webinar:
                meeting_obj = client.create_webinar(host_email, **kwargs)
            else:
                meeting_obj = client.create_meeting(host_email, **kwargs)
        except HTTPError as e:
            self.logger.exception('Error creating Zoom Room: %s',
                                  e.response.content)
            raise VCRoomError(
                _('Could not create the room in Zoom. Please contact support if the error persists'
                  ))

        vc_room.data.update({
            'zoom_id':
            str(meeting_obj['id']),
            'start_url':
            meeting_obj['start_url'],
            'host':
            host.identifier,
            'alternative_hosts':
            process_alternative_hosts(meeting_obj['settings'].get(
                'alternative_hosts', ''))
        })
        vc_room.data.update(get_url_data_args(meeting_obj['join_url']))
        flag_modified(vc_room, 'data')

        # e-mail Host URL to meeting host
        if self.settings.get('send_host_url'):
            notify_host_start_url(vc_room)