diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 02c01f597..7fcdcc88f 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -18,30 +18,32 @@ runtimes: # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) lint: disabled: + - svgo + - oxipng - pyright enabled: - dotenv-linter@3.3.0 - hadolint@2.13.1 - markdownlint@0.45.0 - - eslint@9.34.0 + - eslint@9.35.0 - actionlint@1.7.7 - bandit@1.8.6 - black@25.1.0 - - checkov@3.2.469 + - checkov@3.2.471 - git-diff-check - isort@6.0.1 - - mypy@1.17.1 + - mypy@1.18.1 - osv-scanner@2.2.2 - prettier@3.6.2: packages: - "@trivago/prettier-plugin-sort-imports@5.2.2" - "@vue/compiler-sfc@3.5.21" - - ruff@0.12.11 + - ruff@0.13.0 - shellcheck@0.11.0 - shfmt@3.6.0 - taplo@0.10.0 - trivy@0.66.0 - - trufflehog@3.90.5 + - trufflehog@3.90.6 - yamllint@1.37.1 ignore: - linters: [ALL] diff --git a/backend/endpoints/responses/search.py b/backend/endpoints/responses/search.py index f0a6e3ed7..e13c720dd 100644 --- a/backend/endpoints/responses/search.py +++ b/backend/endpoints/responses/search.py @@ -10,6 +10,7 @@ class SearchRomSchema(BaseModel): ss_id: int | None = None sgdb_id: int | None = None flashpoint_id: str | None = None + launchbox_id: int | None = None hltb_id: int | None = None platform_id: int name: str @@ -20,6 +21,7 @@ class SearchRomSchema(BaseModel): ss_url_cover: str = "" sgdb_url_cover: str = "" flashpoint_url_cover: str = "" + launchbox_url_cover: str = "" hltb_url_cover: str = "" is_unidentified: bool is_identified: bool diff --git a/backend/endpoints/search.py b/backend/endpoints/search.py index f8cf5108b..7502be22d 100644 --- a/backend/endpoints/search.py +++ b/backend/endpoints/search.py @@ -10,12 +10,14 @@ from handler.database import db_rom_handler from handler.metadata import ( meta_flashpoint_handler, meta_igdb_handler, + meta_launchbox_handler, meta_moby_handler, meta_sgdb_handler, meta_ss_handler, ) from handler.metadata.flashpoint_handler import FlashpointRom from handler.metadata.igdb_handler import IGDBRom +from handler.metadata.launchbox_handler import LaunchboxRom from handler.metadata.moby_handler import MobyGamesRom from handler.metadata.sgdb_handler import SGDBRom from handler.metadata.ss_handler import SSRom @@ -87,6 +89,7 @@ async def search_rom( moby_matched_roms: list[MobyGamesRom] = [] ss_matched_roms: list[SSRom] = [] flashpoint_matched_roms: list[FlashpointRom] = [] + launchbox_matched_roms: list[LaunchboxRom] = [] if search_by.lower() == "id": try: @@ -111,6 +114,7 @@ async def search_rom( moby_matched_roms, ss_matched_roms, flashpoint_matched_roms, + launchbox_matched_roms, ) = await asyncio.gather( meta_igdb_handler.get_matched_roms_by_name( search_term, get_main_platform_igdb_id(rom.platform) @@ -119,7 +123,12 @@ async def search_rom( search_term, rom.platform.moby_id ), meta_ss_handler.get_matched_roms_by_name(search_term, rom.platform.ss_id), - meta_flashpoint_handler.get_matched_roms_by_name(rom.fs_name), + meta_flashpoint_handler.get_matched_roms_by_name( + search_term, rom.platform.slug + ), + meta_launchbox_handler.get_matched_roms_by_name( + search_term, rom.platform.slug + ), ) merged_dict: dict[str, dict] = {} @@ -184,6 +193,21 @@ async def search_rom( **merged_dict.get(flashpoint_name, {}), } + for launchbox_rom in launchbox_matched_roms: + if launchbox_rom["launchbox_id"]: + launchbox_name = meta_launchbox_handler.normalize_search_term( + launchbox_rom.get("name", ""), + remove_articles=False, + ) + merged_dict[launchbox_name] = { + **launchbox_rom, + "is_identified": True, + "is_unidentified": False, + "platform_id": rom.platform_id, + "launchbox_url_cover": launchbox_rom.pop("url_cover", ""), + **merged_dict.get(launchbox_name, {}), + } + async def get_sgdb_rom(name: str) -> tuple[str, SGDBRom]: return name, await meta_sgdb_handler.get_details_by_names([name]) diff --git a/backend/handler/metadata/flashpoint_handler.py b/backend/handler/metadata/flashpoint_handler.py index a7806619f..4fa4e1650 100644 --- a/backend/handler/metadata/flashpoint_handler.py +++ b/backend/handler/metadata/flashpoint_handler.py @@ -226,7 +226,7 @@ class FlashpointHandler(MetadataHandler): """ from handler.filesystem import fs_rom_handler - if not FLASHPOINT_API_ENABLED: + if not self.is_enabled(): return FlashpointRom(flashpoint_id=None) if platform_slug not in FLASHPOINT_PLATFORM_LIST: @@ -276,13 +276,22 @@ class FlashpointHandler(MetadataHandler): log.debug(f"No good match found for '{search_term}' on Flashpoint") return FlashpointRom(flashpoint_id=None) - async def get_matched_roms_by_name(self, fs_name: str) -> list[FlashpointRom]: + async def get_matched_roms_by_name( + self, fs_name: str, platform_slug: str + ) -> list[FlashpointRom]: """ Get ROM information by name from Flashpoint. + + Args: + fs_name (str): The filesystem name of the ROM. + platform_slug (str): The platform slug. """ from handler.filesystem import fs_rom_handler - if not FLASHPOINT_API_ENABLED: + if not self.is_enabled(): + return [] + + if platform_slug not in FLASHPOINT_PLATFORM_LIST: return [] search_term = fs_rom_handler.get_file_name_with_no_tags(fs_name) diff --git a/backend/handler/metadata/launchbox_handler.py b/backend/handler/metadata/launchbox_handler.py index 3f1774ba5..af1eeb1d0 100644 --- a/backend/handler/metadata/launchbox_handler.py +++ b/backend/handler/metadata/launchbox_handler.py @@ -328,6 +328,15 @@ class LaunchboxHandler(MetadataHandler): return await self.get_rom_by_id(database_id) + async def get_matched_roms_by_name( + self, search_term: str, platform_slug: str + ) -> list[LaunchboxRom]: + if not self.is_enabled(): + return [] + + rom = await self.get_rom(search_term, platform_slug) + return [rom] if rom else [] + class SlugToLaunchboxId(TypedDict): id: int diff --git a/frontend/src/__generated__/models/SearchRomSchema.ts b/frontend/src/__generated__/models/SearchRomSchema.ts index c0da236e7..7849d6ef3 100644 --- a/frontend/src/__generated__/models/SearchRomSchema.ts +++ b/frontend/src/__generated__/models/SearchRomSchema.ts @@ -9,6 +9,7 @@ export type SearchRomSchema = { ss_id?: (number | null); sgdb_id?: (number | null); flashpoint_id?: (string | null); + launchbox_id?: (number | null); hltb_id?: (number | null); platform_id: number; name: string; @@ -19,6 +20,7 @@ export type SearchRomSchema = { ss_url_cover?: string; sgdb_url_cover?: string; flashpoint_url_cover?: string; + launchbox_url_cover?: string; hltb_url_cover?: string; is_unidentified: boolean; is_identified: boolean; diff --git a/frontend/src/components/common/Game/Card/Base.vue b/frontend/src/components/common/Game/Card/Base.vue index 30190bfec..0926884a5 100644 --- a/frontend/src/components/common/Game/Card/Base.vue +++ b/frontend/src/components/common/Game/Card/Base.vue @@ -152,7 +152,10 @@ const largeCover = computed(() => { return ( props.rom.igdb_url_cover || props.rom.moby_url_cover || - props.rom.ss_url_cover + props.rom.ss_url_cover || + props.rom.launchbox_url_cover || + props.rom.flashpoint_url_cover || + props.rom.hltb_url_cover ); const pathCoverLarge = isWebpEnabled.value ? props.rom.path_cover_large?.replace(EXTENSION_REGEX, ".webp") @@ -260,7 +263,10 @@ onBeforeUnmount(() => { !rom.igdb_url_cover && !rom.moby_url_cover && !rom.ss_url_cover && - !rom.sgdb_url_cover) + !rom.sgdb_url_cover && + !rom.launchbox_url_cover && + !rom.flashpoint_url_cover && + !rom.hltb_url_cover) " class="translucent text-white" :class=" diff --git a/frontend/src/components/common/Game/Card/Sources.vue b/frontend/src/components/common/Game/Card/Sources.vue index 91ac5be6b..36123caff 100644 --- a/frontend/src/components/common/Game/Card/Sources.vue +++ b/frontend/src/components/common/Game/Card/Sources.vue @@ -14,7 +14,13 @@ defineProps<{ rom: SearchRomSchema }>(); open-delay="500" > @@ -30,8 +36,8 @@ defineProps<{ rom: SearchRomSchema }>(); @@ -49,14 +55,33 @@ defineProps<{ rom: SearchRomSchema }>(); + + + (); open-delay="500" > @@ -78,7 +109,13 @@ defineProps<{ rom: SearchRomSchema }>(); open-delay="500" > diff --git a/frontend/src/components/common/Game/Dialog/MatchRom.vue b/frontend/src/components/common/Game/Dialog/MatchRom.vue index da3101053..820752007 100644 --- a/frontend/src/components/common/Game/Dialog/MatchRom.vue +++ b/frontend/src/components/common/Game/Dialog/MatchRom.vue @@ -24,6 +24,7 @@ type MatchedSource = { | "Mobygames" | "Screenscraper" | "Flashpoint" + | "Launchbox" | "HowLongToBeat" | "SteamGridDB"; logo_path: string; @@ -54,6 +55,7 @@ const isIGDBFiltered = ref(true); const isMobyFiltered = ref(true); const isSSFiltered = ref(true); const isFlashpointFiltered = ref(true); +const isLaunchboxFiltered = ref(true); const isHLTBFiltered = ref(true); const computedAspectRatio = computed(() => { const ratio = @@ -94,6 +96,11 @@ function toggleSourceFilter(source: MatchedSource["name"]) { heartbeat.value.METADATA_SOURCES.FLASHPOINT_API_ENABLED ) { isFlashpointFiltered.value = !isFlashpointFiltered.value; + } else if ( + source == "Launchbox" && + heartbeat.value.METADATA_SOURCES.LAUNCHBOX_API_ENABLED + ) { + isLaunchboxFiltered.value = !isLaunchboxFiltered.value; } else if ( source == "HowLongToBeat" && heartbeat.value.METADATA_SOURCES.HLTB_API_ENABLED @@ -106,6 +113,7 @@ function toggleSourceFilter(source: MatchedSource["name"]) { (rom.moby_id && isMobyFiltered.value) || (rom.ss_id && isSSFiltered.value) || (rom.flashpoint_id && isFlashpointFiltered.value) || + (rom.launchbox_id && isLaunchboxFiltered.value) || (rom.hltb_id && isHLTBFiltered.value) ) { return true; @@ -138,6 +146,7 @@ async function searchRom() { (rom.moby_id && isMobyFiltered.value) || (rom.ss_id && isSSFiltered.value) || (rom.flashpoint_id && isFlashpointFiltered.value) || + (rom.launchbox_id && isLaunchboxFiltered.value) || (rom.hltb_id && isHLTBFiltered.value) ) { return true; @@ -203,6 +212,13 @@ function showSources(matchedRom: SearchRomSchema) { logo_path: "/assets/scrappers/flashpoint.png", }); } + if (matchedRom.launchbox_url_cover) { + sources.value.push({ + url_cover: matchedRom.launchbox_url_cover, + name: "Launchbox", + logo_path: "/assets/scrappers/launchbox.png", + }); + } if (matchedRom.hltb_url_cover) { sources.value.push({ url_cover: matchedRom.hltb_url_cover, @@ -260,6 +276,7 @@ async function updateRom( ss_id: selectedRom.ss_id || null, moby_id: selectedRom.moby_id || null, flashpoint_id: selectedRom.flashpoint_id || null, + launchbox_id: selectedRom.launchbox_id || null, hltb_id: selectedRom.hltb_id || null, name: selectedRom.name || null, slug: selectedRom.slug || null, @@ -270,6 +287,7 @@ async function updateRom( selectedRom.ss_url_cover || selectedRom.moby_url_cover || selectedRom.flashpoint_url_cover || + selectedRom.launchbox_url_cover || selectedRom.hltb_url_cover || null, }; @@ -423,6 +441,36 @@ onBeforeUnmount(() => { + + +