feat: add new export.gamelist.media.image configuration

also fix broken title_screen/miximage/physical key name usage
This commit is contained in:
Vargash
2026-03-31 11:16:40 +02:00
parent ec30b18bba
commit f4c965be33
8 changed files with 66 additions and 12 deletions

View File

@@ -127,6 +127,7 @@ class Config:
SCAN_LANGUAGE_PRIORITY: list[str]
SCAN_MEDIA: list[str]
GAMELIST_THUMBNAIL_MEDIA: str
GAMELIST_IMAGE_MEDIA: str
def __init__(self, **entries):
self.__dict__.update(entries)
@@ -347,6 +348,11 @@ class ConfigManager:
"export.gamelist.media.thumbnail",
"cover",
),
GAMELIST_IMAGE_MEDIA=pydash.get(
self._raw_config,
"export.gamelist.media.image",
"screenshot",
),
)
def _get_ejs_controls(self) -> dict[str, EjsControls]:

View File

@@ -243,6 +243,12 @@ def populate_rom_specific_paths(
updated_metadata["physical_path"] = (
f"{fs_resource_handler.get_media_resources_path(rom.platform_id, rom.id, MetadataMediaType.PHYSICAL)}/physical.png"
)
if MetadataMediaType.TITLE_SCREEN in preferred_media_types and rom_metadata.get(
"title_screen_url"
):
updated_metadata["title_screen_path"] = (
f"{fs_resource_handler.get_media_resources_path(rom.platform_id, rom.id, MetadataMediaType.TITLE_SCREEN)}/title_screen.png"
)
if MetadataMediaType.VIDEO in preferred_media_types and rom_metadata.get(
"video_url"
):

View File

@@ -116,6 +116,7 @@ class SSMetadataMedia(TypedDict):
physical_path: str | None
marquee_path: str | None
logo_path: str | None
title_screen_path: str | None
video_path: str | None
video_normalized_path: str | None
@@ -166,6 +167,7 @@ def extract_media_from_ss_game(rom: Rom, game: SSGame) -> SSMetadataMedia:
physical_path=None,
marquee_path=None,
logo_path=None,
title_screen_path=None,
video_path=None,
video_normalized_path=None,
)
@@ -281,6 +283,10 @@ def extract_media_from_ss_game(rom: Rom, game: SSGame) -> SSMetadataMedia:
ss_media["title_screen_url"] = strip_sensitive_query_params(
media["url"], SENSITIVE_KEYS
)
if MetadataMediaType.TITLE_SCREEN in preferred_media_types:
ss_media["title_screen_path"] = (
f"{fs_resource_handler.get_media_resources_path(rom.platform_id, rom.id, MetadataMediaType.TITLE_SCREEN)}/title_screen.png"
)
elif media.get("type") == "video" and not ss_media["video_url"]:
ss_media["video_url"] = strip_sensitive_query_params(
media["url"], SENSITIVE_KEYS

View File

@@ -80,3 +80,4 @@ export:
gamelist:
media:
thumbnail: "box3d"
image: "title_screen"

View File

@@ -55,6 +55,7 @@ def test_config_loader():
assert loader.config.SCAN_REGION_PRIORITY == ["jp", "eu", "wor"]
assert loader.config.SCAN_LANGUAGE_PRIORITY == ["jp", "es"]
assert loader.config.GAMELIST_THUMBNAIL_MEDIA == "box3d"
assert loader.config.GAMELIST_IMAGE_MEDIA == "title_screen"
def test_empty_config_loader():
@@ -88,3 +89,4 @@ def test_empty_config_loader():
assert loader.config.EJS_SETTINGS == {}
assert loader.config.EJS_CONTROLS == {}
assert loader.config.GAMELIST_THUMBNAIL_MEDIA == "cover"
assert loader.config.GAMELIST_IMAGE_MEDIA == "screenshot"

View File

@@ -87,6 +87,27 @@ class GamelistExporter:
f"{FRONTEND_RESOURCES_PATH}/{rom.path_screenshots[0]}"
)
image_path: str | None = None
image_option = cm.config.GAMELIST_IMAGE_MEDIA
if image_option == "title_screen":
if rom.ss_metadata and rom.ss_metadata.get("title_screen_path"):
image_path = f"{FRONTEND_RESOURCES_PATH}/{rom.ss_metadata['title_screen_path']}"
elif rom.gamelist_metadata and rom.gamelist_metadata.get("title_screen_path"):
image_path = f"{FRONTEND_RESOURCES_PATH}/{rom.gamelist_metadata['title_screen_path']}"
elif image_option == "miximage":
if rom.ss_metadata and rom.ss_metadata.get("miximage_path"):
image_path = f"{FRONTEND_RESOURCES_PATH}/{rom.ss_metadata['miximage_path']}"
elif rom.gamelist_metadata and rom.gamelist_metadata.get("miximage_path"):
image_path = f"{FRONTEND_RESOURCES_PATH}/{rom.gamelist_metadata['miximage_path']}"
elif image_option == "cover":
if rom.path_cover_l:
image_path = f"{FRONTEND_RESOURCES_PATH}/{rom.path_cover_l}"
# "screenshot" (default) and anything else falls through to path_screenshots
if image_path is None and rom.path_screenshots:
image_path = f"{FRONTEND_RESOURCES_PATH}/{rom.path_screenshots[0]}"
if image_path:
SubElement(game, "image").text = image_path
if rom.path_manual:
SubElement(game, "manual").text = (
f"{FRONTEND_RESOURCES_PATH}/{rom.path_manual}"
@@ -154,9 +175,9 @@ class GamelistExporter:
SubElement(game, "physicalmedia").text = (
f"{FRONTEND_RESOURCES_PATH}/{rom.ss_metadata["physical_path"]}"
)
if rom.ss_metadata.get("title_screen"):
if rom.ss_metadata.get("title_screen_path"):
SubElement(game, "title_screen").text = (
f"{FRONTEND_RESOURCES_PATH}/{rom.ss_metadata["title_screen"]}"
f"{FRONTEND_RESOURCES_PATH}/{rom.ss_metadata['title_screen_path']}"
)
if rom.ss_metadata.get("bezel_path"):
SubElement(game, "bezel").text = (
@@ -172,16 +193,18 @@ class GamelistExporter:
SubElement(game, "fanart").text = rom.gamelist_metadata["fanart"]
if rom.gamelist_metadata.get("marquee"):
SubElement(game, "marquee").text = rom.gamelist_metadata["marquee"]
if rom.gamelist_metadata.get("miximage"):
SubElement(game, "miximage").text = rom.gamelist_metadata["miximage"]
if rom.gamelist_metadata.get("physical"):
SubElement(game, "physicalmedia").text = rom.gamelist_metadata[
"physical"
]
if rom.gamelist_metadata.get("title_screen"):
SubElement(game, "title_screen").text = rom.gamelist_metadata[
"title_screen"
]
if rom.gamelist_metadata.get("miximage_path"):
SubElement(game, "miximage").text = (
f"{FRONTEND_RESOURCES_PATH}/{rom.gamelist_metadata['miximage_path']}"
)
if rom.gamelist_metadata.get("physical_path"):
SubElement(game, "physicalmedia").text = (
f"{FRONTEND_RESOURCES_PATH}/{rom.gamelist_metadata['physical_path']}"
)
if rom.gamelist_metadata.get("title_screen_path"):
SubElement(game, "title_screen").text = (
f"{FRONTEND_RESOURCES_PATH}/{rom.gamelist_metadata['title_screen_path']}"
)
# Add scraping info
scrap = SubElement(game, "scrap")

View File

@@ -191,3 +191,7 @@ export:
# Falls back to front cover if 3D box art has not been scraped
# Other options: cover (default), box2d, miximage, physical
thumbnail: box3d
# Use the miximage as the <image> tag, preferred by Batocera/RetroBAT
# Falls back to first screenshot if not available
# Other options: "screenshot" (default), "title_screen", "cover"
image: "miximage"

View File

@@ -145,6 +145,12 @@
# # miximage - mixed image (falls back to cover if not available)
# # physical - disc/cartridge image (falls back to cover if not available)
# thumbnail: cover
# # Media asset to use as the <image> tag in the exported gamelist.xml
# # screenshot - first screenshot (default)
# # title_screen - title screen image (falls back to screenshot if not available)
# # miximage - mixed image (falls back to screenshot if not available)
# # cover - front cover art (falls back to screenshot if not available)
# image: screenshot
# EmulatorJS per-core options
# emulatorjs: