mirror of
https://github.com/rommapp/romm.git
synced 2026-06-27 22:35:57 +00:00
manual cleanu
This commit is contained in:
@@ -29,8 +29,17 @@ def upgrade() -> None:
|
||||
if_not_exists=True,
|
||||
)
|
||||
|
||||
with op.batch_alter_table("platforms", schema=None) as batch_op:
|
||||
batch_op.add_column(
|
||||
sa.Column("libretro_slug", sa.String(length=100), nullable=True),
|
||||
if_not_exists=True,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
with op.batch_alter_table("roms", schema=None) as batch_op:
|
||||
batch_op.drop_index("idx_roms_libretro_id", if_exists=True)
|
||||
batch_op.drop_column("libretro_id", if_exists=True)
|
||||
|
||||
with op.batch_alter_table("platforms", schema=None) as batch_op:
|
||||
batch_op.drop_column("libretro_slug", if_exists=True)
|
||||
|
||||
@@ -17,6 +17,7 @@ class PlatformSchema(BaseModel):
|
||||
igdb_slug: str | None
|
||||
moby_slug: str | None
|
||||
hltb_slug: str | None
|
||||
libretro_slug: str | None
|
||||
custom_name: str | None = None
|
||||
igdb_id: int | None = None
|
||||
sgdb_id: int | None = None
|
||||
|
||||
@@ -1,98 +1,25 @@
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
from sys import platform
|
||||
from typing import Final, NotRequired, TypedDict
|
||||
|
||||
from adapters.services.libretro_thumbnails import (
|
||||
LIBRETRO_THUMBNAIL_ROOT,
|
||||
LibretroThumbnailsService,
|
||||
)
|
||||
from adapters.services.libretro_thumbnails import LibretroThumbnailsService
|
||||
from adapters.services.libretro_thumbnails_types import LibretroArtType
|
||||
from handler.metadata.igdb_handler import IGDB_PLATFORM_LIST
|
||||
from logger.logger import log
|
||||
|
||||
from .base_handler import MetadataHandler, UniversalPlatformSlug
|
||||
|
||||
# Mapping of RomM UniversalPlatformSlug values to libretro thumbnail
|
||||
# directory names (https://thumbnails.libretro.com/).
|
||||
LIBRETRO_PLATFORM_LIST: Final[dict[UniversalPlatformSlug, str]] = {
|
||||
UniversalPlatformSlug.ADVENTURE_VISION: "Entex - Adventure Vision",
|
||||
UniversalPlatformSlug.AMIGA: "Commodore - Amiga",
|
||||
UniversalPlatformSlug.AMIGA_CD32: "Commodore - Amiga",
|
||||
UniversalPlatformSlug.ACPC: "Amstrad - CPC",
|
||||
UniversalPlatformSlug.ATARI2600: "Atari - 2600",
|
||||
UniversalPlatformSlug.ATARI5200: "Atari - 5200",
|
||||
UniversalPlatformSlug.ATARI7800: "Atari - 7800",
|
||||
UniversalPlatformSlug.ATARI_ST: "Atari - ST",
|
||||
UniversalPlatformSlug.JAGUAR: "Atari - Jaguar",
|
||||
UniversalPlatformSlug.LYNX: "Atari - Lynx",
|
||||
UniversalPlatformSlug.WONDERSWAN: "Bandai - WonderSwan",
|
||||
UniversalPlatformSlug.WONDERSWAN_COLOR: "Bandai - WonderSwan Color",
|
||||
UniversalPlatformSlug.COLECOVISION: "Coleco - ColecoVision",
|
||||
UniversalPlatformSlug.C64: "Commodore - 64",
|
||||
UniversalPlatformSlug.VIC_20: "Commodore - VIC-20",
|
||||
UniversalPlatformSlug.DOS: "DOS",
|
||||
UniversalPlatformSlug.FAIRCHILD_CHANNEL_F: "Fairchild - Channel F",
|
||||
UniversalPlatformSlug.VECTREX: "GCE - Vectrex",
|
||||
UniversalPlatformSlug.ODYSSEY_2: "Magnavox - Odyssey2",
|
||||
UniversalPlatformSlug.INTELLIVISION: "Mattel - Intellivision",
|
||||
UniversalPlatformSlug.MSX: "Microsoft - MSX",
|
||||
UniversalPlatformSlug.MSX2: "Microsoft - MSX2",
|
||||
UniversalPlatformSlug.XBOX: "Microsoft - XBOX",
|
||||
UniversalPlatformSlug.PC_8800_SERIES: "NEC - PC Engine - TurboGrafx 16",
|
||||
UniversalPlatformSlug.PC_FX: "NEC - PC-FX",
|
||||
UniversalPlatformSlug.PC_9800_SERIES: "NEC - PC-98",
|
||||
UniversalPlatformSlug.SUPERGRAFX: "NEC - PC Engine SuperGrafx",
|
||||
UniversalPlatformSlug.TG16: "NEC - PC Engine - TurboGrafx 16",
|
||||
UniversalPlatformSlug.TURBOGRAFX_CD: "NEC - PC Engine CD - TurboGrafx-CD",
|
||||
UniversalPlatformSlug.FDS: "Nintendo - Family Computer Disk System",
|
||||
UniversalPlatformSlug.GB: "Nintendo - Game Boy",
|
||||
UniversalPlatformSlug.GBA: "Nintendo - Game Boy Advance",
|
||||
UniversalPlatformSlug.GBC: "Nintendo - Game Boy Color",
|
||||
UniversalPlatformSlug.NGC: "Nintendo - GameCube",
|
||||
UniversalPlatformSlug.N64: "Nintendo - Nintendo 64",
|
||||
UniversalPlatformSlug.N64DD: "Nintendo - Nintendo 64DD",
|
||||
UniversalPlatformSlug.N3DS: "Nintendo - Nintendo 3DS",
|
||||
UniversalPlatformSlug.NDS: "Nintendo - Nintendo DS",
|
||||
UniversalPlatformSlug.NES: "Nintendo - Nintendo Entertainment System",
|
||||
UniversalPlatformSlug.FAMICOM: "Nintendo - Nintendo Entertainment System",
|
||||
UniversalPlatformSlug.POKEMON_MINI: "Nintendo - Pokemon Mini",
|
||||
UniversalPlatformSlug.SATELLAVIEW: "Nintendo - Satellaview",
|
||||
UniversalPlatformSlug.SUFAMI_TURBO: "Nintendo - Sufami Turbo",
|
||||
UniversalPlatformSlug.SNES: "Nintendo - Super Nintendo Entertainment System",
|
||||
UniversalPlatformSlug.SFAM: "Nintendo - Super Nintendo Entertainment System",
|
||||
UniversalPlatformSlug.VIRTUALBOY: "Nintendo - Virtual Boy",
|
||||
UniversalPlatformSlug.WII: "Nintendo - Wii",
|
||||
UniversalPlatformSlug.WIIU: "Nintendo - Wii U",
|
||||
UniversalPlatformSlug.SCUMMVM: "ScummVM",
|
||||
UniversalPlatformSlug.SEGA32: "Sega - 32X",
|
||||
UniversalPlatformSlug.DC: "Sega - Dreamcast",
|
||||
UniversalPlatformSlug.GAMEGEAR: "Sega - Game Gear",
|
||||
UniversalPlatformSlug.GENESIS: "Sega - Mega Drive - Genesis",
|
||||
UniversalPlatformSlug.SEGACD: "Sega - Mega-CD - Sega CD",
|
||||
UniversalPlatformSlug.SMS: "Sega - Master System - Mark III",
|
||||
UniversalPlatformSlug.SG1000: "Sega - SG-1000",
|
||||
UniversalPlatformSlug.SATURN: "Sega - Saturn",
|
||||
UniversalPlatformSlug.X1: "Sharp - X1",
|
||||
UniversalPlatformSlug.SHARP_X68000: "Sharp - X68000",
|
||||
UniversalPlatformSlug.ZX81: "Sinclair - ZX 81",
|
||||
UniversalPlatformSlug.ZXS: "Sinclair - ZX Spectrum",
|
||||
UniversalPlatformSlug.NEOGEOAES: "SNK - Neo Geo",
|
||||
UniversalPlatformSlug.NEOGEOMVS: "SNK - Neo Geo",
|
||||
UniversalPlatformSlug.NEO_GEO_CD: "SNK - Neo Geo CD",
|
||||
UniversalPlatformSlug.NEO_GEO_POCKET: "SNK - Neo Geo Pocket",
|
||||
UniversalPlatformSlug.NEO_GEO_POCKET_COLOR: "SNK - Neo Geo Pocket Color",
|
||||
UniversalPlatformSlug.PSX: "Sony - PlayStation",
|
||||
UniversalPlatformSlug.PS2: "Sony - PlayStation 2",
|
||||
UniversalPlatformSlug.PSP: "Sony - PlayStation Portable",
|
||||
UniversalPlatformSlug.TIC_80: "TIC-80",
|
||||
UniversalPlatformSlug.TOMY_TUTOR: "Tomy - Tutor",
|
||||
UniversalPlatformSlug.SUPERVISION: "Watara - Supervision",
|
||||
}
|
||||
|
||||
from .base_handler import MetadataHandler
|
||||
from .base_handler import UniversalPlatformSlug as UPS
|
||||
|
||||
_PAREN_TAG_PATTERN = re.compile(r"\([^)]*\)")
|
||||
|
||||
|
||||
class LibretroPlatform(TypedDict):
|
||||
slug: str
|
||||
libretro_slug: str | None
|
||||
|
||||
|
||||
class LibretroRom(TypedDict):
|
||||
libretro_id: str | None
|
||||
url_cover: NotRequired[str]
|
||||
@@ -131,7 +58,6 @@ class LibretroHandler(MetadataHandler):
|
||||
|
||||
@classmethod
|
||||
def is_enabled(cls) -> bool:
|
||||
# Public server, no API key required. Always enabled.
|
||||
return True
|
||||
|
||||
async def heartbeat(self) -> bool:
|
||||
@@ -141,12 +67,13 @@ class LibretroHandler(MetadataHandler):
|
||||
log.error("Error checking libretro thumbnails: %s", exc)
|
||||
return False
|
||||
|
||||
def _resolve_system(self, platform_slug: str) -> str | None:
|
||||
try:
|
||||
ups = UniversalPlatformSlug(platform_slug)
|
||||
except ValueError:
|
||||
return None
|
||||
return LIBRETRO_PLATFORM_LIST.get(ups)
|
||||
def get_platform(self, slug: str) -> LibretroPlatform:
|
||||
if slug in LIBRETRO_PLATFORM_LIST:
|
||||
libretro_slug = LIBRETRO_PLATFORM_LIST[UPS(slug)]
|
||||
|
||||
return LibretroPlatform(slug=slug, libretro_slug=libretro_slug)
|
||||
|
||||
return LibretroPlatform(slug=slug, libretro_slug=None)
|
||||
|
||||
def _find_exact_match(self, target: str, listing: list[str]) -> str | None:
|
||||
"""Case-insensitive exact match on filename (extension stripped)."""
|
||||
@@ -197,11 +124,13 @@ class LibretroHandler(MetadataHandler):
|
||||
omitted because libretro artwork filenames are not proper game names —
|
||||
letting them overwrite a real name from IGDB/Moby would be wrong.
|
||||
"""
|
||||
system_name = self._resolve_system(platform_slug)
|
||||
if not system_name:
|
||||
platform = self.get_platform(platform_slug)
|
||||
if not platform or not platform["libretro_slug"]:
|
||||
return LibretroRom(libretro_id=None)
|
||||
|
||||
listing = await self.service.fetch_listing(system_name, LibretroArtType.BOX_ART)
|
||||
listing = await self.service.fetch_listing(
|
||||
platform["libretro_slug"], LibretroArtType.BOX_ART
|
||||
)
|
||||
if not listing:
|
||||
return LibretroRom(libretro_id=None)
|
||||
|
||||
@@ -210,7 +139,7 @@ class LibretroHandler(MetadataHandler):
|
||||
return LibretroRom(libretro_id=None)
|
||||
|
||||
url = LibretroThumbnailsService.build_art_url(
|
||||
system_name, LibretroArtType.BOX_ART, matched
|
||||
platform["libretro_slug"], LibretroArtType.BOX_ART, matched
|
||||
)
|
||||
return LibretroRom(
|
||||
libretro_id=libretro_id_for(matched),
|
||||
@@ -226,11 +155,13 @@ class LibretroHandler(MetadataHandler):
|
||||
tag-stripped title matches the search term on either an exact or
|
||||
fuzzy basis.
|
||||
"""
|
||||
system_name = self._resolve_system(platform_slug)
|
||||
if not system_name:
|
||||
platform = self.get_platform(platform_slug)
|
||||
if not platform or not platform["libretro_slug"]:
|
||||
return []
|
||||
|
||||
listing = await self.service.fetch_listing(system_name, LibretroArtType.BOX_ART)
|
||||
listing = await self.service.fetch_listing(
|
||||
platform["libretro_slug"], LibretroArtType.BOX_ART
|
||||
)
|
||||
if not listing:
|
||||
return []
|
||||
|
||||
@@ -260,7 +191,7 @@ class LibretroHandler(MetadataHandler):
|
||||
LibretroRom(
|
||||
libretro_id=libretro_id_for(filename),
|
||||
url_cover=LibretroThumbnailsService.build_art_url(
|
||||
system_name, LibretroArtType.BOX_ART, filename
|
||||
platform["libretro_slug"], LibretroArtType.BOX_ART, filename
|
||||
),
|
||||
name=stripped,
|
||||
)
|
||||
@@ -276,9 +207,85 @@ class LibretroHandler(MetadataHandler):
|
||||
LibretroRom(
|
||||
libretro_id=libretro_id_for(fuzzy),
|
||||
url_cover=LibretroThumbnailsService.build_art_url(
|
||||
system_name, LibretroArtType.BOX_ART, fuzzy
|
||||
platform["libretro_slug"], LibretroArtType.BOX_ART, fuzzy
|
||||
),
|
||||
name=_strip_paren_tags(_remove_file_extension(fuzzy)),
|
||||
)
|
||||
)
|
||||
return matches[:limit]
|
||||
|
||||
|
||||
LIBRETRO_PLATFORM_LIST: Final[dict[UPS, str]] = {
|
||||
UPS.ADVENTURE_VISION: "Entex - Adventure Vision",
|
||||
UPS.AMIGA: "Commodore - Amiga",
|
||||
UPS.AMIGA_CD32: "Commodore - Amiga",
|
||||
UPS.ACPC: "Amstrad - CPC",
|
||||
UPS.ATARI2600: "Atari - 2600",
|
||||
UPS.ATARI5200: "Atari - 5200",
|
||||
UPS.ATARI7800: "Atari - 7800",
|
||||
UPS.ATARI_ST: "Atari - ST",
|
||||
UPS.JAGUAR: "Atari - Jaguar",
|
||||
UPS.LYNX: "Atari - Lynx",
|
||||
UPS.WONDERSWAN: "Bandai - WonderSwan",
|
||||
UPS.WONDERSWAN_COLOR: "Bandai - WonderSwan Color",
|
||||
UPS.COLECOVISION: "Coleco - ColecoVision",
|
||||
UPS.C64: "Commodore - 64",
|
||||
UPS.VIC_20: "Commodore - VIC-20",
|
||||
UPS.DOS: "DOS",
|
||||
UPS.FAIRCHILD_CHANNEL_F: "Fairchild - Channel F",
|
||||
UPS.VECTREX: "GCE - Vectrex",
|
||||
UPS.ODYSSEY_2: "Magnavox - Odyssey2",
|
||||
UPS.INTELLIVISION: "Mattel - Intellivision",
|
||||
UPS.MSX: "Microsoft - MSX",
|
||||
UPS.MSX2: "Microsoft - MSX2",
|
||||
UPS.XBOX: "Microsoft - XBOX",
|
||||
UPS.PC_8800_SERIES: "NEC - PC Engine - TurboGrafx 16",
|
||||
UPS.PC_FX: "NEC - PC-FX",
|
||||
UPS.PC_9800_SERIES: "NEC - PC-98",
|
||||
UPS.SUPERGRAFX: "NEC - PC Engine SuperGrafx",
|
||||
UPS.TG16: "NEC - PC Engine - TurboGrafx 16",
|
||||
UPS.TURBOGRAFX_CD: "NEC - PC Engine CD - TurboGrafx-CD",
|
||||
UPS.FDS: "Nintendo - Family Computer Disk System",
|
||||
UPS.GB: "Nintendo - Game Boy",
|
||||
UPS.GBA: "Nintendo - Game Boy Advance",
|
||||
UPS.GBC: "Nintendo - Game Boy Color",
|
||||
UPS.NGC: "Nintendo - GameCube",
|
||||
UPS.N64: "Nintendo - Nintendo 64",
|
||||
UPS.N64DD: "Nintendo - Nintendo 64DD",
|
||||
UPS.N3DS: "Nintendo - Nintendo 3DS",
|
||||
UPS.NDS: "Nintendo - Nintendo DS",
|
||||
UPS.NES: "Nintendo - Nintendo Entertainment System",
|
||||
UPS.FAMICOM: "Nintendo - Nintendo Entertainment System",
|
||||
UPS.POKEMON_MINI: "Nintendo - Pokemon Mini",
|
||||
UPS.SATELLAVIEW: "Nintendo - Satellaview",
|
||||
UPS.SUFAMI_TURBO: "Nintendo - Sufami Turbo",
|
||||
UPS.SNES: "Nintendo - Super Nintendo Entertainment System",
|
||||
UPS.SFAM: "Nintendo - Super Nintendo Entertainment System",
|
||||
UPS.VIRTUALBOY: "Nintendo - Virtual Boy",
|
||||
UPS.WII: "Nintendo - Wii",
|
||||
UPS.WIIU: "Nintendo - Wii U",
|
||||
UPS.SCUMMVM: "ScummVM",
|
||||
UPS.SEGA32: "Sega - 32X",
|
||||
UPS.DC: "Sega - Dreamcast",
|
||||
UPS.GAMEGEAR: "Sega - Game Gear",
|
||||
UPS.GENESIS: "Sega - Mega Drive - Genesis",
|
||||
UPS.SEGACD: "Sega - Mega-CD - Sega CD",
|
||||
UPS.SMS: "Sega - Master System - Mark III",
|
||||
UPS.SG1000: "Sega - SG-1000",
|
||||
UPS.SATURN: "Sega - Saturn",
|
||||
UPS.X1: "Sharp - X1",
|
||||
UPS.SHARP_X68000: "Sharp - X68000",
|
||||
UPS.ZX81: "Sinclair - ZX 81",
|
||||
UPS.ZXS: "Sinclair - ZX Spectrum",
|
||||
UPS.NEOGEOAES: "SNK - Neo Geo",
|
||||
UPS.NEOGEOMVS: "SNK - Neo Geo",
|
||||
UPS.NEO_GEO_CD: "SNK - Neo Geo CD",
|
||||
UPS.NEO_GEO_POCKET: "SNK - Neo Geo Pocket",
|
||||
UPS.NEO_GEO_POCKET_COLOR: "SNK - Neo Geo Pocket Color",
|
||||
UPS.PSX: "Sony - PlayStation",
|
||||
UPS.PS2: "Sony - PlayStation 2",
|
||||
UPS.PSP: "Sony - PlayStation Portable",
|
||||
UPS.TIC_80: "TIC-80",
|
||||
UPS.TOMY_TUTOR: "Tomy - Tutor",
|
||||
UPS.SUPERVISION: "Watara - Supervision",
|
||||
}
|
||||
|
||||
@@ -182,10 +182,12 @@ async def scan_platform(
|
||||
tgdb_platform = meta_tgdb_handler.get_platform(platform_attrs["slug"])
|
||||
flashpoint_platform = meta_flashpoint_handler.get_platform(platform_attrs["slug"])
|
||||
hltb_platform = meta_hltb_handler.get_platform(platform_attrs["slug"])
|
||||
libretro_platform = meta_libretro_handler.get_platform(platform_attrs["slug"])
|
||||
|
||||
platform_attrs["name"] = platform_attrs["slug"].replace("-", " ").title()
|
||||
platform_attrs.update(
|
||||
{
|
||||
**libretro_platform,
|
||||
**hltb_platform,
|
||||
**flashpoint_platform,
|
||||
**tgdb_platform,
|
||||
@@ -228,6 +230,7 @@ async def scan_platform(
|
||||
or tgdb_platform["tgdb_id"]
|
||||
or flashpoint_platform["flashpoint_id"]
|
||||
or hltb_platform["hltb_slug"]
|
||||
or libretro_platform["libretro_slug"]
|
||||
):
|
||||
log.info(
|
||||
f"Folder {hl(platform_attrs['slug'])}[{hl(fs_slug, color=LIGHTYELLOW)}] identified as {hl(platform_attrs['name'], color=BLUE)} {emoji.EMOJI_VIDEO_GAME}",
|
||||
|
||||
@@ -31,6 +31,7 @@ class Platform(BaseModel):
|
||||
igdb_slug: Mapped[str | None] = mapped_column(String(length=100), default=None)
|
||||
moby_slug: Mapped[str | None] = mapped_column(String(length=100), default=None)
|
||||
hltb_slug: Mapped[str | None] = mapped_column(String(length=100), default=None)
|
||||
libretro_slug: Mapped[str | None] = mapped_column(String(length=100), default=None)
|
||||
slug: Mapped[str] = mapped_column(String(length=100))
|
||||
fs_slug: Mapped[str] = mapped_column(String(length=100))
|
||||
name: Mapped[str] = mapped_column(String(length=400))
|
||||
|
||||
@@ -9,6 +9,7 @@ from handler.metadata import (
|
||||
meta_hltb_handler,
|
||||
meta_igdb_handler,
|
||||
meta_launchbox_handler,
|
||||
meta_libretro_handler,
|
||||
meta_moby_handler,
|
||||
meta_ra_handler,
|
||||
meta_sgdb_handler,
|
||||
@@ -51,6 +52,7 @@ class ScanLibraryTask(PeriodicTask):
|
||||
MetadataSource.FLASHPOINT: meta_flashpoint_handler.is_enabled(),
|
||||
MetadataSource.HLTB: meta_hltb_handler.is_enabled(),
|
||||
MetadataSource.TGDB: meta_tgdb_handler.is_enabled(),
|
||||
MetadataSource.LIBRETRO: meta_libretro_handler.is_enabled(),
|
||||
}
|
||||
|
||||
metadata_sources = [source for source, flag in source_mapping.items() if flag]
|
||||
|
||||
@@ -7,6 +7,7 @@ from handler.metadata.hasheous_handler import HasheousHandler
|
||||
from handler.metadata.hltb_handler import HLTBHandler
|
||||
from handler.metadata.igdb_handler import IGDBHandler
|
||||
from handler.metadata.launchbox_handler.handler import LaunchboxHandler
|
||||
from handler.metadata.libretro_handler import LibretroHandler
|
||||
from handler.metadata.moby_handler import MobyGamesHandler
|
||||
from handler.metadata.ra_handler import RAHandler
|
||||
from handler.metadata.sgdb_handler import SGDBBaseHandler
|
||||
@@ -38,6 +39,7 @@ class TestScanLibraryTask:
|
||||
mocker.patch.object(FlashpointHandler, "is_enabled", return_value=False)
|
||||
mocker.patch.object(HLTBHandler, "is_enabled", return_value=False)
|
||||
mocker.patch.object(TGDBHandler, "is_enabled", return_value=False)
|
||||
mocker.patch.object(LibretroHandler, "is_enabled", return_value=False)
|
||||
mocker.patch("tasks.scheduled.scan_library.ENABLE_SCHEDULED_RESCAN", True)
|
||||
|
||||
scan_result = MagicMock()
|
||||
|
||||
@@ -7,6 +7,7 @@ from handler.metadata import (
|
||||
meta_hltb_handler,
|
||||
meta_igdb_handler,
|
||||
meta_launchbox_handler,
|
||||
meta_libretro_handler,
|
||||
meta_moby_handler,
|
||||
meta_ra_handler,
|
||||
meta_ss_handler,
|
||||
@@ -25,6 +26,7 @@ class SupportedPlatform(TypedDict):
|
||||
ra_id: int | None
|
||||
flashpoint_id: int | None
|
||||
hltb_slug: str | None
|
||||
libretro_slug: str | None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -41,6 +43,7 @@ if __name__ == "__main__":
|
||||
ra_platform = meta_ra_handler.get_platform(slug_lower)
|
||||
flashpoint_platform = meta_flashpoint_handler.get_platform(slug_lower)
|
||||
hltb_platform = meta_hltb_handler.get_platform(slug_lower)
|
||||
libretro_platform = meta_libretro_handler.get_platform(slug_lower)
|
||||
|
||||
supported_platforms[slug_lower] = {
|
||||
"name": igdb_platform.get("name", None)
|
||||
@@ -61,6 +64,7 @@ if __name__ == "__main__":
|
||||
"ra_id": ra_platform["ra_id"],
|
||||
"flashpoint_id": flashpoint_platform["flashpoint_id"],
|
||||
"hltb_slug": hltb_platform.get("hltb_slug", None),
|
||||
"libretro_slug": libretro_platform.get("libretro_slug", None),
|
||||
}
|
||||
|
||||
# Sort platforms by name field
|
||||
@@ -115,5 +119,10 @@ if __name__ == "__main__":
|
||||
if platform["hltb_slug"]
|
||||
else ""
|
||||
),
|
||||
(
|
||||
f'<a href="https://thumbnails.libretro.com/{platform["libretro_slug"]}" target="_blank" rel="noopener noreferrer"><img alt="libretro logo" src="../../resources/metadata_providers/libretro.png" height="24px" width="24px"></a>'
|
||||
if platform["libretro_slug"]
|
||||
else ""
|
||||
),
|
||||
" |",
|
||||
)
|
||||
|
||||
@@ -28,6 +28,7 @@ from handler.metadata import (
|
||||
meta_hltb_handler,
|
||||
meta_igdb_handler,
|
||||
meta_launchbox_handler,
|
||||
meta_libretro_handler,
|
||||
meta_moby_handler,
|
||||
meta_ra_handler,
|
||||
meta_sgdb_handler,
|
||||
@@ -185,6 +186,7 @@ def process_changes(changes: Sequence[Change]) -> None:
|
||||
MetadataSource.FLASHPOINT: meta_flashpoint_handler.is_enabled(),
|
||||
MetadataSource.HLTB: meta_hltb_handler.is_enabled(),
|
||||
MetadataSource.TGDB: meta_tgdb_handler.is_enabled(),
|
||||
MetadataSource.LIBRETRO: meta_libretro_handler.is_enabled(),
|
||||
}
|
||||
metadata_sources = [source for source, flag in source_mapping.items() if flag]
|
||||
if not metadata_sources:
|
||||
|
||||
@@ -82,34 +82,35 @@
|
||||
# priority:
|
||||
# # Below are the default priority values used
|
||||
# metadata: # Top-level metadata source priority
|
||||
# - "igdb" # IGDB (highest priority)
|
||||
# - "moby" # MobyGames
|
||||
# - "ss" # Screenscraper
|
||||
# - "ra" # RetroAchievements
|
||||
# - "launchbox" # Launchbox
|
||||
# - "gamelist" # ES-DE gamelist.xml
|
||||
# - "hasheous" # Hasheous
|
||||
# - "flashpoint" # Flashpoint Project
|
||||
# - "hltb" # HowLongToBeat (lowest priority)
|
||||
# - igdb # IGDB (highest priority)
|
||||
# - moby # MobyGames
|
||||
# - ss # Screenscraper
|
||||
# - ra # RetroAchievements
|
||||
# - launchbox # Launchbox
|
||||
# - gamelist # ES-DE gamelist.xml
|
||||
# - hasheous # Hasheous
|
||||
# - flashpoint # Flashpoint Project
|
||||
# - hltb # HowLongToBeat (lowest priority)
|
||||
# artwork: # Cover art and screenshots
|
||||
# - "igdb" # IGDB
|
||||
# - "moby" # MobyGames
|
||||
# - "ss" # Screenscraper
|
||||
# - "ra" # RetroAchievements
|
||||
# - "launchbox" # Launchbox
|
||||
# - "gamelist" # ES-DE gamelist.xml
|
||||
# - "hasheous" # Hasheous
|
||||
# - "flashpoint" # Flashpoint Project
|
||||
# - "hltb" # HowLongToBeat
|
||||
# - igdb # IGDB
|
||||
# - moby # MobyGames
|
||||
# - ss # Screenscraper
|
||||
# - ra # RetroAchievements
|
||||
# - launchbox # Launchbox
|
||||
# - libretro # Libretro
|
||||
# - gamelist # ES-DE gamelist.xml
|
||||
# - hasheous # Hasheous
|
||||
# - flashpoint # Flashpoint Project
|
||||
# - hltb # HowLongToBeat
|
||||
# region: # Used by IGDB and ScreenScraper for regional variants
|
||||
# - "us"
|
||||
# - "wor"
|
||||
# - "ss"
|
||||
# - "eu"
|
||||
# - "jp"
|
||||
# - us
|
||||
# - wor
|
||||
# - ss
|
||||
# - eu
|
||||
# - jp
|
||||
# language: # Used by ScreenScraper for descriptions
|
||||
# - "en"
|
||||
# - "fr"
|
||||
# - en
|
||||
# - fr
|
||||
# # Media assets to download
|
||||
# # Only used by Screenscraper and ES-DE gamelist.xml
|
||||
# media:
|
||||
|
||||
BIN
frontend/assets/scrappers/libretro.png
Normal file
BIN
frontend/assets/scrappers/libretro.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -12,6 +12,7 @@ export type PlatformSchema = {
|
||||
igdb_slug: (string | null);
|
||||
moby_slug: (string | null);
|
||||
hltb_slug: (string | null);
|
||||
libretro_slug: (string | null);
|
||||
custom_name?: (string | null);
|
||||
igdb_id?: (number | null);
|
||||
sgdb_id?: (number | null);
|
||||
|
||||
@@ -113,6 +113,7 @@ const coverImageSource = computed(() => {
|
||||
if (hostname === "hasheous.org") return "Hasheous";
|
||||
if (hostname === "infinity.unstable.life") return "Flashpoint";
|
||||
if (hostname === "howlongtobeat.com") return "HowLongToBeat";
|
||||
if (hostname === "thumbnails.libretro.com") return "Libretro";
|
||||
|
||||
return null;
|
||||
} catch {
|
||||
|
||||
@@ -24,6 +24,9 @@ const releaseDate = new Date(
|
||||
|
||||
const platformsStore = storePlatforms();
|
||||
const { allPlatforms } = storeToRefs(platformsStore);
|
||||
const platform = computed(() => {
|
||||
return allPlatforms.value.find((p) => p.id === props.rom.platform_id);
|
||||
});
|
||||
|
||||
const hashMatches = computed(() => {
|
||||
return [
|
||||
@@ -79,10 +82,7 @@ const hashMatches = computed(() => {
|
||||
:to="{ name: ROUTES.PLATFORM, params: { platform: rom.platform_id } }"
|
||||
>
|
||||
<MissingFromFSIcon
|
||||
v-if="
|
||||
allPlatforms.find((p) => p.id === rom.platform_id)
|
||||
?.missing_from_fs
|
||||
"
|
||||
v-if="platform?.missing_from_fs"
|
||||
class="mr-2"
|
||||
text="Missing platform from filesystem"
|
||||
/>
|
||||
@@ -328,6 +328,19 @@ const hashMatches = computed(() => {
|
||||
<span>{{ rom.sgdb_id }}</span>
|
||||
</v-chip>
|
||||
</a>
|
||||
<a
|
||||
v-if="platform && rom.libretro_id"
|
||||
style="text-decoration: none; color: inherit"
|
||||
:href="`https://thumbnails.libretro.com/${platform.libretro_slug}/Named_Boxarts/${rom.fs_name_no_ext}.png`"
|
||||
target="_blank"
|
||||
class="mr-1"
|
||||
>
|
||||
<v-chip class="px-0 mt-1" size="small" title="Libretro match">
|
||||
<v-avatar variant="text" size="30" rounded="0">
|
||||
<v-img src="/assets/scrappers/libretro.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
</a>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row
|
||||
|
||||
@@ -524,6 +524,16 @@ watch(
|
||||
<v-img src="/assets/scrappers/hltb.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="currentPlatform.libretro_slug"
|
||||
class="px-0 ml-1 mt-1"
|
||||
size="small"
|
||||
title="Libretro"
|
||||
>
|
||||
<v-avatar variant="text" class="bg-surface" size="30" rounded="0">
|
||||
<v-img src="/assets/scrappers/libretro.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else class="mt-2 text-center" no-gutters>
|
||||
|
||||
@@ -179,6 +179,16 @@ const { t } = useI18n();
|
||||
<v-img src="/assets/scrappers/esde.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="rom.libretro_id"
|
||||
class="pa-1 bg-surface"
|
||||
size="small"
|
||||
title="Libretro match"
|
||||
>
|
||||
<v-avatar variant="text" size="18" rounded>
|
||||
<v-img src="/assets/scrappers/libretro.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
</template>
|
||||
</template>
|
||||
</RomListItem>
|
||||
|
||||
@@ -299,6 +299,16 @@ function updateOptions({ sortBy }: { sortBy: SortBy }) {
|
||||
<v-img src="/assets/scrappers/esde.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="item.libretro_id"
|
||||
class="mr-1 pa-0 item-chip"
|
||||
size="x-small"
|
||||
title="Libretro match"
|
||||
>
|
||||
<v-avatar variant="text" size="20" rounded>
|
||||
<v-img src="/assets/scrappers/libretro.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="item.siblings.length > 0 && showSiblings"
|
||||
class="translucent mr-1 px-1 item-chip"
|
||||
|
||||
@@ -758,6 +758,16 @@ onMounted(async () => {
|
||||
>
|
||||
<v-img src="/assets/scrappers/hltb.png" />
|
||||
</v-avatar>
|
||||
|
||||
<v-avatar
|
||||
v-if="item.raw.libretro_slug"
|
||||
class="bg-surface"
|
||||
variant="text"
|
||||
size="25"
|
||||
rounded
|
||||
>
|
||||
<v-img src="/assets/scrappers/libretro.png" />
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else class="text-center" no-gutters>
|
||||
|
||||
@@ -302,13 +302,23 @@ async function stopScan() {
|
||||
|
||||
<v-avatar
|
||||
v-if="item.raw.hltb_slug"
|
||||
class="bg-surface"
|
||||
class="bg-surface mr-1"
|
||||
variant="text"
|
||||
size="25"
|
||||
rounded
|
||||
>
|
||||
<v-img src="/assets/scrappers/hltb.png" />
|
||||
</v-avatar>
|
||||
|
||||
<v-avatar
|
||||
v-if="item.raw.libretro_slug"
|
||||
class="bg-surface"
|
||||
variant="text"
|
||||
size="25"
|
||||
rounded
|
||||
>
|
||||
<v-img src="/assets/scrappers/libretro.png" />
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else class="text-center" no-gutters>
|
||||
|
||||
Reference in New Issue
Block a user