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(() => {
+
+
+
+
+
+
+