Esempio n. 1
0
def down_vote(video_id, **kwargs):
    user = kwargs['user']
    video = db.session.query(Video).filter_by(id=video_id).one_or_none()
    if not video:
        raise Error(StatusCode.FORBIDDEN, 'Video does not exist')

    if video.status != VideoStatus.VOTING:
        raise Error(StatusCode.FORBIDDEN, 'Not allow to vote')

    participant = db.session.query(RoomParticipant).filter_by(
        user_id=user.id, room_id=video.room_id).first()
    if participant.status == ParticipantStatus.IN:  # User is in the room that has that video to be able to vote
        vote = db.session.query(Vote).filter_by(user_id=user.id,
                                                video_id=video.id).first()
        if vote is None:
            raise Error(StatusCode.FORBIDDEN,
                        'You have to up-vote first in order to down-vote')
        if vote.status == VoteStatus.DOWNVOTE:
            raise Error(StatusCode.FORBIDDEN, 'Already down-voted')
        if vote.status == VoteStatus.UPVOTE:
            vote.status = VoteStatus.DOWNVOTE
            video.total_vote -= 1
            db.session.commit()
            data = {
                "name": user.name,
                "id": video.id,
                "total_vote": video.total_vote
            }

            pusher.trigger(video.room_id, PusherEvent.DOWN_VOTE, data)

            return jsonify({
                'message': 'Down-voted successfully',
                'data': VideoSchema().dump(video).data
            })
Esempio n. 2
0
def up_vote(video_id, **kwargs):
    user = kwargs['user']
    video = db.session.query(Video).filter_by(id=video_id).one_or_none()
    if not video:
        raise Error(StatusCode.FORBIDDEN, 'Video does not exist')

    if video.status != VideoStatus.VOTING:
        raise Error(StatusCode.FORBIDDEN, 'Video cannot be voted')

    room_id = video.room_id
    participant = db.session.query(RoomParticipant).filter_by(
        user_id=user.id, room_id=room_id).one_or_none()

    if not participant or participant.status != ParticipantStatus.IN:
        raise Error(StatusCode.FORBIDDEN, 'Video cannot be voted')

    # User is in the room that has that video to be able to vote
    vote = db.session.query(Vote).filter_by(user_id=user.id,
                                            video_id=video.id).first()
    if vote is None:
        new_vote = Vote(user_id=user.id,
                        video_id=video.id,
                        status=VoteStatus.UPVOTE)
        video.total_vote += 1
        db.session.add(new_vote)
        db.session.commit()

        data = {
            "name": user.name,
            "id": video.id,
            "total_vote": video.total_vote
        }

        pusher.trigger(video.room_id, PusherEvent.UP_VOTE, data)

        return jsonify({
            'message': 'Upvote successfully',
            'data': VideoSchema().dump(video).data
        })
    if vote.status == VoteStatus.UPVOTE:
        raise Error(StatusCode.FORBIDDEN, 'Already up-voted')

    if vote.status == VoteStatus.DOWNVOTE:
        vote.status = VoteStatus.UPVOTE
        video.total_vote += 1
        db.session.commit()

        data = {
            "name": user.name,
            "id": video.id,
            "total_vote": video.total_vote
        }

        pusher.trigger(video.room_id, PusherEvent.UP_VOTE, data)

        return jsonify({
            'message': 'Upvote successfully',
            'data': VideoSchema().dump(video).data
        })
Esempio n. 3
0
def add_participant_to_room(room_id, user, args):
    room = db.session.query(Room).filter_by(id=room_id).one_or_none()

    if room is None:
        raise Error(StatusCode.BAD_REQUEST, 'Invalid room id')

    # Only room member can add new participant
    checked_participant = db.session.query(RoomParticipant).filter_by(
        user_id=user.id, room_id=room_id).one_or_none()
    if checked_participant is None or checked_participant.status == ParticipantStatus.DELETED:
        raise Error(StatusCode.FORBIDDEN,
                    'You\'re not allowed to add new member to this room')

    added_user = User.query.filter_by(email=args['email']).one_or_none()
    if not added_user:
        raise Error(StatusCode.BAD_REQUEST, 'This user does not exist')

    is_participant = RoomParticipant.query.filter_by(
        user_id=added_user.id, room_id=room_id).one_or_none()
    if not is_participant:
        new_participant = RoomParticipant(user_id=user.id,
                                          room_id=room_id,
                                          status=ParticipantStatus.OUT)
        db.session.add(new_participant)
        db.session.commit()

        notification = {
            "name": added_user.name,
            "user_id": added_user.id,
            "room": room_id
        }

        pusher.trigger(room_id, PusherEvent.NEW_PARTICIPANT, notification)

        return jsonify({
            'message':
            'New participant to the room is created',
            'data':
            RoomParticipantSchema().dump(new_participant).data
        }), 200
    elif is_participant.status == ParticipantStatus.OUT or is_participant.status == ParticipantStatus.DELETED:
        # User is re-added to this room
        checked_participant.status = ParticipantStatus.IN
        db.session.commit()

        notification = {"name": user.name, "user_id": user.id, "room": room_id}

        pusher.trigger(room_id, PusherEvent.NEW_PARTICIPANT, notification)

        return jsonify({
            'message':
            'Participant is re-added to the room',
            'data':
            RoomParticipantSchema().dump(checked_participant).data
        }), 200
    raise Error(StatusCode.UNAUTHORIZED,
                'This user is already a member of this room')
Esempio n. 4
0
def add_video(user, args):
    room_id = args['room_id']
    room = db.session.query(Room).filter_by(id=room_id).one_or_none()

    if room is None:
        raise Error(StatusCode.BAD_REQUEST, 'Invalid room id')

    participant = db.session.query(RoomParticipant).filter_by(
        user_id=user.id, room_id=args['room_id']).first()

    # check whether user is in the room or not to add video
    if not participant or participant.status != ParticipantStatus.IN:
        raise Error(StatusCode.FORBIDDEN, 'Not allow to add video')

    new_video = Video(**args,
                      creator_id=user.id,
                      total_vote=1,
                      status=VideoStatus.VOTING)

    db.session.add(new_video)
    db.session.flush()

    pusher.trigger(room_id, PusherEvent.NEW_VIDEO,
                   VideoSchema().dump(new_video).data)

    new_vote = Vote(video_id=new_video.id,
                    user_id=user.id,
                    status=VoteStatus.UPVOTE)
    db.session.add(new_vote)
    db.session.commit()

    # Play the newest proposed video if current_video is not set
    if not room.current_video:
        new_video.status = VideoStatus.PLAYING
        current_video = video_engine.set_current_video(room_id, new_video.id)

        parsed_current_video = VideoSchema().dump(current_video).data
        parsed_current_video['video_time'] = 0
        parsed_current_video['status'] = VideoStatus.PAUSING

        pusher.trigger(room_id, PusherEvent.PROCEED, parsed_current_video)
        video_engine.set_online_users_video_status(room_id,
                                                   VideoStatus.PAUSING)

    return jsonify({
        'message': 'Video added to room successfully',
        'data': VideoSchema().dump(new_video).data
    })
Esempio n. 5
0
def participant_exit_room(room_id, **kwargs):
    user = kwargs['user']
    room = db.session.query(Room).filter_by(id=room_id).first()
    if room is None:
        raise Error(StatusCode.BAD_REQUEST, 'Invalid room id')

    participant = db.session.query(RoomParticipant).filter_by(
        user_id=user.id, room_id=room_id).first()
    if participant.status == ParticipantStatus.IN:
        participant.status = ParticipantStatus.OUT
        db.session.commit()

        notification = {"name": user.name, "user_id": user.id, "room": room_id}

        pusher.trigger(room_id, PusherEvent.EXIT_PARTICIPANT, notification)

        return jsonify({'message': 'Participant exited successfully'}), 200
    raise Error(StatusCode.UNAUTHORIZED, 'participant failed to exit')
Esempio n. 6
0
def _handle_member_removed(data):
    channel_name = data['channel']
    room_id = parse_channel_name(channel_name)
    user_id = data['user_id']
    participant = RoomParticipant.query \
        .join(User, User.id == RoomParticipant.user_id) \
        .filter(RoomParticipant.user_id == user_id) \
        .filter(RoomParticipant.room_id == room_id) \
        .one_or_none()

    if participant and participant.status != ParticipantStatus.DELETED:
        data = {
            'user_id': participant.user.id,
            'name': participant.user.name,
            'email': participant.user.email
        }
        trigger(room_id, PusherEvent.EXIT_PARTICIPANT, data)
        participant.status = ParticipantStatus.OUT
        db.session.commit()
Esempio n. 7
0
def send_message(user, args):
    room_id = args['room_id']

    participant = db.session.query(RoomParticipant).filter_by(
        room_id=args['room_id'], user_id=user.id).first()
    if participant.status != ParticipantStatus.IN:
        raise Error(StatusCode.FORBIDDEN, message='Invalid room access')

    message = Message(user_id=user.id, **args)
    db.session.add(message)
    db.session.commit()

    data = {
        'user_id': user.id,
        'username': user.name,
        'room_id': room_id,
        'content': args['content']
    }
    pusher.trigger(room_id, PusherEvent.NEW_MESSAGE, data)

    return jsonify({
        'message': 'Message added successfully',
        'data': MessageSchema().dump(message).data
    }), 200
Esempio n. 8
0
def update_video_status(room_id, user, args):
    status = args['status']

    room = Room.query.filter(Room.id == room_id).one()

    # Limit user from seeking or pausing video in a room
    if not room.current_video:
        raise Error(StatusCode.BAD_REQUEST,
                    'There is no current media in this room')

    meta_data = {'room': room_id, 'video': room.current_video, 'user': user.id}
    rlimit = RateLimit(10, 3 * 60, meta_data)
    if status in (VideoStatus.SEEKING, VideoStatus.PAUSING):
        if rlimit.is_over_limit:
            raise Error(
                StatusCode.FORBIDDEN,
                'You have been seeking or pausing too many times recently')

        rlimit.increase()

    if status == VideoStatus.READY:
        # Only play video when all members are ready
        room_member = RoomParticipant.query.filter(RoomParticipant.room_id == room_id) \
                                            .filter(RoomParticipant.user_id == user.id) \
                                            .one()
        room_member.video_status = VideoStatus.READY
        res = {
            'message': 'Waiting for other members to be ready',
        }
        if video_engine.check_all_user_have_same_video_status(
                room_id, VideoStatus.READY):
            current_video = video_engine.get_current_video(room_id)
            event_data = {
                'event': VideoStatus.PLAYING,
                'data': VideoSchema().dump(current_video).data
            }
            pusher.trigger(room_id, PusherEvent.VIDEO_STATUS_CHANGED,
                           event_data)
            video_engine.set_online_users_video_status(room_id,
                                                       VideoStatus.PLAYING)
            room.status = VideoStatus.PLAYING

    if status == VideoStatus.PLAYING:
        # Force all members to play video
        room.video_time = args['video_time']
        room.status = status
        video_engine.set_online_users_video_status(room_id,
                                                   VideoStatus.PLAYING)
        current_song = video_engine.get_current_video(room_id)
        event_data = {
            'event': VideoStatus.PLAYING,
            'data': VideoSchema().dump(current_song).data
        }
        pusher.trigger(room_id, PusherEvent.VIDEO_STATUS_CHANGED, event_data)
        res = {'message': 'Play video'}
    if status == VideoStatus.PAUSING:
        # Force all members to pause
        room.video_time = args['video_time']
        room.status = status
        video_engine.set_online_users_video_status(room_id,
                                                   VideoStatus.PAUSING)
        current_song = video_engine.get_current_video(room_id)
        event_data = {
            'event': VideoStatus.PAUSING,
            'data': VideoSchema().dump(current_song).data
        }
        pusher.trigger(room_id, PusherEvent.VIDEO_STATUS_CHANGED, event_data)
        res = {'message': 'Pause video'}
    if status == VideoStatus.SEEKING:
        # If someone seek videos, pause video at that time, and wait for all members to be ready
        room.video_time = args['video_time']
        room.status = VideoStatus.PAUSING
        video_engine.set_online_users_video_status(room_id,
                                                   VideoStatus.PAUSING)
        current_song = video_engine.get_current_video(room_id)
        event_data = {
            'event': VideoStatus.SEEKING,
            'data': VideoSchema().dump(current_song).data
        }
        pusher.trigger(room_id, PusherEvent.VIDEO_STATUS_CHANGED, event_data)
        res = {'message': 'Seek video'}
    if status == VideoStatus.FINISHED:
        room_member = RoomParticipant.query.filter(RoomParticipant.room_id == room_id) \
            .filter(RoomParticipant.user_id == user.id) \
            .one()

        room.video_time = args['video_time']
        room_member.video_status = VideoStatus.FINISHED

        # If all members are finished their current video, then choose next song to play
        if video_engine.check_all_user_have_same_video_status(
                room_id, VideoStatus.FINISHED):
            current_song = Video.query.filter(
                Video.id == room.current_video).one()
            current_song.status = VideoStatus.FINISHED

            video_engine.set_online_users_video_status(room_id,
                                                       VideoStatus.PAUSING)
            next_video = video_engine.set_current_video(room_id)
            parsed_next_video = VideoSchema().dump(next_video).data
            if parsed_next_video:
                parsed_next_video['video_time'] = 0
                parsed_next_video['status'] = VideoStatus.PAUSING
            pusher.trigger(room_id, PusherEvent.PROCEED, parsed_next_video)

        res = {'message': 'Wait for other member to finish their video'}

    db.session.commit()
    return jsonify(res)