Add miximage_v2 media type mapping to SS.fr mixrbv2

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-28 20:15:40 +00:00
committed by GitHub
parent 71cb3e4f04
commit d29ed39a6a
5 changed files with 161 additions and 5 deletions

View File

@@ -75,6 +75,7 @@ class MetadataMediaType(enum.StrEnum):
BOX2D_BACK = "box2d_back"
BOX3D = "box3d"
MIXIMAGE = "miximage"
MIXIMAGE_V2 = "miximage_v2"
PHYSICAL = "physical"
SCREENSHOT = "screenshot"
TITLE_SCREEN = "title_screen"
@@ -665,6 +666,7 @@ class ConfigManager:
MetadataMediaType.BOX2D,
MetadataMediaType.BOX3D,
MetadataMediaType.MIXIMAGE,
MetadataMediaType.MIXIMAGE_V2,
MetadataMediaType.PHYSICAL,
}
if not isinstance(self.config.GAMELIST_MEDIA_THUMBNAIL, str):
@@ -683,6 +685,7 @@ class ConfigManager:
valid_image_options = {
MetadataMediaType.TITLE_SCREEN,
MetadataMediaType.MIXIMAGE,
MetadataMediaType.MIXIMAGE_V2,
MetadataMediaType.BOX2D,
MetadataMediaType.SCREENSHOT,
}

View File

@@ -171,7 +171,8 @@ class SSMetadataMedia(TypedDict):
logo_url: str | None # wheel-hd or wheel
manual_url: str | None # manual
marquee_url: str | None # screenmarquee
miximage_url: str | None # mixrbv1 | mixrbv2
miximage_url: str | None # miximage1 | miximage2 | mixrbv1
miximage_v2_url: str | None # mixrbv2
physical_url: str | None # support-2D
screenshot_url: str | None # ss
steamgrid_url: str | None # steamgrid
@@ -185,6 +186,7 @@ class SSMetadataMedia(TypedDict):
box3d_path: str | None
fanart_path: str | None
miximage_path: str | None
miximage_v2_path: str | None
physical_path: str | None
marquee_path: str | None
logo_path: str | None
@@ -233,6 +235,7 @@ def extract_media_from_ss_game(rom: Rom, game: SSGame) -> SSMetadataMedia:
manual_url=None,
marquee_url=None,
miximage_url=None,
miximage_v2_url=None,
physical_url=None,
screenshot_url=None,
steamgrid_url=None,
@@ -244,6 +247,7 @@ def extract_media_from_ss_game(rom: Rom, game: SSGame) -> SSMetadataMedia:
box3d_path=None,
fanart_path=None,
miximage_path=None,
miximage_v2_path=None,
physical_path=None,
marquee_path=None,
logo_path=None,
@@ -322,7 +326,6 @@ def extract_media_from_ss_game(rom: Rom, game: SSGame) -> SSMetadataMedia:
media.get("type") == "miximage1"
or media.get("type") == "miximage2"
or media.get("type") == "mixrbv1"
or media.get("type") == "mixrbv2"
) and not ss_media["miximage_url"]:
ss_media["miximage_url"] = strip_sensitive_query_params(
media["url"], SENSITIVE_KEYS
@@ -331,6 +334,17 @@ def extract_media_from_ss_game(rom: Rom, game: SSGame) -> SSMetadataMedia:
ss_media["miximage_path"] = (
f"{fs_resource_handler.get_media_resources_path(rom.platform_id, rom.id, MetadataMediaType.MIXIMAGE)}/miximage.png"
)
elif (
media.get("type") == "mixrbv2"
and not ss_media["miximage_v2_url"]
):
ss_media["miximage_v2_url"] = strip_sensitive_query_params(
media["url"], SENSITIVE_KEYS
)
if MetadataMediaType.MIXIMAGE_V2 in preferred_media_types:
ss_media["miximage_v2_path"] = (
f"{fs_resource_handler.get_media_resources_path(rom.platform_id, rom.id, MetadataMediaType.MIXIMAGE_V2)}/miximage_v2.png"
)
elif media.get("type") == "support-2D" and not ss_media["physical_url"]:
ss_media["physical_url"] = strip_sensitive_query_params(
media["url"], SENSITIVE_KEYS

View File

@@ -19,7 +19,10 @@ from handler.metadata.ss_handler import (
)
def _make_config(region_priority: list[str] | None = None) -> Config:
def _make_config(
region_priority: list[str] | None = None,
scan_media: list[str] | None = None,
) -> Config:
"""Build a minimal Config object for testing."""
return Config(
EXCLUDED_PLATFORMS=[],
@@ -34,7 +37,7 @@ def _make_config(region_priority: list[str] | None = None) -> Config:
FIRMWARE_FOLDER_NAME="bios",
SCAN_REGION_PRIORITY=region_priority or [],
SCAN_LANGUAGE_PRIORITY=["en"],
SCAN_MEDIA=["box2d", "box3d", "screenshot"],
SCAN_MEDIA=scan_media if scan_media is not None else ["box2d", "box3d", "screenshot"],
GAMELIST_MEDIA_THUMBNAIL=MetadataMediaType.BOX2D,
GAMELIST_MEDIA_IMAGE=MetadataMediaType.SCREENSHOT,
)
@@ -203,6 +206,138 @@ class TestExtractMediaFromSsGame:
assert result["box2d_url"] is not None
assert "box-2D(us)" in result["box2d_url"]
def _make_game_with_both_miximage_versions(self) -> SSGame:
"""A game that has both mixrbv1 and mixrbv2 (v1 listed first, matching SS API order)."""
return cast(
SSGame,
{
"medias": [
{
"type": "mixrbv1",
"parent": "jeu",
"region": "us",
"url": "https://screenscraper.example.com/mixrbv1",
"crc": "aabbccdd",
"md5": "deadbeef",
"sha1": "cafebabe",
"size": "12345",
"format": "png",
},
{
"type": "mixrbv2",
"parent": "jeu",
"region": "us",
"url": "https://screenscraper.example.com/mixrbv2",
"crc": "11223344",
"md5": "feedface",
"sha1": "baadf00d",
"size": "67890",
"format": "png",
},
]
},
)
def test_miximage_maps_to_mixrbv1(self):
"""When 'miximage' is in SCAN_MEDIA, only mixrbv1 is downloaded."""
config = _make_config(scan_media=["miximage"])
rom = self._make_rom()
game = self._make_game_with_both_miximage_versions()
with (
patch("handler.metadata.ss_handler.cm.get_config", return_value=config),
patch(
"handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path",
return_value="roms/1/100/miximage",
),
):
result = extract_media_from_ss_game(rom, game)
assert result["miximage_url"] is not None
assert "mixrbv1" in result["miximage_url"]
assert result["miximage_path"] is not None
assert result["miximage_v2_url"] is not None
assert "mixrbv2" in result["miximage_v2_url"]
assert result["miximage_v2_path"] is None
def test_miximage_v2_maps_to_mixrbv2(self):
"""When 'miximage_v2' is in SCAN_MEDIA, only mixrbv2 is downloaded."""
config = _make_config(scan_media=["miximage_v2"])
rom = self._make_rom()
game = self._make_game_with_both_miximage_versions()
with (
patch("handler.metadata.ss_handler.cm.get_config", return_value=config),
patch(
"handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path",
return_value="roms/1/100/miximage_v2",
),
):
result = extract_media_from_ss_game(rom, game)
assert result["miximage_v2_url"] is not None
assert "mixrbv2" in result["miximage_v2_url"]
assert result["miximage_v2_path"] is not None
assert result["miximage_url"] is not None
assert "mixrbv1" in result["miximage_url"]
assert result["miximage_path"] is None
def test_miximage_v2_not_downloaded_when_only_miximage_in_config(self):
"""When only 'miximage' is in SCAN_MEDIA, miximage_v2_path is not set."""
config = _make_config(scan_media=["miximage"])
rom = self._make_rom()
game = self._make_game_with_both_miximage_versions()
with (
patch("handler.metadata.ss_handler.cm.get_config", return_value=config),
patch(
"handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path",
return_value="roms/1/100/miximage",
),
):
result = extract_media_from_ss_game(rom, game)
assert result["miximage_v2_path"] is None
def test_miximage_v1_not_downloaded_when_only_miximage_v2_in_config(self):
"""When only 'miximage_v2' is in SCAN_MEDIA, miximage_path is not set."""
config = _make_config(scan_media=["miximage_v2"])
rom = self._make_rom()
game = self._make_game_with_both_miximage_versions()
with (
patch("handler.metadata.ss_handler.cm.get_config", return_value=config),
patch(
"handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path",
return_value="roms/1/100/miximage_v2",
),
):
result = extract_media_from_ss_game(rom, game)
assert result["miximage_path"] is None
def test_both_miximage_versions_downloaded_when_both_in_config(self):
"""When both 'miximage' and 'miximage_v2' are in SCAN_MEDIA, both are downloaded."""
config = _make_config(scan_media=["miximage", "miximage_v2"])
rom = self._make_rom()
game = self._make_game_with_both_miximage_versions()
with (
patch("handler.metadata.ss_handler.cm.get_config", return_value=config),
patch(
"handler.metadata.ss_handler.fs_resource_handler.get_media_resources_path",
side_effect=lambda pid, rid, mt: f"roms/{pid}/{rid}/{mt.value}",
),
):
result = extract_media_from_ss_game(rom, game)
assert result["miximage_url"] is not None
assert "mixrbv1" in result["miximage_url"]
assert result["miximage_path"] is not None
assert result["miximage_v2_url"] is not None
assert "mixrbv2" in result["miximage_v2_url"]
assert result["miximage_v2_path"] is not None
class TestExtractMetadataFromSsRom:
def _make_rom(self, regions: list[str] | None = None) -> MagicMock:

View File

@@ -26,6 +26,7 @@ ASSET_DIRS: dict[str, str] = {
"fanart": "fanart",
"marquee": "marquees",
"miximage": "miximages",
"miximage_v2": "miximages",
"physical": "physical",
"screenshot": "screenshots",
"title_screen": "titlescreens",
@@ -89,6 +90,7 @@ class GamelistExporter:
"fanart": [ss.get("fanart_path", ""), gl.get("fanart_path", "")],
"marquee": [ss.get("logo_path", ""), gl.get("marquee_path", "")],
"miximage": [ss.get("miximage_path", ""), gl.get("miximage_path", "")],
"miximage_v2": [ss.get("miximage_v2_path", "")],
"physical": [ss.get("physical_path", ""), gl.get("physical_path", "")],
"title_screen": [
ss.get("title_screen_path", ""),
@@ -262,6 +264,7 @@ class GamelistExporter:
"fanart": "fanart",
"marquee": "marquee",
"miximage": "miximage",
"miximage_v2": "miximage",
"physical": "physicalmedia",
"title_screen": "title_screen",
"bezel": "bezel",

View File

@@ -117,7 +117,8 @@
# # Used as alternative cover art
# - box2d # Normal cover art (always enabled)
# - box3d # 3D box art
# - miximage # Mixed image of multiple media
# - miximage # Mixed image of multiple media (v1 / mixrbv1)
# - miximage_v2 # Mixed image of multiple media (v2 / mixrbv2)
# - physical # Disc, cartridge, etc.
# # Added to the screenshots carousel
# - screenshot # Screenshot (enabled by default)