def block(room_number, userId): """ Block an existing user from entering a party\n User is blocked according to IP :param room_number:\n :param userId:\n :return: json{Status} """ #get user member = DBUtils.get_member(userId, room_number) if member is None: return Response.responseFailure( "User is not a member of this party room.") else: member = member[userId] #block user IP to block result = DBUtils.block_member(userId, member['IP'], member['nickname'], room_number) if result: #kick user out result = DBUtils.delete_member(userId, room_number) if result: return Response.responseSuccess( "Kicked user successfully. Blocked user " + member['nickname'] + ".") return Response.responseFailure("Failed to block user.")
def dequeue_song(self, room_number, url, name=None, master_id=None): # TODO - change when master is known original_master = '' master_id='test' if master_id is not None: original_master = DBUtils.get_master(room_number) # TODO - uncomment once the master_id is on # if original_master != master_id: # msg = 'Not a master to dequeue' # return False, None, None, msg history, queue = DBUtils.get_all_songs(room_number) if url in queue: song = queue[url] del queue[url] history[url] = song else: msg = 'Song does not exist in queue' return False, history, queue, msg is_successful, history, queue = DBUtils.update_song_lists(room_number, history, queue) if is_successful: return True, history, queue, None else: msg = 'Something went wrong! please try again' return False, history, queue, msg
def enqueue_song(room_number, url, name, duration, userId): url = SecurityUtils.encrypt_url(url) room = DBUtils.get_room(room_number) queue = room['queue'] # Assume a song does not exist exists = False if url in queue: exists = True queue_list = QueueModerator.sort_pending_songs(queue) return False, queue_list song = { 'name': name, 'score': 0, # initial score is always 0 'duration': duration, 'nickname': DBUtils.get_member(userId, room_number)[userId]['nickname'], 'userId': userId } result = DBUtils.enqueue_song(room['_id'], url, song, len(queue.keys()) + 1) unsorted_queue = DBUtils.get_pending_songs(room_number) queue_list = QueueModerator.sort_pending_songs(unsorted_queue) return result, queue_list
def upvote_song(room_number, url, cookie): user_id = SecurityUtils.get_userId(cookie) url = SecurityUtils.encrypt_url(url) pending_songs = DBUtils.get_pending_songs(room_number) # Check if a song is in the queue/pending songs if url not in pending_songs: return False, ErrorMsg.NO_SONG.value songs = DBUtils.get_votes_per_user(room_number, user_id) if url not in songs: result = DBUtils.upvote(room_number, url, user_id) msg = 'Something went wrong, please vote again!' pending_songs = DBUtils.get_pending_songs(room_number) sorted_queue = QueueModerator.sort_pending_songs(pending_songs) return (True, sorted_queue, None) if result else (False, sorted_queue, msg) elif songs[url]: sorted_queue = QueueModerator.sort_pending_songs(pending_songs) msg = 'User has already voted for this song' return False, sorted_queue, msg sorted_queue = QueueModerator.sort_pending_songs(pending_songs) return False, sorted_queue, None
def checkUser(roomId, cookie, master=False): """ Checks if a given userToken represents an legitimate party room member\n It could also check if the userToken belongs to master if "master" flag is present :param roomId: room of which the user supposedly belongs to\n :param cookie: value saved on the user device in a cookie\n :optionalParam master: True - check against master instead of regular user\n :returns: if verified - success, else - failure """ #parse the cookie userId = token = mac = '' parts = cookie.split(':') if len(parts) == 3: userId = parts[0] token = parts[1] mac = parts[2] else: return False #check cookie integrity if SecurityUtils.generateCookie(userId, token) == cookie: #check is cookie not fake if master: user = DBUtils.get_master(roomId) return user is not None and userId in user and token == user[ userId] # check if tokens match else: user = DBUtils.get_member(userId, roomId) return user is not None and userId in user and token == user[ userId]['token'] return False
def join_room(room_number, nickname, ip): """ Register a new user\n Generates users id, computes it's secret token, saves it in database\n :param room_number:\n :param nickname: \n :param ip: \n :return: json{Status, [UserCookie]} """ #do not allow blocked IP users join blocked_members = DBUtils.get_fields(room_number, ['blocked_members']) if blocked_members is not None: blocked_members = blocked_members[0]['blocked_members'] ips = [] for userId in blocked_members: ips.append(blocked_members[userId]['IP']) if ip in ips: return Response.responseFailure( "Blocked from entering this party room") #get unique ID try: # print("pre user ID") userId = DBUtils.generateUniqueId(Purpose.USER, room_number) # print("after UserID has been assigned") result = userId except ValueError as error: return Response.responseFailure("Room does not exist") token = SecurityUtils.generateToken() user = { userId: { 'nickname': nickname, 'token': token, 'IP': ip, 'songs': {} }, } #save in database result = DBUtils.add_member(room_number, user) if result: #generate user identifiers cookie = SecurityUtils.generateCookie(userId, token) return Response.responseSuccess({ "UserCookie": cookie, "UserId": userId, "SpotifySearchToken": TokenModerator.get_client_credentials_token(), "YoutubeSearchToken": config.TOKEN_KEYS['YOUTUBE_DATA_API'] }) else: return Response.responseFailure("Failed to add new party member")
def create_room(): ''' :return: if successful - True, room object; else - False, {}, message # return: response message, either success or failure which holds a room object with the following fields: # queue - dictionary/json object with pending songs # history - dictionary/json object with played songs # searchToken - search token (TODO) # accessToken - access token (TODO) # master - id of creator of room (TODO) # users - list with user ids and their votes # return json response with room if it's created, otherwise empty object and a failure message ''' userId = DBUtils.generateUniqueId(Purpose.USER) token = SecurityUtils.generateToken() cookie = SecurityUtils.generateCookie(userId, token) spotify_search_token = TokenModerator.get_client_credentials_token() youtube_key = TokenModerator.get_youtube_search_key() room_obj = { # '_id': DBUtils.generateUniqueId(Purpose.ROOM), '_id': DBUtils.generateFourSymbolId(), 'master': {userId: token}, 'SpotifySearchToken': spotify_search_token, 'YoutubeSearchToken': youtube_key, 'head': None, 'queue': {}, 'history': {}, # played songs 'users': { userId:{ 'nickname': 'Master', 'token': token, 'IP': "localhost", 'songs': {} #master does not have 'blocked' field on purpose } }, 'blocked_members':{} } #@think is it ok to return values as head, users, master, _id as those are not needed result = DBUtils.create_room(room_obj) # cookie to identify the master room_obj.update({'MasterCookie': cookie}) if result: return True, room_obj, None else: msg = 'Room was not created' return False, {}, msg
def enqueue_song(self, room_number, url, name): room = DBUtils.get_room(room_number) queue = room['queue'] # Assume a song does not exist exists = False if url in queue: exists = True return False, queue queue[url] = { 'name': name, 'score': 0 # initial score is always 0 } result, queue = DBUtils.enqueue_song(room['_id'], queue) return result, queue
def delete_room(roomId): ''' DESTROY EXISTING ROOM AND ALL IT"S DATA\n Used as cleanup after the party happened and non of existing information is needed anymore\n :param roomId - id of the room to be destroyed\n :return Success/Failure json ''' # no checks are required due to use of MiddlewareUtils in main.py return DBUtils.delete_room(roomId)
def dequeue_song(room_number): is_successful, dequeued_song, msg = DBUtils.dequeue_song(room_number) history, unsorted_queue = DBUtils.get_all_songs(room_number) queue = QueueModerator.sort_pending_songs(unsorted_queue) history = QueueModerator.decrypt_urls(history) decrypted_song = None if dequeued_song is not None: for x in dequeued_song.keys(): decrypted_song = dequeued_song[x] decrypted_song['url'] = SecurityUtils.decrypt_url(x) break if is_successful: return True, history, queue, decrypted_song, None else: return False, history, queue, decrypted_song, msg.value
def remove_song(room_number, url): url = SecurityUtils.encrypt_url(url) is_successful, unsorted_queue = DBUtils.remove_song(room_number, url) sorted_queue = QueueModerator.sort_pending_songs(unsorted_queue) if is_successful: return True, sorted_queue, None else: return False, sorted_queue, ErrorMsg.NOT_REMOVED.value
def pending_songs(room_number): # print("whats going on") try: unsorted_queue = DBUtils.get_pending_songs(room_number) # possible type error - idk if unsorted_queue is of type dict sorted_queue = QueueModerator.sort_pending_songs(unsorted_queue) return True, sorted_queue except: return False, []
def kick(room_number, userId): """ Kick a user from party\n User can still reenter the party using the link :param room_number:\n :param userId:\n :return: json{Status} """ result = DBUtils.delete_member(userId, room_number) return result
def unvote_song(room_number, url, cookie): user_id = SecurityUtils.get_userId(cookie) url = SecurityUtils.encrypt_url(url) pending_songs = DBUtils.get_pending_songs(room_number) # Check if a song is in the queue/pending songs if url not in pending_songs: sorted_queue = QueueModerator.sort_pending_songs(pending_songs) return False, sorted_queue, ErrorMsg.NO_SONG.value songs = DBUtils.get_votes_per_user(room_number, user_id) if url not in songs or songs[url] == 0: sorted_queue = QueueModerator.sort_pending_songs(pending_songs) return False, sorted_queue, ErrorMsg.NO_VOTE.value result, err = DBUtils.unvote(room_number, url, user_id) pending_songs = DBUtils.get_pending_songs(room_number) sorted_queue = QueueModerator.sort_pending_songs(pending_songs) if result: return True, sorted_queue, None else: return False, sorted_queue, err.value
def unblock(room_number, userId): """ Unblock a user\n Look at router.unblock for more detail\n :param room_number:\n :param userId:\n :return: json{Status} """ #unblock user result = DBUtils.unblock_member(userId, room_number) if result: return Response.responseSuccess("Unblocked user IP successfully.") return Response.responseFailure("Failed to block user.")
def create_room(self, room_number): room_obj = { 'id': room_number, 'searchToken': '', # TODO - add script to acquire token 'accessToken': '', # TODO - add script to acquire token 'queue': {}, 'history': {}, # played songs 'users': [], 'master': '' # TODO - add master's URL } result, room = DBUtils.create_room(room_obj) if result: return True, room, None else: msg = 'Room was not created, please try another ID' return False, {}, msg
def get_members(room_number): """ Get the list of all party members\n :param room_number:\n :return: json{Status, users:{party_members_data}} """ fields = ['users'] users = DBUtils.get_fields(room_number, fields) result = False for u in users: result = u['users'] if result is not False: return Response.responseSuccess(result) else: return Response.responseFailure("Failed to retrieve users list.")
def get_blocked_members(room_number): """ Get the list of blocked party members\n :param room_number:\n :return: json{Status, 'blocked_members':{}} """ fields = ['blocked_members'] users = DBUtils.get_fields(room_number, fields) result = False for u in users: result = u['blocked_members'] break if result is not False: return Response.responseSuccess(result) else: return Response.responseFailure( "Failed to retrieve block members list.")
def generate_nickname(room_number): ''' Generates a unique nickname for a specific room\n :param room_number: \n :return: string nickname ''' nickname = '' while True: response = requests.post("https://api.codetunnel.net/random-nick", json={ 'sizelimit': '20' }).json() if response[ 'success']: #make sure this doesn't enter infinite loop nickname = response['nickname'] else: return "" if DBUtils.nicknameUnique(room_number, nickname): break return nickname
def get_currently_playing(room_number): try: currently_playing = DBUtils.get_currently_playing(room_number) return True, currently_playing except: return False, None
def played_songs(room_number): history = DBUtils.get_played_songs(room_number) history = QueueModerator.decrypt_urls(history) return history