Example #1
0
    async def leave_group(self, request, context):
        try:
            leave_member = request.leave_member
            leave_member_by = request.leave_member_by

            new_member_status = "removed"
            if leave_member.id == leave_member_by.id:
                new_member_status = "leaved"

            group = GroupService().get_group_info(request.group_id)
            group_clients = json.loads(group.group_clients)

            leave_member_in_group = False
            leave_member_by_in_group = False
            for e in group_clients:
                if e['id'] == leave_member.id:
                    leave_member_in_group = True
                    e['status'] = new_member_status
                if e['id'] == leave_member_by.id:
                    leave_member_by_in_group = True
            if not leave_member_in_group:
                raise Exception(Message.LEAVED_MEMBER_NOT_IN_GROUP)
            if not leave_member_by_in_group and new_member_status == "removed":
                raise Exception(Message.REMOVER_MEMBER_NOT_IN_GROUP)

            # update field group_clients first
            logger.info("New group client: {}".format(group_clients))
            group.group_clients = json.dumps(group_clients)
            group.updated_by = leave_member_by.id
            group.update()

            owner_workspace_domain = get_owner_workspace_domain()

            # wait for service to leave group, and return base response if no exception occured
            if (group.owner_workspace_domain and group.owner_workspace_domain != owner_workspace_domain):
                await self.service.leave_group_not_owner(
                    leave_member,
                    leave_member_by,
                    group,
                )
            else:
                await self.service.leave_group_owner(
                    leave_member,
                    leave_member_by,
                    group,
                )

            return group_messages.BaseResponse()
        except Exception as e:
            logger.error(e)
            if not e.args or e.args[0] not in Message.msg_dict:
                errors = [Message.get_error_object(Message.LEAVE_GROUP_FAILED)]
            else:
                errors = [Message.get_error_object(e.args[0])]
            context.set_details(json.dumps(
                errors, default=lambda x: x.__dict__))
            context.set_code(grpc.StatusCode.INTERNAL)
Example #2
0
    async def workspace_video_call(self, request, context):
        try:
            logger.info("workspace_video_call")

            from_client_id = request.from_client_id
            from_client_name = request.from_client_name
            if request.from_client_avatar:
                from_client_avatar = request.from_client_avatar
            else:
                from_client_avatar = ""
            group_id = request.group_id
            client_id = request.client_id

            server_info = ServerInfoService().get_server_info()
            webrtc_token = secrets.token_hex(10)

            group_obj = GroupService().get_group_info(group_id)
            group_obj.group_rtc_token = webrtc_token
            group_obj.update()
            # register webrtc
            self.service_group.register_webrtc_token(webrtc_token)
            #  create room
            self.service_group.create_rtc_group(group_id, webrtc_token)
            logger.info('janus webrtc token={}'.format(webrtc_token))
            client_ws_url = get_system_config()['janus_webrtc'].get('client_ws_url')

            # send push notification to all member of group
            lst_client_in_groups = self.service_group.get_clients_in_group(group_id)
            # list token for each device type

            owner_workspace_domain = get_owner_workspace_domain()

            for client in lst_client_in_groups:
                if client.GroupClientKey.client_workspace_domain != request.from_client_workspace_domain:
                    push_payload = {
                        'notify_type': 'request_call',
                        'call_type': request.call_type,
                        'group_id': str(request.group_id),
                        'group_name': group_obj.group_name if group_obj.group_name else '',
                        'group_type': group_obj.group_type if group_obj.group_type else '',
                        'group_rtc_token': webrtc_token,
                        'group_rtc_url': client_ws_url,
                        'group_rtc_id': str(group_id),
                        'from_client_id': from_client_id,
                        'from_client_name': from_client_name,
                        'from_client_avatar': from_client_avatar,
                        'client_id': client_id,
                        'stun_server': server_info.stun_server,
                        'turn_server': server_info.turn_server
                    }
                    logger.info(push_payload)
                    if client.GroupClientKey.client_workspace_domain is None or client.GroupClientKey.client_workspace_domain == owner_workspace_domain:
                        await NotifyPushService().push_voip_client(client.User.id, push_payload)
                    else:
                        new_push_payload = deepcopy(push_payload)
                        new_push_payload['group_id'] = str(client.GroupClientKey.client_workspace_group_id)
                        logger.info(new_push_payload)
                        ClientPush(client.GroupClientKey.client_workspace_domain).push_voip(client.User.id,
                                                                                            json.dumps(new_push_payload))

            stun_server_obj = json.loads(server_info.stun_server)
            stun_server = video_call_pb2.StunServer(
                server=stun_server_obj["server"],
                port=stun_server_obj["port"]
            )
            turn_server_obj = json.loads(server_info.turn_server)
            turn_server = video_call_pb2.TurnServer(
                server=turn_server_obj["server"],
                port=turn_server_obj["port"],
                type=turn_server_obj["type"],
                user=turn_server_obj["user"],
                pwd=turn_server_obj["pwd"]
            )
            return video_call_pb2.ServerResponse(
                group_rtc_url=client_ws_url,
                group_rtc_id=group_id,
                group_rtc_token=webrtc_token,
                stun_server=stun_server,
                turn_server=turn_server,
            )
        except Exception as e:
            logger.error(e)
            if not e.args or e.args[0] not in Message.msg_dict:
                errors = [Message.get_error_object(Message.CLIENT_REQUEST_CALL_FAILED)]
            else:
                errors = [Message.get_error_object(e.args[0])]
            context.set_details(json.dumps(
                errors, default=lambda x: x.__dict__))
            context.set_code(grpc.StatusCode.INTERNAL)
Example #3
0
    async def add_member(self, request, context):
        try:
            group = GroupService().get_group_info(request.group_id)
            group_clients = json.loads(group.group_clients)
            added_member_info = request.added_member_info
            adding_member_info = request.adding_member_info

            #get workspace is active in group
            workspace_domains = list(set(
                [e['workspace_domain'] for e in group_clients
                 if ('status' not in e or
                     ('status' in e and e['status'] in ['active']))]
            ))
            logger.info(workspace_domains)

            #check added and adding member in group
            adding_member_in_group = False
            for e in group_clients:
                if 'status' not in e or e['status'] in ['active']:
                    if e['id'] == added_member_info.id:
                        raise Exception(Message.ADDED_USER_IS_ALREADY_MEMBER)
                    if e['id'] == adding_member_info.id:
                        adding_member_in_group = True
            if not adding_member_in_group:
                raise Exception(Message.ADDER_MEMBER_NOT_IN_GROUP)

            # new group clients
            new_group_clients = []
            is_old_member = False
            for e in group_clients:
                if e['id'] == added_member_info.id:
                    e['status'] = 'active'  # turn into active member
                    is_old_member = True
                new_group_clients.append(e)
            if not is_old_member:
                added_member_info.status = 'active'
                new_group_clients.append(
                    MessageToDict(
                        added_member_info,
                        preserving_proto_field_name=True
                    )
                )

            # update group members first
            group.group_clients = json.dumps(new_group_clients)
            group.updated_by = adding_member_info.id
            group.updated_at = datetime.datetime.now()
            group.update()

            owner_workspace_domain = get_owner_workspace_domain()

            # wait for service to add member to group, and return base response if no exception occured
            if (group.owner_workspace_domain and group.owner_workspace_domain != owner_workspace_domain):
                await self.service.add_member_to_group_not_owner(
                    added_member_info,
                    adding_member_info,
                    group,
                )
            else:
                await self.service.add_member_to_group_owner(
                    added_member_info,
                    adding_member_info,
                    group
                )

            return group_messages.BaseResponse()
        except Exception as e:
            logger.error(e)
            if not e.args or e.args[0] not in Message.msg_dict:
                errors = [Message.get_error_object(Message.ADD_MEMBER_FAILED)]
            else:
                errors = [Message.get_error_object(e.args[0])]
            context.set_details(json.dumps(
                errors, default=lambda x: x.__dict__))
            context.set_code(grpc.StatusCode.INTERNAL)