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 })
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 })
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')
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 })
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')
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()
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
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)