diff --git a/backend/handler/metadata/hasheous_handler.py b/backend/handler/metadata/hasheous_handler.py index 93848d492..2a6f35b35 100644 --- a/backend/handler/metadata/hasheous_handler.py +++ b/backend/handler/metadata/hasheous_handler.py @@ -249,7 +249,14 @@ class HasheousHandler(MetadataHandler): for meta in metadata: if meta["source"] == "IGDB": - igdb_id = meta["immutableId"] + try: + # TEMP: Hasheous is slowly replacing slugs with IDs + igdb_id = int(meta["immutableId"]) + except (ValueError, TypeError): + log.debug( + f"Found an IGDB slug instead of an ID: {meta['immutableId']}" + ) + pass elif meta["source"] == "TheGamesDB": tgdb_id = meta["immutableId"] elif meta["source"] == "RetroAchievements": diff --git a/backend/handler/metadata/igdb_handler.py b/backend/handler/metadata/igdb_handler.py index 0f3a66b9f..054f866e7 100644 --- a/backend/handler/metadata/igdb_handler.py +++ b/backend/handler/metadata/igdb_handler.py @@ -515,7 +515,7 @@ class IGDBHandler(MetadataHandler): "Searching for %s on IGDB without game_Type after splitting semicolon", term, ) - rom = await self._search_rom(term, platform_igdb_id) + rom = await self._search_rom(term.strip(), platform_igdb_id) if rom: break diff --git a/backend/handler/metadata/ss_handler.py b/backend/handler/metadata/ss_handler.py index 6547e17aa..c91b87dea 100644 --- a/backend/handler/metadata/ss_handler.py +++ b/backend/handler/metadata/ss_handler.py @@ -273,11 +273,31 @@ class SSHandler(MetadataHandler): if not platform_ss_id: return None + def is_exact_match(rom: SSGame, search_term: str) -> bool: + rom_names = [name.get("text", "").lower() for name in rom.get("noms", [])] + search_term_lower = search_term.lower() + search_term_normalized = self._normalize_exact_match(search_term) + + return any( + ( + rom_name.lower() == search_term_lower + or self._normalize_exact_match(rom_name) == search_term_normalized + ) + for rom_name in rom_names + ) + + print(f"Search term: {search_term}") search_term = uc(search_term) + print(f"Normalized search term: {search_term}") roms = await self.ss_service.search_games( term=quote(search_term, safe="/ "), system_id=platform_ss_id, ) + + for rom in roms: + if is_exact_match(rom, search_term): + return rom + return roms[0] if roms else None def get_platform(self, slug: str) -> SSPlatform: @@ -361,9 +381,19 @@ class SSHandler(MetadataHandler): search_term = await self._mame_format(search_term) fallback_rom = SSRom(ss_id=None, name=search_term) + print(f"Searching for ROM: {search_term} on platform ID: {platform_ss_id}") + search_term = self.normalize_search_term(search_term) + print(f"Normalized search term: {search_term}") res = await self._search_rom(search_term, platform_ss_id) + # Split the search term since igdb struggles with colons + if not res and ":" in search_term: + for term in search_term.split(":")[::-1]: + res = await self._search_rom(term.strip(), platform_ss_id) + if res: + break + # Some MAME games have two titles split by a slash if not res and "/" in search_term: for term in search_term.split("/"): diff --git a/backend/handler/scan_handler.py b/backend/handler/scan_handler.py index 6732d3b54..24b560932 100644 --- a/backend/handler/scan_handler.py +++ b/backend/handler/scan_handler.py @@ -520,16 +520,16 @@ async def scan_rom( ) # Only update fields if match is found - if hasheous_handler_rom.get("hasheous_id"): - rom_attrs.update({**hasheous_handler_rom}) + if launchbox_handler_rom.get("launchbox_id"): + rom_attrs.update({**launchbox_handler_rom}) if ra_handler_rom.get("ra_id"): rom_attrs.update({**ra_handler_rom}) if moby_handler_rom.get("moby_id"): rom_attrs.update({**moby_handler_rom}) - if launchbox_handler_rom.get("launchbox_id"): - rom_attrs.update({**launchbox_handler_rom}) if ss_handler_rom.get("ss_id"): rom_attrs.update({**ss_handler_rom}) + if hasheous_handler_rom.get("hasheous_id"): + rom_attrs.update({**hasheous_handler_rom}) if igdb_handler_rom.get("igdb_id"): rom_attrs.update({**igdb_handler_rom}) diff --git a/backend/tasks/scan_library.py b/backend/tasks/scan_library.py index 4dd3a905b..78a86fe61 100644 --- a/backend/tasks/scan_library.py +++ b/backend/tasks/scan_library.py @@ -21,7 +21,7 @@ class ScanLibraryTask(PeriodicTask): return log.info("Scheduled library scan started...") - await scan_platforms([], scan_type=ScanType.UNIDENTIFIED) + await scan_platforms([], scan_type=ScanType.UNIDENTIFIED, metadata_sources=[]) log.info("Scheduled library scan done") diff --git a/frontend/src/views/Auth/Setup.vue b/frontend/src/views/Auth/Setup.vue index 570f7747b..2c0b5b67f 100644 --- a/frontend/src/views/Auth/Setup.vue +++ b/frontend/src/views/Auth/Setup.vue @@ -49,6 +49,12 @@ const metadataOptions = computed(() => [ logo_path: "/assets/scrappers/ra.png", disabled: !heartbeat.value.METADATA_SOURCES?.RA_API_ENABLED, }, + { + name: "Hasheous", + value: "hasheous", + logo_path: "/assets/scrappers/hasheous.png", + disabled: !heartbeat.value.METADATA_SOURCES?.HASHEOUS_API_ENABLED, + }, ]); const defaultAdminUser = ref({ username: "",