def list_games(platform: str) -> Iterator[Game]: """ Given a supported platform it will provide an iterator of with a subset of data for all games found in the listing service Nintendo of America. Game data --------- * title: str * region: str (NA) * platform: str * nsuid: str (optional) * description: str * free_to_play: bool * genres: List[str] * na_slug: str * players: int * publisher: str * release_date : datetime Parameters ---------- platform: str Valid nintendo platform. Returns ------- Iterator[classes.nintendeals.games.Game]: Partial information of a game provided by NoA. """ for data in search_games(platform=platform): game = Game( title=data["title"], region=NA, platform=platform, nsuid=data.get("nsuid"), ) game.na_slug = data["slug"] game.genres = data.get("categories", []) try: release_date = data["releaseDateMask"].split("T")[0] game.release_date = datetime.strptime(release_date, '%Y-%m-%d') except ValueError: pass try: game.players = int(re.sub(r"[^\d]*", "", data["players"])) except ValueError: game.players = 0 game.description = data.get("description") game.free_to_play = data.get("msrp") == 0.0 game.publisher = data.get("publishers", [None])[0] yield game
def list_games(platform: str) -> Iterator[Game]: """ Given a supported platform it will provide an iterator of with a subset of data for all games found in the listing service Nintendo of Japan. Game data --------- * title: str * region: str (JP) * platform: str * nsuid: str * product_code: str * developer: str * free_to_play: bool * release_date: datetime Parameters ---------- platform: str Valid nintendo platform. Returns ------- Iterator[classes.nintendeals.games.Game]: Partial information of a game provided by NoJ. """ if not platform in FILENAMES: raise UnsupportedPlatform(platform) url = LISTING_URL.format(platform=FILENAMES.get(platform)) response = requests.get(url) games_data = xmltodict.parse(response.text)['TitleInfoList']['TitleInfo'] for data in games_data: game = Game( title=data["TitleName"], region=JP, platform=platform, nsuid=data["LinkURL"].split("/")[-1], product_code=data["InitialCode"], ) game.developer = data.get("MakerName") game.free_to_play = data.get("Price") == "無料" try: game.release_date = datetime.strptime(data.get('SalesDate'), '%Y.%m.%d') except: return None yield game
def test_get_price(self, nsuid, region, country, currency, value): game = Game( title="title", region=region, platform=SWITCH, nsuid=nsuid, ) price = game.price(country) self.assertEqual(nsuid, price.nsuid) self.assertEqual(country, price.country) self.assertEqual(currency, price.currency) self.assertEqual(value, price.value)
def _scrap(url: str) -> Game: response = requests.get(url, allow_redirects=True) soup = BeautifulSoup(response.text, features="html.parser") script = next((s for s in soup.find_all("script") if "var NXSTORE = NXSTORE || {};" in str(s))) json_data = next((line for line in str(script).split("\n") if "NXSTORE.titleDetail.jsonData = " in line)) data = json.loads( json_data.replace("NXSTORE.titleDetail.jsonData = ", "")[:-1]) nsuid = str(data["id"]) extra_info = _get_extra_info(nsuid) if extra_info["nsuid"] != nsuid: raise NsuidMismatch((nsuid, extra_info["nsuid"])) platform = data["platform"]["name"] product_code = f"{extra_info['hard'].replace('1_', '')}{extra_info['icode']}" game = Game( nsuid=nsuid, product_code=product_code, title=data["formal_name"], region=JP, platform=PLATFORMS[platform], ) # Genres game.genres = data.get("genre", "").split(" / ") game.genres.sort() # Languages game.languages = list( map(lambda lang: lang["name"], data.get("languages", []))) game.languages.sort() # Players try: game.players = max(data.get("player_number", {}).values()) except ValueError: game.players = 0 # Release date try: release_date = data["release_date_on_eshop"] game.release_date = datetime.strptime(release_date, '%Y-%m-%d') except ValueError: pass # Game size (in MBs) game.size = round(data.get("total_rom_size", 0) / 1024 / 1024) # Other properties features = list(map(lambda lang: lang["name"], data.get("features", []))) game.amiibo = extra_info.get("amiibo", "0") == "1" game.demo = len(data.get("demos", [])) > 0 game.description = data["description"] game.developer = extra_info["maker"] game.dlc = data.get("has_aoc", False) game.free_to_play = extra_info.get("dprice") == 0.0 game.game_vouchers = len(data.get("included_pretickets", [])) > 0 game.iaps = data.get("in_app_purchase", False) game.local_multiplayer = data["player_number"].get("local_min", 0) > 0 game.online_play = "Nintendo Switch Online" in features game.publisher = data["publisher"]["name"] game.save_data_cloud = data.get("cloud_backup_type") == "supported" # Unknown game.voice_chat = None return game
def list_games(platform: str) -> Iterator[Game]: """ Given a supported platform it will provide an iterator of with a subset of data for all games found in the listing service Nintendo of Europe. Game data --------- * title: str * region: str (EU) * platform: str * nsuid: str (optional) * product_code: str (optional) * amiibo: bool * demo: bool * developer: str * dlc: bool * free_to_play: bool * game_vouchers: bool * genres: List[str] * languages: List[str] * local_multiplayer: bool * online_play: bool * players: int * publisher: str * release_date: datetime * save_data_cloud: bool * voice_chat: bool Parameters ---------- platform: str Valid nintendo platform. Returns ------- Iterator[classes.nintendeals.games.Game]: Partial information of a game provided by NoE. """ assert platform in SYSTEM_NAMES system_name = SYSTEM_NAMES[platform] rows = 200 start = -rows while True: start += rows params = { "q": "*", "wt": "json", "sort": "title asc", "start": start, "rows": rows, "fq": f"type:GAME AND system_names_txt:\"{system_name}\"" } response = requests.get(url=LISTING_URL, params=params) json = response.json().get('response').get('docs', []) if not len(json): break for data in json: game = Game( title=data["title_extras_txt"][0], region=EU, platform=platform, nsuid=data.get("nsuid_txt", [None])[0], product_code=data.get("product_code_txt", [None])[0], ) game.genres = data.get("pretty_game_categories_txt", []) game.players = data.get("players_to") game.languages = list( map(lambda lang: lang.title(), data.get("language_availability", []))) try: release_date = data["dates_released_dts"][0].split("T")[0] game.release_date = datetime.strptime(release_date, '%Y-%m-%d') except ValueError: pass game.amiibo = data.get("near_field_comm_b", False) game.demo = data.get("demo_availability", False) game.developer = data.get("developer") game.dlc = data.get("dlc_shown_b", False) game.free_to_play = data.get("price_regular_f") == 0.0 game.game_vouchers = data.get("switch_game_voucher_b", False) game.local_multiplayer = data.get("local_play", False) game.online_play = data.get("internet", False) game.publisher = data.get("publisher") game.save_data_cloud = data.get("cloud_saves_b", False) game.voice_chat = data.get("voice_chat_b", False) yield game
def _scrap(url: str) -> Game: response = requests.get(url, allow_redirects=True) soup = BeautifulSoup(response.text, features="html.parser") scripts = list(filter(lambda s: "window.game" in str(s), soup.find_all('script'))) if not scripts: return None script = scripts[0] lines = [line.strip().replace("\",", "") for line in str(script).split("\n") if ':' in line] data = dict(map(lambda line: line.split(': "'), lines)) platform = data["platform"] game = Game( nsuid=data["nsuid"], product_code=data["productCode"], title=_unquote(data["title"]), region=NA, platform=PLATFORMS[platform], ) # Genres game.genres = _unquote(data["genre"]).split(",") game.genres.sort() # Languages game.languages = _class(soup, "languages").split(",") game.languages.sort() # Players try: game.players = int(re.sub(r"[^\d]*", "", _class(soup, "num-of-players"))) except (ValueError, TypeError): game.players = 0 # Release date try: release_date = _itemprop(soup, "releaseDate") game.release_date = datetime.strptime(release_date, '%b %d, %Y') except ValueError: pass # Game size (in MBs) game.size = _itemprop(soup, "romSize") if game.size: game.size, unit = game.size.split(" ") game.size = round(float(game.size) * (1024 if unit == "GB" else 1)) # Other properties game.demo = _aria_label(soup, "Download game demo opens in another window.") is not None game.description = _itemprop(soup, "description", tag="div") game.developer = _itemprop(soup, "manufacturer") game.dlc = _class(soup, "dlc", tag="section") is not None game.free_to_play = data["msrp"] == '0' game.game_vouchers = _aria_label(soup, "Eligible for Game Vouchers") is not None game.online_play = _aria_label(soup, "online-play") is not None game.publisher = _unquote(data["publisher"]) game.save_data_cloud = _aria_label(soup, "save-data-cloud") is not None game.na_slug = _unquote(data["slug"]) # Unknown game.amiibo = None game.iaps = None game.local_multiplayer = None game.voice_chat = None return game
def _scrap(url: str) -> Game: response = requests.get(url, allow_redirects=True) soup = BeautifulSoup(response.text, features="html.parser") scripts = list(filter(lambda s: "var nsuids = [" in str(s), soup.find_all('script'))) if not scripts: return None script = scripts[0] lines = [line.strip().replace("\",", "") for line in str(script).split("\n") if ':' in line] data = {} for line in lines: split = line.split(": \"") if len(split) != 2: continue data[split[0].replace("\"", "")] = split[1].replace("\"", "") platform = data["systemTypeMasterSystem"] game = Game( nsuid=data["nsuid"], product_code=data["productCode"], title=soup.find("h1").text, region=EU, platform=PLATFORMS[platform], ) # Genres game.genres = list(map(lambda g: g.strip(), _sibling(soup, string="Categories").split(","))) game.genres.sort() # Languages game.languages = _sibling(soup, string="Languages").split(",") game.languages.sort() # Players try: text = _sibling(soup, "Players") game.players = max(map(int, text.split(" - "))) except (AttributeError, ValueError): game.players = 0 # Release date try: release_date = data["releaseDate"] game.release_date = datetime.strptime(release_date, '%d/%m/%Y') except ValueError: pass # Game size (in MBs) game.size = _sibling(soup, "Download size") if game.size: game.size, unit = game.size.split(" ") game.size = round(float(game.size)) # Other properties features = _sibling(soup, string="Features") game.amiibo = "amiibo" in features game.demo = "Demo available" in features game.description = soup.find("div", class_="col-xs-12 content").text.strip() game.developer = _sibling(soup, "Developer") game.dlc = "Downloadable content" in features game.free_to_play = "\"offdeviceProductPrice\": \"0.0\"" in response.text game.iaps = "Offers in-game purchases" in response.text game.local_multiplayer = "Local multiplayer" in features game.online_play = "Paid online membership service" in features game.publisher = _sibling(soup, "Publisher") game.save_data_cloud = "Save Data Cloud" in features game.voice_chat = "Voice Chat" in features # Unknown game.game_vouchers = None return game