def client_connect(cookie): if GAME_CODE_KEY not in session: # TODO: error handling return game_code_raw = session[GAME_CODE_KEY] game_code = GameCode(game_code_raw) if not game_store.contains_game(game_code): ErrorHandler.game_code_dne(ClientEvent.CONNECT, game_code) return game_manager = game_store.get_game(game_code) #try client, events = game_manager.handle_client_event( client_id=None, client_event=ClientEvent.CONNECT, data=cookie) #except Exception as e: # emit('error', str(e)) for event in events: event.emit() # Store the client id and game code in the session for further requests session[CLIENT_ID_KEY] = client.id # Add the client's socket to the socket room join_room(game_code) # emit an update to the clients game_manager.get_lobby_update_event().emit()
def main(): api = api_setup() error_handler = ErrorHandler(api=api) error_handler.api_test() print("Input Twitter IDs. These can be found from twitterid.com") start_user = int(input("Find a path from: ")) target_user = int(input("To: ")) method = int(input("Choose a search method. NaiveBFS (input 1) is better for low number of followings " "from the start user, whereas BidirectionalBFS (input 2) is better for similar number " "of followings and followers. ")) if method == 1: naive_obj = NaiveBFS(api) _path = naive_obj.run_search(origin_user=start_user, target_user=target_user) elif method == 2: bidirectional_obj = BidirectionalBFS(api, search_radius=1000, auto_next=True) _path = bidirectional_obj.run_search(origin_user=start_user, target_user=target_user)
def game_event_handler(game_event, data=None): try: game_code_raw, client_id = get_session_data(session) except ValueError as err: emit('error', str(err)) return game_code = GameCode(game_code_raw) if not game_store.contains_game(game_code): ErrorHandler.game_code_dne(GameEvent.UPDATE, game_code) return game_manager = game_store.get_game(game_code) #try: game, events = game_manager.handle_game_event(client_id, game_event, data) for event in events: event.emit() return game
def origin_following_bfs(self, start_user): """ If the origin follows user A and B, and user B follows C, a graph can be drown as such: Origin ---> A ---> B ----> C Every yield expands the radius of the search by 1, until it hits search_radius :param start_user: The user from which to start the search :yield: All paths possible up to the current radius, in format set({user_id: path_to_that_user_id}, etc.) """ api = self.api error_handler = ErrorHandler(api=api) queue = Queue() queue.put(start_user) visited = {start_user} path_to = defaultdict(lambda: [start_user]) _ = path_to[start_user] for current_radius in range(self.search_radius): if queue.qsize() == 0: print('Queue empty. Ending origin BFS.') return current_user = queue.get() if self.cache.read_from_cache( user_id=current_user ) is None: # current_user does not yet exist in cache current_user_followings = api.GetFriendIDs( user_id=current_user) current_user_screen_name = api.GetUser( user_id=current_user).name self.cache.append_to_cache( user_id=current_user, screen_name=current_user_screen_name, following_ids=current_user_followings) print( f"Origin BFS: requested {current_user_screen_name}'s screen name and followings from API. " f"Commencing search.") else: cached_data = self.cache.read_from_cache(user_id=current_user) current_user_screen_name = cached_data[ 'screen_name'] # if user_id exists as a key in cache, # screen_name will always exist as well if not cached_data[ 'following']: # i.e. following list does not yet exist in cache current_user_followings = api.GetFriendIDs( user_id=current_user) self.cache.append_to_cache( user_id=current_user, screen_name=current_user_screen_name, following_ids=current_user_followings) print( f"Origin BFS: retrieved {current_user_screen_name}'s screen name from cache. " f"Requested followings from API. Commencing search.") else: current_user_followings = cached_data['following'] print( f"Origin BFS: retrieved {current_user_screen_name}'s screen name AND followings from cache. " f"Today is a good day. Commencing search.") num_followings = len(current_user_followings) for num, following in enumerate(current_user_followings): if following not in visited: try: if self.cache.read_from_cache( user_id=following ) is None: # this user does not yet exist in cache following_screen_name = api.GetUser( user_id=following).name self.cache.append_to_cache( user_id=following, screen_name=following_screen_name) print( f"Origin BFS: {current_user_screen_name} follows {following_screen_name}. " f"Requested {following_screen_name}'s screen name from API and cached." ) else: following_screen_name = self.cache.read_from_cache( user_id=following)['screen_name'] print( f"Origin BFS: {current_user_screen_name} follows {following_screen_name}. " f"Retrieved {following_screen_name}'s screen name from cache." ) visited.add(following) queue.put(following) current_path = list(path_to[current_user]) current_path.extend([following]) path_to[following] = current_path except twitter.error.TwitterError as ex: error_handler.handle(ex, user_id=following) else: print('User already visited. Skipping...') print(num + 1, '/', num_followings) yield path_to
def target_follower_bfs(self, start_user): """ Same as origin_follower_bfs, but the other way round. If user A and user B follows target, and user C follows user B: C ---> B ---> target A ---> :param start_user: This refers to the target user. The user from which to start the search. :yield: All paths possible up to the current radius, in format set({user_id: path_to_that_user_id}, etc.) """ api = self.api error_handler = ErrorHandler(api=api) queue = Queue() queue.put(start_user) visited = {start_user} path_to = defaultdict(lambda: [start_user]) _ = path_to[start_user] for current_radius in range(self.search_radius): if queue.qsize() == 0: print('Queue empty. Ending target BFS.') return current_user = queue.get() if self.cache.read_from_cache( user_id=current_user ) is None: # current_user does not yet exist in cache current_user_followers = api.GetFollowerIDs( user_id=current_user) current_user_screen_name = api.GetUser( user_id=current_user).name self.cache.append_to_cache( user_id=current_user, screen_name=current_user_screen_name, follower_ids=current_user_followers) print( f"Target BFS: requested {current_user_screen_name}'s screen name and followers from API. " f"Commencing search.") else: cached_data = self.cache.read_from_cache(user_id=current_user) current_user_screen_name = cached_data[ 'screen_name'] # if user_id exists as a key in cache, # screen_name will always exist as well if not cached_data[ 'followers']: # i.e. follower list does not yet exist in cache current_user_followers = api.GetFollowerIDs( user_id=current_user) self.cache.append_to_cache( user_id=current_user, screen_name=current_user_screen_name, follower_ids=current_user_followers) print( f"Target BFS: retrieved {current_user_screen_name}'s screen name from cache. " f"Requested followers from API. Commencing search.") else: current_user_followers = cached_data['followers'] print( f"Target BFS: retrieved {current_user_screen_name}'s screen name AND followers from cache. " f"Today is a good day. Commencing search.") num_followers = len(current_user_followers) for num, follower in enumerate(current_user_followers): if follower not in visited: try: if self.cache.read_from_cache( user_id=follower ) is None: # this user does not yet exist in cache follower_screen_name = api.GetUser( user_id=follower).name self.cache.append_to_cache( user_id=follower, screen_name=follower_screen_name) print( f"Target BFS: {current_user_screen_name} is followed by {follower_screen_name}. " f"Requested {follower_screen_name}'s screen name from API and cached." ) else: follower_screen_name = self.cache.read_from_cache( user_id=follower)['screen_name'] print( f"Target BFS: {current_user_screen_name} is followed by {follower_screen_name}. " f"Retrieved {follower_screen_name}'s screen name from cache." ) visited.add(follower) queue.put(follower) current_path = list(path_to[current_user]) current_path.extend([follower]) path_to[follower] = current_path except twitter.error.TwitterError as ex: error_handler.handle(ex, user_id=follower) else: print('User already visited. Skipping...') print(num + 1, '/', num_followers) yield path_to
def bfs(self, start_user, target_user): """ Find shortest path from start_user to target_user, where a path is defined as: X --> Y when user X follows user Y. This is a horrible algorithm - don't use it unless you're willing to wait for around a week or longer if you know the degree of separation is >= 2 :param start_user: The starting (origin) user :param target_user: The user you're trying to find a path to :return: A path from start_user to target_user """ api = self.api error_handler = ErrorHandler(api=api) queue = Queue() queue.put(start_user) visited = {start_user} path_to = defaultdict(lambda: [start_user]) while queue.not_empty: current_user = queue.get() if self.cache.read_from_cache( user_id=current_user ) is None: # current_user does not yet exist in cache current_user_followings = api.GetFriendIDs( user_id=current_user) current_user_screen_name = api.GetUser( user_id=current_user).name self.cache.append_to_cache( user_id=current_user, screen_name=current_user_screen_name, following_ids=current_user_followings) print( f"Naive BFS: requested {current_user_screen_name}'s screen name and followings from API. " f"Commencing search.") else: cached_data = self.cache.read_from_cache(user_id=current_user) current_user_screen_name = cached_data[ 'screen_name'] # if user_id exists as a key in cache, # screen_name will always exist as well if not cached_data[ 'following']: # i.e. following list does not yet exist in cache current_user_followings = api.GetFriendIDs( user_id=current_user) self.cache.append_to_cache( user_id=current_user, screen_name=current_user_screen_name, following_ids=current_user_followings) print( f"Naive BFS: retrieved {current_user_screen_name}'s screen name from cache. " f"Requested followings from API. Commencing search.") else: current_user_followings = cached_data['following'] print( f"Naive BFS: retrieved {current_user_screen_name}'s screen name AND followings from cache. " f"Today is a good day. Commencing search.") num_followings = len(current_user_followings) for num, following in enumerate(current_user_followings): if following not in visited: try: if self.cache.read_from_cache( user_id=following ) is None: # this user does not yet exist in cache following_screen_name = api.GetUser( user_id=following).name self.cache.append_to_cache( user_id=following, screen_name=following_screen_name) print( f"Naive BFS: {current_user_screen_name} follows {following_screen_name}. " f"Requested {following_screen_name}'s screen name from API and cached." ) else: following_screen_name = self.cache.read_from_cache( user_id=following)['screen_name'] print( f"Naive BFS: {current_user_screen_name} follows {following_screen_name}. " f"Retrieved {following_screen_name}'s screen name from cache." ) visited.add(following) queue.put(following) current_path = list(path_to[current_user]) current_path.extend([following]) path_to[following] = current_path if following == target_user: print( f"Naive BFS: {following_screen_name} (target user) found! Stopping search." ) break except twitter.error.TwitterError as ex: error_handler.handle(ex, user_id=following) else: print('User already visited. Skipping...') print(num + 1, '/', num_followings) else: continue break if path_to[target_user] != [start_user] or target_user == start_user: return path_to[target_user] else: return None