From 9319081ff614e7fe8a16736fab371c3583bc7822 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Fri, 26 Jul 2024 22:07:59 -0300 Subject: [PATCH] fix: Return early if IGDB finds an exact match This improvement avoids extra IGDB API requests when a received Rom is an exact match. It avoids up to 2 requests per Rom, when an exact match is found. --- backend/handler/metadata/igdb_handler.py | 51 ++++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/backend/handler/metadata/igdb_handler.py b/backend/handler/metadata/igdb_handler.py index 3dc83f612..e5740ca9f 100644 --- a/backend/handler/metadata/igdb_handler.py +++ b/backend/handler/metadata/igdb_handler.py @@ -263,36 +263,43 @@ async def _search_rom( if with_category else "" ) + + def is_exact_match(rom: dict, search_term: str) -> bool: + return ( + rom["name"].lower() == search_term.lower() + or rom["slug"].lower() == search_term.lower() + or ( + self._normalize_exact_match(rom["name"]) + == self._normalize_exact_match(search_term) + ) + ) + roms = await self._request( self.games_endpoint, data=f'search "{search_term}"; fields {",".join(self.games_fields)}; where platforms=[{platform_igdb_id}] {category_filter};', ) + for rom in roms: + # Return early if an exact match is found. + if is_exact_match(rom, search_term): + return rom + roms_expanded = await self._request( self.search_endpoint, data=f'fields {",".join(self.search_fields)}; where game.platforms=[{platform_igdb_id}] & (name ~ *"{search_term}"* | alternative_name ~ *"{search_term}"*);', ) if roms_expanded: - roms.extend( - await self._request( - self.games_endpoint, - f'fields {",".join(self.games_fields)}; where id={roms_expanded[0]["game"]["id"]};', - ) + extra_roms = await self._request( + self.games_endpoint, + f'fields {",".join(self.games_fields)}; where id={roms_expanded[0]["game"]["id"]};', ) + for rom in extra_roms: + # Return early if an exact match is found. + if is_exact_match(rom, search_term): + return rom - exact_matches = [ - rom - for rom in roms - if ( - rom["name"].lower() == search_term.lower() - or rom["slug"].lower() == search_term.lower() - or ( - self._normalize_exact_match(rom["name"]) - == self._normalize_exact_match(search_term) - ) - ) - ] + roms.extend(extra_roms) - return pydash.get(exact_matches or roms, "[0]", None) + return roms[0] if roms else None @check_twitch_token async def get_platform(self, slug: str) -> IGDBPlatform: @@ -593,8 +600,8 @@ async def _update_twitch_token(self) -> str: return "" # Set token in redis to expire in seconds - sync_cache.set("romm:twitch_token", token, ex=expires_in - 10) # type: ignore[attr-defined] - sync_cache.set("romm:twitch_token_expires_at", time.time() + expires_in - 10) # type: ignore[attr-defined] + sync_cache.set("romm:twitch_token", token, ex=expires_in - 10) + sync_cache.set("romm:twitch_token_expires_at", time.time() + expires_in - 10) log.info("Twitch token fetched!") @@ -609,8 +616,8 @@ async def get_oauth_token(self) -> str: return "" # Fetch the token cache - token = sync_cache.get("romm:twitch_token") # type: ignore[attr-defined] - token_expires_at = sync_cache.get("romm:twitch_token_expires_at") # type: ignore[attr-defined] + token = sync_cache.get("romm:twitch_token") + token_expires_at = sync_cache.get("romm:twitch_token_expires_at") if not token or time.time() > float(token_expires_at or 0): log.warning("Twitch token invalid: fetching a new one...")