def __profile_request(self, game: str, version: int, userid: UserID, exact: bool) -> Optional[ValidatedDict]: # First, get or create the extid/refid for this virtual user cardid = RemoteUser.userid_to_card(userid) refid = self.user.get_refid(game, version, userid) extid = self.user.get_extid(game, version, userid) profiles = Parallel.flatten(Parallel.call( [client.get_profiles for client in self.clients], game, version, APIConstants.ID_TYPE_CARD, [cardid], )) for profile in profiles: cards = [card.upper() for card in profile.get('cards', [])] if cardid in cards: # Sanitize the returned data profile = copy.deepcopy(profile) del profile['cards'] exact_match = profile.get('match', 'partial') == 'exact' if exact and (not exact_match): # This is a partial match, not for this game/version continue if 'match' in profile: del profile['match'] # Add in our defaults we always provide profile['game'] = game profile['version'] = version if exact_match else 0 profile['refid'] = refid profile['extid'] = extid return self.__format_profile(ValidatedDict(profile)) return None
def __get_cardids(self, userid: UserID) -> List[str]: if RemoteUser.is_remote(userid): return [RemoteUser.userid_to_card(userid)] else: return self.user.get_cards(userid)
def get_any_profiles(self, game: str, version: int, userids: List[UserID]) -> List[Tuple[UserID, Optional[ValidatedDict]]]: if len(userids) == 0: return [] remote_ids = [ userid for userid in userids if RemoteUser.is_remote(userid) ] local_ids = [ userid for userid in userids if not RemoteUser.is_remote(userid) ] if len(remote_ids) == 0: # We only have local profiles here, just pass on to the underlying layer return self.user.get_any_profiles(game, version, local_ids) else: # We have to fetch some local profiles and some remote profiles, and then # merge them together card_to_userid = { RemoteUser.userid_to_card(userid): userid for userid in remote_ids } local_profiles, remote_profiles = Parallel.execute([ lambda: self.user.get_any_profiles(game, version, local_ids), lambda: Parallel.flatten(Parallel.call( [client.get_profiles for client in self.clients], game, version, APIConstants.ID_TYPE_CARD, [RemoteUser.userid_to_card(userid) for userid in remote_ids], )) ]) for profile in remote_profiles: cards = [card.upper() for card in profile.get('cards', [])] for card in cards: # Map it back to the requested user userid = card_to_userid.get(card) if userid is None: continue # Sanitize the returned data profile = copy.deepcopy(profile) del profile['cards'] exact_match = profile.get('match', 'partial') == 'exact' if 'match' in profile: del profile['match'] refid = self.user.get_refid(game, version, userid) extid = self.user.get_extid(game, version, userid) # Add in our defaults we always provide profile['game'] = game profile['version'] = version if exact_match else 0 profile['refid'] = refid profile['extid'] = extid local_profiles.append( (userid, self.__format_profile(ValidatedDict(profile))), ) # Mark that we saw this card/user del card_to_userid[card] # Finally, mark all missing remote profiles as None for card in card_to_userid: local_profiles.append((card_to_userid[card], None)) return local_profiles
def test_id_mangling(self) -> None: card = "E0040100DEADBEEF" userid = RemoteUser.card_to_userid(card) self.assertTrue(userid > (2**32 - 1)) newcard = RemoteUser.userid_to_card(userid) self.assertEqual(card, newcard)