Skip to content

Commit 06eac10

Browse files
authored
Merge pull request #3368 from rommapp/copilot/fix-ra-hashes-missing-ids
fix: include games without achievements in RA hash cache
2 parents 9eecb67 + 3db3dd4 commit 06eac10

1 file changed

Lines changed: 15 additions & 21 deletions

File tree

backend/handler/metadata/ra_handler.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from adapters.services.retroachievements import RetroAchievementsService
1212
from adapters.services.retroachievements_types import (
1313
RAGameExtendedDetails,
14-
RAGameListItem,
1514
)
1615
from config import (
1716
REFRESH_RETROACHIEVEMENTS_CACHE_DAYS,
@@ -128,7 +127,7 @@ def parse_release_timestamp():
128127
class RAHandler(MetadataHandler):
129128
def __init__(self) -> None:
130129
self.ra_service = RetroAchievementsService()
131-
self.HASHES_FILE_NAME = "ra_hashes.json"
130+
self.HASHES_FILE_NAME = "ra_hashes_v2.json"
132131

133132
@classmethod
134133
def is_enabled(cls) -> bool:
@@ -174,47 +173,44 @@ async def _days_since_last_cache_file_update(self, platform_id: int) -> int:
174173
file_stat = await AnyioPath(str(full_path)).stat()
175174
return int((time.time() - file_stat.st_mtime) / (24 * 3600))
176175

177-
async def _search_rom(self, rom: Rom, ra_hash: str) -> RAGameListItem | None:
176+
async def _search_rom(self, rom: Rom, ra_hash: str) -> int | None:
178177
if not rom.platform.ra_id:
179178
return None
180179

181-
# Fetch all hashes for specific platform
182-
roms: list[RAGameListItem]
180+
# hash_index maps lowercase hash -> game ID for O(1) lookups
181+
hash_index: dict[str, int]
183182
if (
184183
REFRESH_RETROACHIEVEMENTS_CACHE_DAYS
185184
<= await self._days_since_last_cache_file_update(rom.platform.id)
186185
or not await self._exists_cache_file(rom.platform.id)
187186
):
188-
# Write the roms result to a JSON file if older than REFRESH_RETROACHIEVEMENTS_CACHE_DAYS days
187+
# Fetch all games (including those without achievements) and build index
189188
roms = await self.ra_service.get_game_list(
190189
system_id=rom.platform.ra_id,
191-
only_games_with_achievements=True,
190+
only_games_with_achievements=False,
192191
include_hashes=True,
193192
)
194193

194+
hash_index = {h.lower(): r["ID"] for r in roms for h in r.get("Hashes", ())}
195+
195196
platform_resources_path = fs_resource_handler.get_platform_resources_path(
196197
rom.platform.id
197198
)
198199

199-
json_file = json.dumps(roms, indent=4)
200+
json_file = json.dumps(hash_index, indent=4)
200201
await fs_resource_handler.write_file(
201202
json_file.encode("utf-8"),
202203
platform_resources_path,
203204
self.HASHES_FILE_NAME,
204205
)
205206
else:
206-
# Read the roms result from the JSON file
207+
# Read the hash index from the JSON file
207208
json_file_bytes = await fs_resource_handler.read_file(
208209
self._get_hashes_file_path(rom.platform.id)
209210
)
210-
roms = json.loads(json_file_bytes.decode("utf-8"))
211-
212-
ra_hash_lower = ra_hash.lower()
213-
for r in roms:
214-
if any(ra_hash_lower == h.lower() for h in r.get("Hashes", ())):
215-
return r
211+
hash_index = json.loads(json_file_bytes.decode("utf-8"))
216212

217-
return None
213+
return hash_index.get(ra_hash.lower())
218214

219215
def get_platform(self, slug: str) -> RAGamesPlatform:
220216
if slug not in RA_PLATFORM_LIST:
@@ -250,15 +246,13 @@ async def get_rom(self, rom: Rom, ra_hash: str) -> RAGameRom:
250246
if not ra_hash:
251247
return RAGameRom(ra_id=None)
252248

253-
ra_game_list_item = await self._search_rom(rom, ra_hash)
249+
ra_game_id = await self._search_rom(rom, ra_hash)
254250

255-
if not ra_game_list_item:
251+
if ra_game_id is None:
256252
return RAGameRom(ra_id=None)
257253

258254
try:
259-
rom_details = await self.ra_service.get_game_extended_details(
260-
ra_game_list_item["ID"]
261-
)
255+
rom_details = await self.ra_service.get_game_extended_details(ra_game_id)
262256

263257
return RAGameRom(
264258
ra_id=rom_details["ID"],

0 commit comments

Comments
 (0)