mirror of
https://github.com/rommapp/romm.git
synced 2026-02-19 07:50:57 +01:00
Revive giantbomb metadata handler
This commit is contained in:
@@ -15,7 +15,7 @@ PLATFORM_SLUG_TO_RETROACHIEVEMENTS_ID: dict[UPS, int] = {
|
||||
UPS.ARCADE: 27,
|
||||
UPS.ARCADIA_2001: 73,
|
||||
UPS.ARDUBOY: 71,
|
||||
UPS.ATARI_JAGUAR_CD: 77,
|
||||
UPS.JAGUAR_CD: 77,
|
||||
UPS.ATARI2600: 25,
|
||||
UPS.ATARI7800: 51,
|
||||
UPS.COLECOVISION: 44,
|
||||
|
||||
41
backend/alembic/versions/0057_add_giantbomb_metadata.py
Normal file
41
backend/alembic/versions/0057_add_giantbomb_metadata.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""empty message
|
||||
Revision ID: 0057_add_giantbomb_metadata
|
||||
Revises: 0056_gamelist_xml
|
||||
Create Date: 2025-09-19 21:37:14.878761
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "0057_add_giantbomb_metadata"
|
||||
down_revision = "0056_gamelist_xml"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
with op.batch_alter_table("platforms", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("giantbomb_id", sa.Integer(), nullable=True))
|
||||
with op.batch_alter_table("roms", schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column("giantbomb_id", sa.Integer(), nullable=True))
|
||||
batch_op.add_column(
|
||||
sa.Column(
|
||||
"giantbomb_metadata",
|
||||
sa.JSON().with_variant(
|
||||
postgresql.JSONB(astext_type=sa.Text()), "postgresql"
|
||||
),
|
||||
nullable=True,
|
||||
)
|
||||
)
|
||||
batch_op.create_index("idx_roms_giantbomb_id", ["giantbomb_id"], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
with op.batch_alter_table("roms", schema=None) as batch_op:
|
||||
batch_op.drop_index("idx_roms_giantbomb_id")
|
||||
batch_op.drop_column("giantbomb_metadata")
|
||||
batch_op.drop_column("giantbomb_id")
|
||||
with op.batch_alter_table("platforms", schema=None) as batch_op:
|
||||
batch_op.drop_column("giantbomb_id")
|
||||
@@ -108,6 +108,9 @@ FLASHPOINT_API_ENABLED: Final[bool] = safe_str_to_bool(
|
||||
# HOWLONGTOBEAT
|
||||
HLTB_API_ENABLED: Final[bool] = safe_str_to_bool(_get_env("HLTB_API_ENABLED"))
|
||||
|
||||
# GIANTBOMB
|
||||
GIANTBOMB_API_ENABLED: Final = safe_str_to_bool(_get_env("GIANTBOMB_API_ENABLED"))
|
||||
|
||||
# AUTH
|
||||
ROMM_AUTH_SECRET_KEY: Final[str | None] = _get_env("ROMM_AUTH_SECRET_KEY")
|
||||
if not ROMM_AUTH_SECRET_KEY:
|
||||
@@ -153,7 +156,8 @@ ENABLE_RESCAN_ON_FILESYSTEM_CHANGE: Final[bool] = safe_str_to_bool(
|
||||
_get_env("ENABLE_RESCAN_ON_FILESYSTEM_CHANGE")
|
||||
)
|
||||
RESCAN_ON_FILESYSTEM_CHANGE_DELAY: Final[int] = safe_int(
|
||||
_get_env("RESCAN_ON_FILESYSTEM_CHANGE_DELAY"), 5 # 5 minutes
|
||||
_get_env("RESCAN_ON_FILESYSTEM_CHANGE_DELAY"),
|
||||
5, # 5 minutes
|
||||
)
|
||||
ENABLE_SCHEDULED_RESCAN: Final[bool] = safe_str_to_bool(
|
||||
_get_env("ENABLE_SCHEDULED_RESCAN")
|
||||
|
||||
@@ -24,6 +24,7 @@ from handler.filesystem import fs_platform_handler
|
||||
from handler.metadata import (
|
||||
meta_flashpoint_handler,
|
||||
meta_gamelist_handler,
|
||||
meta_giantbomb_handler,
|
||||
meta_hasheous_handler,
|
||||
meta_hltb_handler,
|
||||
meta_igdb_handler,
|
||||
@@ -62,6 +63,7 @@ async def heartbeat() -> HeartbeatResponse:
|
||||
playmatch_enabled = meta_playmatch_handler.is_enabled()
|
||||
hltb_enabled = meta_hltb_handler.is_enabled()
|
||||
tgdb_enabled = meta_tgdb_handler.is_enabled()
|
||||
giantbomb_enabled = meta_giantbomb_handler.is_enabled()
|
||||
|
||||
return {
|
||||
"SYSTEM": {
|
||||
@@ -80,6 +82,7 @@ async def heartbeat() -> HeartbeatResponse:
|
||||
or tgdb_enabled
|
||||
or flashpoint_enabled
|
||||
or hltb_enabled
|
||||
or giantbomb_enabled
|
||||
),
|
||||
"IGDB_API_ENABLED": igdb_enabled,
|
||||
"SS_API_ENABLED": ss_enabled,
|
||||
@@ -92,6 +95,7 @@ async def heartbeat() -> HeartbeatResponse:
|
||||
"TGDB_API_ENABLED": tgdb_enabled,
|
||||
"FLASHPOINT_API_ENABLED": flashpoint_enabled,
|
||||
"HLTB_API_ENABLED": hltb_enabled,
|
||||
"GIANTBOMB_API_ENABLED": giantbomb_enabled,
|
||||
},
|
||||
"FILESYSTEM": {
|
||||
"FS_PLATFORMS": await fs_platform_handler.get_platforms(),
|
||||
@@ -153,5 +157,7 @@ async def metadata_heartbeat(source: str) -> bool:
|
||||
return await meta_hltb_handler.heartbeat()
|
||||
case MetadataSource.GAMELIST:
|
||||
return await meta_gamelist_handler.heartbeat()
|
||||
case MetadataSource.GIANTBOMB:
|
||||
return await meta_giantbomb_handler.heartbeat()
|
||||
case _:
|
||||
return False
|
||||
|
||||
@@ -19,6 +19,7 @@ class MetadataSourcesDict(TypedDict):
|
||||
TGDB_API_ENABLED: bool
|
||||
FLASHPOINT_API_ENABLED: bool
|
||||
HLTB_API_ENABLED: bool
|
||||
GIANTBOMB_API_ENABLED: bool
|
||||
|
||||
|
||||
class FilesystemDict(TypedDict):
|
||||
|
||||
@@ -17,6 +17,7 @@ class PlatformSchema(BaseModel):
|
||||
igdb_slug: str | None
|
||||
moby_slug: str | None
|
||||
hltb_slug: str | None
|
||||
giantbomb_slug: str | None = None
|
||||
custom_name: str | None = None
|
||||
igdb_id: int | None = None
|
||||
sgdb_id: int | None = None
|
||||
@@ -27,6 +28,7 @@ class PlatformSchema(BaseModel):
|
||||
hasheous_id: int | None = None
|
||||
tgdb_id: int | None = None
|
||||
flashpoint_id: int | None = None
|
||||
giantbomb_id: int | None = None
|
||||
category: str | None = None
|
||||
generation: int | None = None
|
||||
family_name: str | None = None
|
||||
|
||||
@@ -10,6 +10,7 @@ from pydantic import Field, computed_field, field_validator
|
||||
from endpoints.responses.assets import SaveSchema, ScreenshotSchema, StateSchema
|
||||
from handler.metadata.flashpoint_handler import FlashpointMetadata
|
||||
from handler.metadata.gamelist_handler import GamelistMetadata
|
||||
from handler.metadata.giantbomb_handler import GiantBombMetadata
|
||||
from handler.metadata.hasheous_handler import HasheousMetadata
|
||||
from handler.metadata.hltb_handler import HLTBMetadata
|
||||
from handler.metadata.igdb_handler import IGDBMetadata
|
||||
@@ -69,6 +70,11 @@ RomGamelistMetadata = TypedDict( # type: ignore[misc]
|
||||
{k: NotRequired[v] for k, v in get_type_hints(GamelistMetadata).items()}, # type: ignore[misc]
|
||||
total=False,
|
||||
)
|
||||
RomGiantBombMetadata = TypedDict( # type: ignore[misc]
|
||||
"RomGiantBombMetadata",
|
||||
{k: NotRequired[v] for k, v in get_type_hints(GiantBombMetadata).items()}, # type: ignore[misc]
|
||||
total=False,
|
||||
)
|
||||
|
||||
|
||||
def rom_user_schema_factory() -> RomUserSchema:
|
||||
@@ -210,6 +216,7 @@ class RomSchema(BaseModel):
|
||||
flashpoint_id: str | None
|
||||
hltb_id: int | None
|
||||
gamelist_id: str | None
|
||||
giantbomb_id: int | None
|
||||
|
||||
platform_id: int
|
||||
platform_slug: str
|
||||
@@ -240,6 +247,7 @@ class RomSchema(BaseModel):
|
||||
flashpoint_metadata: RomFlashpointMetadata | None
|
||||
hltb_metadata: RomHLTBMetadata | None
|
||||
gamelist_metadata: RomGamelistMetadata | None
|
||||
giantbomb_metadata: RomGiantBombMetadata | None
|
||||
|
||||
path_cover_small: str | None
|
||||
path_cover_large: str | None
|
||||
|
||||
@@ -240,6 +240,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
Rom.hasheous_id.isnot(None),
|
||||
Rom.tgdb_id.isnot(None),
|
||||
Rom.flashpoint_id.isnot(None),
|
||||
Rom.giantbomb_id.isnot(None),
|
||||
)
|
||||
if not value:
|
||||
predicate = not_(predicate)
|
||||
@@ -465,6 +466,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
base_subquery.c.launchbox_id,
|
||||
base_subquery.c.tgdb_id,
|
||||
base_subquery.c.flashpoint_id,
|
||||
base_subquery.c.giantbomb_id,
|
||||
)
|
||||
.outerjoin(
|
||||
RomUser,
|
||||
@@ -516,6 +518,11 @@ class DBRomsHandler(DBBaseHandler):
|
||||
base_subquery.c.flashpoint_id,
|
||||
base_subquery.c.platform_id,
|
||||
),
|
||||
_create_metadata_id_case(
|
||||
MetadataSource.GIANTBOMB,
|
||||
base_subquery.c.giantbomb_id,
|
||||
base_subquery.c.platform_id,
|
||||
),
|
||||
_create_metadata_id_case(
|
||||
"romm",
|
||||
base_subquery.c.id,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from .flashpoint_handler import FlashpointHandler
|
||||
from .gamelist_handler import GamelistHandler
|
||||
from .giantbomb_handler import GiantBombHandler
|
||||
from .hasheous_handler import HasheousHandler
|
||||
from .hltb_handler import HLTBHandler
|
||||
from .igdb_handler import IGDBHandler
|
||||
@@ -23,3 +24,4 @@ meta_tgdb_handler = TGDBHandler()
|
||||
meta_flashpoint_handler = FlashpointHandler()
|
||||
meta_gamelist_handler = GamelistHandler()
|
||||
meta_hltb_handler = HLTBHandler()
|
||||
meta_giantbomb_handler = GiantBombHandler()
|
||||
|
||||
@@ -304,7 +304,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
ARDUBOY = "arduboy"
|
||||
ASTRAL_2000 = "astral-2000"
|
||||
ASTROCADE = "astrocade"
|
||||
ATARI_JAGUAR_CD = "atari-jaguar-cd"
|
||||
JAGUAR_CD = "atari-jaguar-cd"
|
||||
ATARI_ST = "atari-st"
|
||||
ATARI_VCS = "atari-vcs"
|
||||
ATARI_XEGS = "atari-xegs"
|
||||
@@ -371,6 +371,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
DC = "dc"
|
||||
DEDICATED_CONSOLE = "dedicated-console"
|
||||
DEDICATED_HANDHELD = "dedicated-handheld"
|
||||
DENSHI_MANGAJUKU = "denshi-mangajuku"
|
||||
DIDJ = "didj"
|
||||
DIGIBLAST = "digiblast"
|
||||
DOJA = "doja"
|
||||
@@ -406,6 +407,8 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
GAME_WAVE = "game-wave"
|
||||
GAMEGEAR = "gamegear"
|
||||
GAMESTICK = "gamestick"
|
||||
GAMEKING = "gameking"
|
||||
GAMEKINGIII = "gamekingiii"
|
||||
GB = "gb"
|
||||
GBA = "gba"
|
||||
GBC = "gbc"
|
||||
@@ -421,6 +424,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
GP32 = "gp32"
|
||||
GT40 = "gt40"
|
||||
GVM = "gvm"
|
||||
HALCYON = "halcyon"
|
||||
HANDHELD_ELECTRONIC_LCD = "handheld-electronic-lcd"
|
||||
HARTUNG = "hartung"
|
||||
HD_DVD_PLAYER = "hd-dvd-player"
|
||||
@@ -472,6 +476,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
LYNX = "lynx"
|
||||
MAC = "mac"
|
||||
MAEMO = "maemo"
|
||||
MAGIC_LEAP_ONE = "magic-leap-one"
|
||||
MAINFRAME = "mainframe"
|
||||
MATSUSHITAPANASONIC_JR = "matsushitapanasonic-jr"
|
||||
MEEGO = "meego"
|
||||
@@ -489,6 +494,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
MODEL1 = "model1"
|
||||
MODEL2 = "model2"
|
||||
MODEL3 = "model3"
|
||||
MONON_COLOR = "monon-color"
|
||||
MOPHUN = "mophun"
|
||||
MOS_TECHNOLOGY_6502 = "mos-technology-6502"
|
||||
MOTOROLA_6800 = "motorola-6800"
|
||||
@@ -500,6 +506,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
MSX2PLUS = "msx2plus"
|
||||
MTX512 = "mtx512"
|
||||
MUGEN = "mugen"
|
||||
MULTI_8 = "multi-8"
|
||||
MULTIVISION = "multivision"
|
||||
N3DS = "3ds"
|
||||
N64 = "n64"
|
||||
@@ -592,6 +599,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
RCA_STUDIO_II = "rca-studio-ii"
|
||||
RESEARCH_MACHINES_380Z = "research-machines-380z"
|
||||
ROKU = "roku"
|
||||
RX_78 = "rx-78"
|
||||
SAM_COUPE = "sam-coupe"
|
||||
SATELLAVIEW = "satellaview"
|
||||
SATURN = "saturn"
|
||||
@@ -604,6 +612,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
SEGA32 = "sega32"
|
||||
SEGACD = "segacd"
|
||||
SEGACD32 = "segacd32"
|
||||
SELECT_A_GAME = "select-a-game"
|
||||
SERIES_X_S = "series-x-s"
|
||||
SFAM = "sfam"
|
||||
SG1000 = "sg1000"
|
||||
@@ -615,6 +624,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
SIGNETICS_2650 = "signetics-2650"
|
||||
SINCLAIR_QL = "sinclair-ql"
|
||||
SK_VM = "sk-vm"
|
||||
SMAKY = "smaky"
|
||||
SMC_777 = "smc-777"
|
||||
SMS = "sms"
|
||||
SNES = "snes"
|
||||
@@ -625,6 +635,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
SRI_5001000 = "sri-5001000"
|
||||
STADIA = "stadia"
|
||||
STEAM_VR = "steam-vr"
|
||||
STREAMING = "streaming"
|
||||
STV = "stv"
|
||||
SUFAMI_TURBO = "sufami-turbo"
|
||||
SUPER_ACAN = "super-acan"
|
||||
@@ -673,6 +684,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
TRS_80_MC_10 = "trs-80-mc-10"
|
||||
TRS_80_MODEL_100 = "trs-80-model-100"
|
||||
TURBOGRAFX_CD = "turbografx-cd"
|
||||
TVBOY = "tvboy"
|
||||
TVOS = "tvos"
|
||||
TYPE_X = "type-x"
|
||||
UZEBOX = "uzebox"
|
||||
@@ -685,6 +697,7 @@ class UniversalPlatformSlug(enum.StrEnum):
|
||||
VIC_20 = "vic-20"
|
||||
VIDEOBRAIN = "videobrain"
|
||||
VIDEOPAC_G7400 = "videopac-g7400"
|
||||
VIEW_MASTER = "view-master"
|
||||
VIRTUALBOY = "virtualboy"
|
||||
VIS = "vis"
|
||||
VISIONOS = "visionos"
|
||||
|
||||
1631
backend/handler/metadata/giantbomb_handler.py
Normal file
1631
backend/handler/metadata/giantbomb_handler.py
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -558,7 +558,7 @@ HLTB_PLATFORM_LIST: dict[UPS, SlugToHLTBPlatform] = {
|
||||
"count": 259,
|
||||
},
|
||||
UPS.JAGUAR: {"name": "Atari Jaguar", "slug": "atari-jaguar", "count": 64},
|
||||
UPS.ATARI_JAGUAR_CD: {
|
||||
UPS.JAGUAR_CD: {
|
||||
"name": "Atari Jaguar CD",
|
||||
"slug": "atari-jaguar-cd",
|
||||
"count": 14,
|
||||
|
||||
@@ -547,9 +547,9 @@ class IGDBHandler(MetadataHandler):
|
||||
list(
|
||||
map(
|
||||
lambda rom: (
|
||||
f'id={pydash.get(rom, "game.id", "")}'
|
||||
f"id={pydash.get(rom, 'game.id', '')}"
|
||||
if "game" in rom.keys()
|
||||
else f'id={rom.get("id", "")}'
|
||||
else f"id={rom.get('id', '')}"
|
||||
),
|
||||
alternative_matched_roms,
|
||||
)
|
||||
@@ -1216,7 +1216,7 @@ IGDB_PLATFORM_LIST: dict[UPS, SlugToIGDB] = {
|
||||
"url": "https://www.igdb.com/platforms/astrocade",
|
||||
"url_logo": "",
|
||||
},
|
||||
UPS.ATARI_JAGUAR_CD: {
|
||||
UPS.JAGUAR_CD: {
|
||||
"category": "Console",
|
||||
"family_name": "Atari",
|
||||
"family_slug": "atari",
|
||||
|
||||
@@ -362,7 +362,7 @@ LAUNCHBOX_PLATFORM_LIST: dict[UPS, SlugToLaunchboxId] = {
|
||||
UPS.ARCADE: {"id": 5, "name": "Arcade"},
|
||||
UPS.ARCADIA_2001: {"id": 79, "name": "Emerson Arcadia 2001"},
|
||||
UPS.ASTROCADE: {"id": 77, "name": "Bally Astrocade"},
|
||||
UPS.ATARI_JAGUAR_CD: {"id": 10, "name": "Atari Jaguar CD"},
|
||||
UPS.JAGUAR_CD: {"id": 10, "name": "Atari Jaguar CD"},
|
||||
UPS.ATARI_ST: {"id": 76, "name": "Atari ST"},
|
||||
UPS.ATARI_XEGS: {"id": 12, "name": "Atari XEGS"},
|
||||
UPS.ATARI2600: {"id": 6, "name": "Atari 2600"},
|
||||
|
||||
@@ -391,7 +391,7 @@ RA_PLATFORM_LIST: dict[UPS, SlugToRAId] = {
|
||||
UPS.ARDUBOY: {"id": 71, "name": "Arduboy"},
|
||||
UPS.ATARI2600: {"id": 25, "name": "Atari 2600"},
|
||||
UPS.ATARI7800: {"id": 51, "name": "Atari 7800"},
|
||||
UPS.ATARI_JAGUAR_CD: {"id": 77, "name": "Atari Jaguar CD"},
|
||||
UPS.JAGUAR_CD: {"id": 77, "name": "Atari Jaguar CD"},
|
||||
UPS.COLECOVISION: {"id": 44, "name": "ColecoVision"},
|
||||
UPS.DC: {"id": 40, "name": "Dreamcast"},
|
||||
UPS.ELEKTOR: {"id": 75, "name": "Elektor"},
|
||||
|
||||
@@ -348,7 +348,7 @@ TGDB_PLATFORM_LIST: dict[UPS, SlugToTGDBId] = {
|
||||
"summary": "The Atari Jaguar is a video game console that was released by Atari Corporation in 1993. It was the last to be marketed under the Atari brand until the release of the Atari Flashback in 2004. It was designed to surpass the Mega Drive/Genesis, Super Nintendo Entertainment System, and the Panasonic 3DO in processing power. Although launched one year earlier, it was eventually in competition with the Sega Saturn, the Sony PlayStation, and other consoles that made up the fifth generation of video game consoles. The console was first released in New York City and San Francisco on November 23, 1993, and the rest of the country in early 1994. Although it was promoted as the first 64-bit gaming system, the Jaguar proved to be a commercial failure and prompted Atari to leave the home video game console market. Despite its commercial failure, the Jaguar has a dedicated fan base that produces homebrew games for it.",
|
||||
"url_logo": "https://cdn.thegamesdb.net/images/original/platform/boxart/28-2.jpg",
|
||||
},
|
||||
UPS.ATARI_JAGUAR_CD: {
|
||||
UPS.JAGUAR_CD: {
|
||||
"id": 29,
|
||||
"name": "Atari Jaguar CD",
|
||||
"manufacturer": "Atari",
|
||||
|
||||
@@ -12,6 +12,7 @@ from handler.filesystem.roms_handler import FSRom
|
||||
from handler.metadata import (
|
||||
meta_flashpoint_handler,
|
||||
meta_gamelist_handler,
|
||||
meta_giantbomb_handler,
|
||||
meta_hasheous_handler,
|
||||
meta_hltb_handler,
|
||||
meta_igdb_handler,
|
||||
@@ -70,6 +71,7 @@ class MetadataSource(enum.StrEnum):
|
||||
FLASHPOINT = "flashpoint" # Flashpoint Project
|
||||
HLTB = "hltb" # HowLongToBeat
|
||||
GAMELIST = "gamelist" # ES-DE gamelist.xml
|
||||
GIANTBOMB = "giantbomb" # Giantbomb
|
||||
|
||||
|
||||
def get_main_platform_igdb_id(platform: Platform):
|
||||
@@ -178,6 +180,7 @@ 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"])
|
||||
giantbomb_platform = meta_giantbomb_handler.get_platform(platform_attrs["slug"])
|
||||
|
||||
platform_attrs["name"] = platform_attrs["slug"].replace("-", " ").title()
|
||||
platform_attrs.update(
|
||||
@@ -198,6 +201,9 @@ async def scan_platform(
|
||||
"tgdb_id": moby_platform.get("tgdb_id")
|
||||
or hasheous_platform.get("tgdb_id")
|
||||
or None,
|
||||
"giantbomb_id": giantbomb_platform.get("giantbomb_id")
|
||||
or hasheous_platform.get("giantbomb_id")
|
||||
or None,
|
||||
"name": igdb_platform.get("name")
|
||||
or ss_platform.get("name")
|
||||
or moby_platform.get("name")
|
||||
@@ -207,9 +213,11 @@ async def scan_platform(
|
||||
or tgdb_platform.get("name")
|
||||
or flashpoint_platform.get("name")
|
||||
or hltb_platform.get("name")
|
||||
or giantbomb_platform.get("name")
|
||||
or platform_attrs["slug"].replace("-", " ").title(),
|
||||
"url_logo": igdb_platform.get("url_logo")
|
||||
or tgdb_platform.get("url_logo")
|
||||
or giantbomb_platform.get("url_logo")
|
||||
or "",
|
||||
}
|
||||
)
|
||||
@@ -447,7 +455,7 @@ async def scan_rom(
|
||||
if playmatch_rom["igdb_id"] is not None:
|
||||
log.debug(
|
||||
f"{hl(rom_attrs['fs_name'])} identified by Playmatch as "
|
||||
f"{hl(str(playmatch_rom["igdb_id"]), color=BLUE)} {emoji.EMOJI_ALIEN_MONSTER}",
|
||||
f"{hl(str(playmatch_rom['igdb_id']), color=BLUE)} {emoji.EMOJI_ALIEN_MONSTER}",
|
||||
extra=LOGGER_MODULE_NAME,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import cached_property
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import Integer, String, func, select
|
||||
@@ -28,6 +29,7 @@ class Platform(BaseModel):
|
||||
hasheous_id: Mapped[int | None] = mapped_column(Integer(), default=None)
|
||||
tgdb_id: Mapped[int | None] = mapped_column(Integer(), default=None)
|
||||
flashpoint_id: Mapped[int | None] = mapped_column(Integer(), default=None)
|
||||
giantbomb_id: Mapped[int | None] = mapped_column(Integer(), default=None)
|
||||
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)
|
||||
@@ -80,11 +82,20 @@ class Platform(BaseModel):
|
||||
and not self.launchbox_id
|
||||
and not self.ra_id
|
||||
and not self.hasheous_id
|
||||
and not self.tgdb_id
|
||||
and not self.giantbomb_id
|
||||
)
|
||||
|
||||
@property
|
||||
def is_identified(self) -> bool:
|
||||
return not self.is_unidentified
|
||||
|
||||
@cached_property
|
||||
def giantbomb_slug(self) -> str | None:
|
||||
from handler.metadata import meta_giantbomb_handler
|
||||
|
||||
giantbomb_platform = meta_giantbomb_handler.get_platform(self.slug)
|
||||
return giantbomb_platform.get("slug", None)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.name} ({self.slug}) ({self.id})"
|
||||
|
||||
@@ -156,6 +156,7 @@ class Rom(BaseModel):
|
||||
flashpoint_id: Mapped[str | None] = mapped_column(String(length=100), default=None)
|
||||
hltb_id: Mapped[int | None] = mapped_column(Integer(), default=None)
|
||||
gamelist_id: Mapped[str | None] = mapped_column(String(length=100), default=None)
|
||||
giantbomb_id: Mapped[int | None] = mapped_column(Integer(), default=None)
|
||||
|
||||
__table_args__ = (
|
||||
Index("idx_roms_igdb_id", "igdb_id"),
|
||||
@@ -169,6 +170,7 @@ class Rom(BaseModel):
|
||||
Index("idx_roms_flashpoint_id", "flashpoint_id"),
|
||||
Index("idx_roms_hltb_id", "hltb_id"),
|
||||
Index("idx_roms_gamelist_id", "gamelist_id"),
|
||||
Index("idx_roms_giantbomb_id", "giantbomb_id"),
|
||||
)
|
||||
|
||||
fs_name: Mapped[str] = mapped_column(String(length=FILE_NAME_MAX_LENGTH))
|
||||
@@ -208,6 +210,9 @@ class Rom(BaseModel):
|
||||
gamelist_metadata: Mapped[dict[str, Any] | None] = mapped_column(
|
||||
CustomJSON(), default=dict
|
||||
)
|
||||
giantbomb_metadata: Mapped[dict[str, Any] | None] = mapped_column(
|
||||
CustomJSON(), default=dict
|
||||
)
|
||||
|
||||
path_cover_s: Mapped[str | None] = mapped_column(Text, default="")
|
||||
path_cover_l: Mapped[str | None] = mapped_column(Text, default="")
|
||||
@@ -350,6 +355,7 @@ class Rom(BaseModel):
|
||||
and not self.flashpoint_id
|
||||
and not self.hltb_id
|
||||
and not self.gamelist_id
|
||||
and not self.giantbomb_id
|
||||
)
|
||||
|
||||
@property
|
||||
|
||||
@@ -5,6 +5,7 @@ from config import (
|
||||
from endpoints.sockets.scan import ScanStats, scan_platforms
|
||||
from handler.metadata import (
|
||||
meta_flashpoint_handler,
|
||||
meta_giantbomb_handler,
|
||||
meta_hasheous_handler,
|
||||
meta_hltb_handler,
|
||||
meta_igdb_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.GIANTBOMB: meta_giantbomb_handler.is_enabled(),
|
||||
}
|
||||
|
||||
metadata_sources = [source for source, flag in source_mapping.items() if flag]
|
||||
|
||||
@@ -36,6 +36,8 @@ def test_heartbeat(client):
|
||||
assert isinstance(metadata["HASHEOUS_API_ENABLED"], bool)
|
||||
assert isinstance(metadata["TGDB_API_ENABLED"], bool)
|
||||
assert isinstance(metadata["FLASHPOINT_API_ENABLED"], bool)
|
||||
assert isinstance(metadata["HLTB_API_ENABLED"], bool)
|
||||
assert isinstance(metadata["GIANTBOMB_API_ENABLED"], bool)
|
||||
|
||||
assert "FILESYSTEM" in heartbeat
|
||||
filesystem = heartbeat["FILESYSTEM"]
|
||||
|
||||
@@ -3,6 +3,7 @@ from typing import TypedDict
|
||||
|
||||
from handler.metadata import (
|
||||
meta_flashpoint_handler,
|
||||
meta_giantbomb_handler,
|
||||
meta_hasheous_handler,
|
||||
meta_hltb_handler,
|
||||
meta_igdb_handler,
|
||||
@@ -25,6 +26,7 @@ class SupportedPlatform(TypedDict):
|
||||
ra_id: int | None
|
||||
flashpoint_id: int | None
|
||||
hltb_slug: str | None
|
||||
giantbomb_url: 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)
|
||||
giantbomb_platform = meta_giantbomb_handler.get_platform(slug_lower)
|
||||
|
||||
supported_platforms[slug_lower] = {
|
||||
"name": igdb_platform.get("name", None)
|
||||
@@ -51,6 +54,7 @@ if __name__ == "__main__":
|
||||
or ra_platform.get("name", None)
|
||||
or flashpoint_platform.get("name", None)
|
||||
or hltb_platform.get("name", None)
|
||||
or giantbomb_platform.get("name", None)
|
||||
or slug_lower.replace("-", " ").title(),
|
||||
"folder": slug_lower,
|
||||
"igdb_slug": igdb_platform.get("igdb_slug", None),
|
||||
@@ -61,6 +65,7 @@ if __name__ == "__main__":
|
||||
"ra_id": ra_platform["ra_id"],
|
||||
"flashpoint_id": flashpoint_platform["flashpoint_id"],
|
||||
"hltb_slug": hltb_platform.get("hltb_slug", None),
|
||||
"giantbomb_url": giantbomb_platform.get("url_logo", None),
|
||||
}
|
||||
|
||||
# Sort platforms by name field
|
||||
@@ -75,8 +80,8 @@ if __name__ == "__main__":
|
||||
|
||||
for platform in supported_platforms.values():
|
||||
print(
|
||||
f'| {platform["name"]} |',
|
||||
f'`{platform["folder"]}` |',
|
||||
f"| {platform['name']} |",
|
||||
f"`{platform['folder']}` |",
|
||||
(
|
||||
f'<a href="https://www.igdb.com/platforms/{platform["igdb_slug"]}" target="_blank" rel="noopener noreferrer"><img alt="igdb logo" src="../../resources/metadata_providers/igdb.png" height="24px" width="24px"></a>'
|
||||
if platform["igdb_slug"]
|
||||
@@ -117,5 +122,10 @@ if __name__ == "__main__":
|
||||
if platform["hltb_slug"]
|
||||
else ""
|
||||
),
|
||||
(
|
||||
f'<a href="{platform["giantbomb_url"]}" target="_blank" rel="noopener noreferrer"><img alt="giantbomb logo" src="../../resources/metadata_providers/giantbomb.png" height="24px" width="24px"></a>'
|
||||
if platform["giantbomb_url"]
|
||||
else ""
|
||||
),
|
||||
" |",
|
||||
)
|
||||
|
||||
@@ -37,6 +37,9 @@ HLTB_API_ENABLED=
|
||||
# TheGamesDB
|
||||
TGDB_API_ENABLED=
|
||||
|
||||
# GiantBomb
|
||||
GIANTBOMB_API_ENABLED=
|
||||
|
||||
# Database config
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
|
||||
BIN
frontend/assets/scrappers/giantbomb.png
Normal file
BIN
frontend/assets/scrappers/giantbomb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 540 KiB |
1
frontend/src/__generated__/index.ts
generated
1
frontend/src/__generated__/index.ts
generated
@@ -61,6 +61,7 @@ export type { RomFileCategory } from './models/RomFileCategory';
|
||||
export type { RomFileSchema } from './models/RomFileSchema';
|
||||
export type { RomFlashpointMetadata } from './models/RomFlashpointMetadata';
|
||||
export type { RomGamelistMetadata } from './models/RomGamelistMetadata';
|
||||
export type { RomGiantBombMetadata } from './models/RomGiantBombMetadata';
|
||||
export type { RomHasheousMetadata } from './models/RomHasheousMetadata';
|
||||
export type { RomHLTBMetadata } from './models/RomHLTBMetadata';
|
||||
export type { RomIGDBMetadata } from './models/RomIGDBMetadata';
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import type { RomFileSchema } from './RomFileSchema';
|
||||
import type { RomFlashpointMetadata } from './RomFlashpointMetadata';
|
||||
import type { RomGamelistMetadata } from './RomGamelistMetadata';
|
||||
import type { RomGiantBombMetadata } from './RomGiantBombMetadata';
|
||||
import type { RomHasheousMetadata } from './RomHasheousMetadata';
|
||||
import type { RomHLTBMetadata } from './RomHLTBMetadata';
|
||||
import type { RomIGDBMetadata } from './RomIGDBMetadata';
|
||||
@@ -33,6 +34,7 @@ export type DetailedRomSchema = {
|
||||
flashpoint_id: (string | null);
|
||||
hltb_id: (number | null);
|
||||
gamelist_id: (string | null);
|
||||
giantbomb_id: (number | null);
|
||||
platform_id: number;
|
||||
platform_slug: string;
|
||||
platform_fs_slug: string;
|
||||
@@ -58,6 +60,7 @@ export type DetailedRomSchema = {
|
||||
flashpoint_metadata: (RomFlashpointMetadata | null);
|
||||
hltb_metadata: (RomHLTBMetadata | null);
|
||||
gamelist_metadata: (RomGamelistMetadata | null);
|
||||
giantbomb_metadata: (RomGiantBombMetadata | null);
|
||||
path_cover_small: (string | null);
|
||||
path_cover_large: (string | null);
|
||||
url_cover: (string | null);
|
||||
|
||||
@@ -15,5 +15,6 @@ export type MetadataSourcesDict = {
|
||||
TGDB_API_ENABLED: boolean;
|
||||
FLASHPOINT_API_ENABLED: boolean;
|
||||
HLTB_API_ENABLED: boolean;
|
||||
GIANTBOMB_API_ENABLED: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ export type PlatformSchema = {
|
||||
igdb_slug: (string | null);
|
||||
moby_slug: (string | null);
|
||||
hltb_slug: (string | null);
|
||||
giantbomb_slug?: (string | null);
|
||||
custom_name?: (string | null);
|
||||
igdb_id?: (number | null);
|
||||
sgdb_id?: (number | null);
|
||||
@@ -22,6 +23,7 @@ export type PlatformSchema = {
|
||||
hasheous_id?: (number | null);
|
||||
tgdb_id?: (number | null);
|
||||
flashpoint_id?: (number | null);
|
||||
giantbomb_id?: (number | null);
|
||||
category?: (string | null);
|
||||
generation?: (number | null);
|
||||
family_name?: (string | null);
|
||||
|
||||
15
frontend/src/__generated__/models/RomGiantBombMetadata.ts
generated
Normal file
15
frontend/src/__generated__/models/RomGiantBombMetadata.ts
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type RomGiantBombMetadata = {
|
||||
guid?: string;
|
||||
alternative_names?: Array<string>;
|
||||
deck?: string;
|
||||
description?: string;
|
||||
first_release_date?: string;
|
||||
image?: Record<string, any>;
|
||||
age_ratings?: Array<string>;
|
||||
site_url?: string;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import type { RomFileSchema } from './RomFileSchema';
|
||||
import type { RomFlashpointMetadata } from './RomFlashpointMetadata';
|
||||
import type { RomGamelistMetadata } from './RomGamelistMetadata';
|
||||
import type { RomGiantBombMetadata } from './RomGiantBombMetadata';
|
||||
import type { RomHasheousMetadata } from './RomHasheousMetadata';
|
||||
import type { RomHLTBMetadata } from './RomHLTBMetadata';
|
||||
import type { RomIGDBMetadata } from './RomIGDBMetadata';
|
||||
@@ -27,6 +28,7 @@ export type SimpleRomSchema = {
|
||||
flashpoint_id: (string | null);
|
||||
hltb_id: (number | null);
|
||||
gamelist_id: (string | null);
|
||||
giantbomb_id: (number | null);
|
||||
platform_id: number;
|
||||
platform_slug: string;
|
||||
platform_fs_slug: string;
|
||||
@@ -52,6 +54,7 @@ export type SimpleRomSchema = {
|
||||
flashpoint_metadata: (RomFlashpointMetadata | null);
|
||||
hltb_metadata: (RomHLTBMetadata | null);
|
||||
gamelist_metadata: (RomGamelistMetadata | null);
|
||||
giantbomb_metadata: (RomGiantBombMetadata | null);
|
||||
path_cover_small: (string | null);
|
||||
path_cover_large: (string | null);
|
||||
url_cover: (string | null);
|
||||
|
||||
@@ -77,6 +77,11 @@ const dataSources = computed(() => {
|
||||
condition: props.rom.hltb_id,
|
||||
url: `https://howlongtobeat.com/game/${props.rom.hltb_id}`,
|
||||
},
|
||||
{
|
||||
name: "Giant Bomb",
|
||||
condition: props.rom.giantbomb_id,
|
||||
url: props.rom.giantbomb_metadata?.site_url,
|
||||
},
|
||||
].filter((source) => source.condition);
|
||||
});
|
||||
|
||||
@@ -108,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 === "giantbomb") return "Giantbomb";
|
||||
|
||||
return null;
|
||||
} catch {
|
||||
|
||||
@@ -333,6 +333,20 @@ const hashMatches = computed(() => {
|
||||
<span>{{ rom.sgdb_id }}</span>
|
||||
</v-chip>
|
||||
</a>
|
||||
<a
|
||||
v-if="rom.giantbomb_id"
|
||||
style="text-decoration: none; color: inherit"
|
||||
:href="rom.giantbomb_metadata?.site_url"
|
||||
target="_blank"
|
||||
class="mr-1"
|
||||
>
|
||||
<v-chip class="pl-0 mt-1" size="small" title="Giant Bomb ID">
|
||||
<v-avatar variant="text" class="mr-2" size="30" rounded="0">
|
||||
<v-img src="/assets/scrappers/giantbomb.png" />
|
||||
</v-avatar>
|
||||
<span>{{ rom.giantbomb_id }}</span>
|
||||
</v-chip>
|
||||
</a>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row
|
||||
|
||||
@@ -439,6 +439,20 @@ watch(
|
||||
<v-img src="/assets/scrappers/hltb.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<a
|
||||
v-if="currentPlatform.giantbomb_id"
|
||||
style="text-decoration: none; color: inherit"
|
||||
:href="`https://www.giantbomb.com/${currentPlatform.giantbomb_slug}/3045-${currentPlatform.giantbomb_id}`"
|
||||
target="_blank"
|
||||
class="ml-1"
|
||||
>
|
||||
<v-chip class="pl-0 mt-1" size="small" @click.stop>
|
||||
<v-avatar variant="text" class="mr-2" size="30" rounded="0">
|
||||
<v-img src="/assets/scrappers/giantbomb.png" />
|
||||
</v-avatar>
|
||||
<span>{{ currentPlatform.giantbomb_id }}</span>
|
||||
</v-chip>
|
||||
</a>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row
|
||||
|
||||
@@ -281,6 +281,16 @@ function updateOptions({ sortBy }: { sortBy: SortBy }) {
|
||||
<v-img src="/assets/scrappers/esde.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="item.giantbomb_id"
|
||||
class="mr-1 pa-0 item-chip"
|
||||
size="x-small"
|
||||
title="Giant Bomb match"
|
||||
>
|
||||
<v-avatar variant="text" size="20" rounded>
|
||||
<v-img src="/assets/scrappers/giantbomb.png" />
|
||||
</v-avatar>
|
||||
</v-chip>
|
||||
<v-chip
|
||||
v-if="item.siblings.length > 0 && showSiblings"
|
||||
class="translucent text-white mr-1 px-1 item-chip"
|
||||
|
||||
@@ -285,6 +285,7 @@ async function updateRom({
|
||||
formData.append("hasheous_id", rom.hasheous_id?.toString() || "");
|
||||
formData.append("tgdb_id", rom.tgdb_id?.toString() || "");
|
||||
formData.append("hltb_id", rom.hltb_id?.toString() || "");
|
||||
formData.append("giantbomb_id", rom.giantbomb_id?.toString() || "");
|
||||
|
||||
if (rom.raw_metadata?.igdb_metadata) {
|
||||
formData.append("raw_igdb_metadata", rom.raw_metadata.igdb_metadata);
|
||||
|
||||
@@ -30,6 +30,7 @@ const defaultHeartbeat: Heartbeat = {
|
||||
TGDB_API_ENABLED: false,
|
||||
FLASHPOINT_API_ENABLED: false,
|
||||
HLTB_API_ENABLED: false,
|
||||
GIANTBOMB_API_ENABLED: false,
|
||||
},
|
||||
FILESYSTEM: {
|
||||
FS_PLATFORMS: [],
|
||||
@@ -168,6 +169,14 @@ export default defineStore("heartbeat", {
|
||||
logo_path: "/assets/scrappers/esde.png",
|
||||
disabled: "",
|
||||
},
|
||||
{
|
||||
name: "Giant Bomb",
|
||||
value: "giantbomb",
|
||||
logo_path: "/assets/scrappers/giantbomb.png",
|
||||
disabled: !this.value.METADATA_SOURCES?.GIANTBOMB_API_ENABLED
|
||||
? i18n.global.t("scan.api-key-missing")
|
||||
: "",
|
||||
},
|
||||
];
|
||||
},
|
||||
getEnabledMetadataOptions(): MetadataOption[] {
|
||||
|
||||
@@ -73,6 +73,12 @@ const metadataOptions = computed(() => [
|
||||
logo_path: "/assets/scrappers/sgdb.png",
|
||||
disabled: !heartbeat.value.METADATA_SOURCES?.STEAMGRIDDB_API_ENABLED,
|
||||
},
|
||||
{
|
||||
name: "Giant Bomb",
|
||||
value: "giantbomb",
|
||||
logo_path: "/assets/scrappers/giantbomb.png",
|
||||
disabled: !heartbeat.value.METADATA_SOURCES?.GIANTBOMB_API_ENABLED,
|
||||
},
|
||||
]);
|
||||
const defaultAdminUser = ref({
|
||||
username: "",
|
||||
|
||||
@@ -257,6 +257,16 @@ async function stopScan() {
|
||||
>
|
||||
<v-img src="/assets/scrappers/hltb.png" />
|
||||
</v-avatar>
|
||||
|
||||
<v-avatar
|
||||
v-if="item.raw.giantbomb_id"
|
||||
class="bg-surface"
|
||||
variant="text"
|
||||
size="25"
|
||||
rounded
|
||||
>
|
||||
<v-img src="/assets/scrappers/giantbomb.png" />
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row
|
||||
|
||||
Reference in New Issue
Block a user