move pm to own scanner

This commit is contained in:
Georges-Antoine Assi
2025-06-15 13:45:09 -04:00
parent c46d81bba5
commit 77ef4eb4ba
2 changed files with 61 additions and 37 deletions

View File

@@ -5,6 +5,7 @@ import httpx
import yarl
from fastapi import HTTPException, status
from logger.logger import log
from models.rom import RomFile
from utils.context import ctx_httpx_client
from backend.config import PLAYMATCH_API_ENABLED
@@ -54,9 +55,7 @@ class PlaymatchHandler:
def __init__(self):
self.base_url = "https://playmatch.retrorealm.dev/api"
async def lookup_rom(
self, file_name: str, file_size: int, md5: str | None, sha1: str | None
) -> list[PlaymatchRomMatch]:
async def lookup_rom(self, rom_file: RomFile) -> list[PlaymatchRomMatch]:
"""
Identify a ROM file using Playmatch API.
@@ -76,10 +75,10 @@ class PlaymatchHandler:
response = await self._request(
url,
{
"fileName": file_name,
"fileSize": file_size,
"md5": md5,
"sha1": sha1,
"fileName": rom_file.file_name,
"fileSize": rom_file.file_size_bytes,
"md5": rom_file.md5_hash,
"sha1": rom_file.sha1_hash,
},
)
except httpx.HTTPStatusError as e:

View File

@@ -43,11 +43,12 @@ class ScanType(Enum):
class MetadataSource:
IGDB = "igdb"
MOBY = "moby"
SS = "ss"
RA = "ra"
LB = "lb"
IGDB = "igdb" # IGDB
MOBY = "moby" # MobyGames
SS = "ss" # Screenscraper
RA = "ra" # RetroAchivements
LB = "lb" # Launchbox
PM = "pm" # Playmatch
async def _get_main_platform_igdb_id(platform: Platform):
@@ -88,6 +89,8 @@ async def scan_platform(
MetadataSource.MOBY,
MetadataSource.SS,
MetadataSource.RA,
MetadataSource.LB,
MetadataSource.PM,
]
platform_attrs: dict[str, Any] = {}
@@ -301,7 +304,7 @@ async def scan_rom(
}
)
async def fetch_igdb_rom():
async def fetch_igdb_rom() -> IGDBRom:
if (
MetadataSource.IGDB in metadata_sources
and platform.igdb_id
@@ -312,26 +315,6 @@ async def scan_rom(
or (scan_type == ScanType.UNIDENTIFIED and not rom.igdb_id)
)
):
rom_file = fs_rom["files"][0]
pm_matches = await meta_pm_handler.lookup_rom(
rom_file.file_name,
rom_file.file_size_bytes,
rom_file.md5_hash,
rom_file.sha1_hash,
)
for pm_match in pm_matches:
if pm_match["provider"] == PlaymatchProvider.IGDB:
pm_igdbid = pm_match["provider_game_id"]
if pm_igdbid is not None:
log.debug(
emoji.emojize(
f"{hl(rom_attrs['fs_name'])} identified by Playmatch as {hl(str(pm_igdbid), color=BLUE)} :alien_monster:"
),
extra=LOGGER_MODULE_NAME,
)
return await meta_igdb_handler.get_rom_by_id(pm_igdbid)
main_platform_igdb_id = await _get_main_platform_igdb_id(platform)
return await meta_igdb_handler.get_rom(
rom_attrs["fs_name"], main_platform_igdb_id or platform.igdb_id
@@ -339,7 +322,7 @@ async def scan_rom(
return IGDBRom(igdb_id=None)
async def fetch_moby_rom():
async def fetch_moby_rom() -> MobyGamesRom:
if (
MetadataSource.MOBY in metadata_sources
and platform.moby_id
@@ -356,7 +339,7 @@ async def scan_rom(
return MobyGamesRom(moby_id=None)
async def fetch_ss_rom():
async def fetch_ss_rom() -> SSRom:
if (
MetadataSource.SS in metadata_sources
and platform.ss_id
@@ -373,7 +356,7 @@ async def scan_rom(
return SSRom(ss_id=None)
async def fetch_launchbox_rom(platform_slug: str):
async def fetch_launchbox_rom(platform_slug: str) -> LaunchboxRom:
if MetadataSource.LB in metadata_sources and (
newly_added
or scan_type == ScanType.COMPLETE
@@ -386,7 +369,7 @@ async def scan_rom(
return LaunchboxRom(launchbox_id=None)
async def fetch_ra_rom():
async def fetch_ra_rom() -> RAGameRom:
if (
MetadataSource.RA in metadata_sources
and platform.ra_id
@@ -402,6 +385,43 @@ async def scan_rom(
return RAGameRom(ra_id=None)
# Playmatch currectly only supports IGDB IDs
async def fetch_playmatch_rom() -> IGDBRom:
if (
MetadataSource.PM in metadata_sources
and platform.igdb_id
and (
newly_added
or scan_type == ScanType.COMPLETE
or (scan_type == ScanType.PARTIAL and not rom.igdb_id)
or (scan_type == ScanType.UNIDENTIFIED and not rom.igdb_id)
)
):
rom_file = fs_rom["files"][0]
pm_matches = await meta_pm_handler.lookup_rom(rom_file)
for pm_match in pm_matches:
if pm_match["provider"] != PlaymatchProvider.IGDB:
continue
pm_igdbid = pm_match.get("provider_game_id")
if pm_igdbid is None:
continue
# Log the successful identification
log.debug(
emoji.emojize(
f"{hl(rom_attrs['fs_name'])} identified by Playmatch as "
f"{hl(str(pm_igdbid), color=BLUE)} :alien_monster:"
),
extra=LOGGER_MODULE_NAME,
)
# Return the ROM data from IGDB
return await meta_igdb_handler.get_rom_by_id(pm_igdbid)
return IGDBRom(igdb_id=None)
# Run both metadata fetches concurrently
(
igdb_handler_rom,
@@ -409,18 +429,21 @@ async def scan_rom(
ss_handler_rom,
ra_handler_rom,
launchbox_handler_rom,
playmatch_handler_rom,
) = await asyncio.gather(
fetch_igdb_rom(),
fetch_moby_rom(),
fetch_ss_rom(),
fetch_ra_rom(),
fetch_launchbox_rom(platform.slug),
fetch_playmatch_rom(),
)
if newly_added:
# Reversed to prioritize IGDB
rom_attrs.update(
{
**playmatch_handler_rom,
**ra_handler_rom,
**launchbox_handler_rom,
**moby_handler_rom,
@@ -430,6 +453,8 @@ async def scan_rom(
)
else:
# Only update fields if match is found
if playmatch_handler_rom.get("igdb_id"):
rom_attrs.update({**playmatch_handler_rom})
if ra_handler_rom.get("ra_id"):
rom_attrs.update({**ra_handler_rom})
if moby_handler_rom.get("moby_id"):