mirror of
https://github.com/rommapp/romm.git
synced 2026-04-18 12:09:38 +00:00
add support for importing metadata from a local launchbox installation
This commit is contained in:
50
.dockerignore
Normal file
50
.dockerignore
Normal file
@@ -0,0 +1,50 @@
|
||||
# Local secrets / env
|
||||
.env
|
||||
**/.env
|
||||
|
||||
# Git / editor / OS
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
**/.DS_Store
|
||||
|
||||
# IDE / dev containers
|
||||
.vscode/
|
||||
.devcontainer/
|
||||
|
||||
# Python virtualenvs & caches
|
||||
.venv/
|
||||
**/.venv/
|
||||
**/venv/
|
||||
**/__pycache__/
|
||||
**/.mypy_cache/
|
||||
**/.pytest_cache/
|
||||
**/.ruff_cache/
|
||||
|
||||
# Node caches
|
||||
**/node_modules/
|
||||
**/.npm/
|
||||
**/.vite/
|
||||
|
||||
# CI / metadata not needed in image
|
||||
.github/
|
||||
|
||||
# Mock & test data (requested)
|
||||
romm_mock/
|
||||
**/romm_mock/
|
||||
backend/tests/
|
||||
**/romm_test/
|
||||
|
||||
# Local-only docker compose files/examples (not needed in image)
|
||||
docker-compose.yml
|
||||
examples/
|
||||
|
||||
# Local tools / docs not required for runtime
|
||||
**/*.md
|
||||
CODE_OF_CONDUCT.md
|
||||
CONTRIBUTING.md
|
||||
DEVELOPER_SETUP.md
|
||||
SECURITY.md
|
||||
|
||||
# Note: we intentionally do NOT ignore `docker/` because `docker/Dockerfile`
|
||||
# copies init scripts and nginx/gunicorn configs from that folder.
|
||||
@@ -230,6 +230,7 @@ async def _identify_rom(
|
||||
scan_type: ScanType,
|
||||
roms_ids: list[int],
|
||||
metadata_sources: list[str],
|
||||
launchbox_remote_enabled: bool,
|
||||
socket_manager: socketio.AsyncRedisManager,
|
||||
scan_stats: ScanStats,
|
||||
calculate_hashes: bool = True,
|
||||
@@ -321,6 +322,7 @@ async def _identify_rom(
|
||||
fs_rom=fs_rom,
|
||||
metadata_sources=metadata_sources,
|
||||
newly_added=newly_added,
|
||||
launchbox_remote_enabled=launchbox_remote_enabled,
|
||||
socket_manager=socket_manager,
|
||||
)
|
||||
|
||||
@@ -450,6 +452,7 @@ async def _identify_platform(
|
||||
fs_platforms: list[str],
|
||||
roms_ids: list[int],
|
||||
metadata_sources: list[str],
|
||||
launchbox_remote_enabled: bool,
|
||||
socket_manager: socketio.AsyncRedisManager,
|
||||
scan_stats: ScanStats,
|
||||
calculate_hashes: bool = True,
|
||||
@@ -539,6 +542,7 @@ async def _identify_platform(
|
||||
scan_type=scan_type,
|
||||
roms_ids=roms_ids,
|
||||
metadata_sources=metadata_sources,
|
||||
launchbox_remote_enabled=launchbox_remote_enabled,
|
||||
socket_manager=socket_manager,
|
||||
scan_stats=scan_stats,
|
||||
calculate_hashes=calculate_hashes,
|
||||
@@ -589,6 +593,7 @@ async def scan_platforms(
|
||||
metadata_sources: list[str],
|
||||
scan_type: ScanType = ScanType.QUICK,
|
||||
roms_ids: list[int] | None = None,
|
||||
launchbox_remote_enabled: bool = True,
|
||||
) -> ScanStats:
|
||||
"""Scan all the listed platforms and fetch metadata from different sources
|
||||
|
||||
@@ -663,6 +668,7 @@ async def scan_platforms(
|
||||
fs_platforms=fs_platforms,
|
||||
roms_ids=roms_ids,
|
||||
metadata_sources=metadata_sources,
|
||||
launchbox_remote_enabled=launchbox_remote_enabled,
|
||||
socket_manager=socket_manager,
|
||||
scan_stats=scan_stats,
|
||||
calculate_hashes=calculate_hashes,
|
||||
@@ -702,6 +708,7 @@ async def scan_handler(_sid: str, options: dict[str, Any]):
|
||||
scan_type = ScanType[options.get("type", "quick").upper()]
|
||||
roms_ids = options.get("roms_ids", [])
|
||||
metadata_sources = options.get("apis", [])
|
||||
launchbox_remote_enabled = bool(options.get("launchbox_remote_enabled", True))
|
||||
|
||||
if DEV_MODE:
|
||||
return await scan_platforms(
|
||||
@@ -709,6 +716,7 @@ async def scan_handler(_sid: str, options: dict[str, Any]):
|
||||
metadata_sources=metadata_sources,
|
||||
scan_type=scan_type,
|
||||
roms_ids=roms_ids,
|
||||
launchbox_remote_enabled=launchbox_remote_enabled,
|
||||
)
|
||||
|
||||
return high_prio_queue.enqueue(
|
||||
@@ -717,6 +725,7 @@ async def scan_handler(_sid: str, options: dict[str, Any]):
|
||||
metadata_sources=metadata_sources,
|
||||
scan_type=scan_type,
|
||||
roms_ids=roms_ids,
|
||||
launchbox_remote_enabled=launchbox_remote_enabled,
|
||||
job_timeout=SCAN_TIMEOUT, # Timeout (default of 4 hours)
|
||||
result_ttl=TASK_RESULT_TTL,
|
||||
meta={
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -287,6 +287,7 @@ async def scan_rom(
|
||||
fs_rom: FSRom,
|
||||
metadata_sources: list[str],
|
||||
newly_added: bool,
|
||||
launchbox_remote_enabled: bool = True,
|
||||
socket_manager: socketio.AsyncRedisManager | None = None,
|
||||
) -> Rom:
|
||||
rom_attrs = {
|
||||
@@ -585,13 +586,17 @@ async def scan_rom(
|
||||
and rom.platform_slug in LAUNCHBOX_PLATFORM_LIST
|
||||
)
|
||||
):
|
||||
if scan_type == ScanType.UPDATE and rom.launchbox_id:
|
||||
return await meta_launchbox_handler.get_rom_by_id(rom.launchbox_id)
|
||||
else:
|
||||
return await meta_launchbox_handler.get_rom(
|
||||
rom_attrs["fs_name"], platform_slug
|
||||
if scan_type == ScanType.UPDATE and rom.launchbox_id and launchbox_remote_enabled:
|
||||
return await meta_launchbox_handler.get_rom_by_id(
|
||||
rom.launchbox_id, remote_enabled=True
|
||||
)
|
||||
|
||||
return await meta_launchbox_handler.get_rom(
|
||||
rom_attrs["fs_name"],
|
||||
platform_slug,
|
||||
remote_enabled=launchbox_remote_enabled,
|
||||
)
|
||||
|
||||
return LaunchboxRom(launchbox_id=None)
|
||||
|
||||
async def fetch_ra_rom(hasheous_rom: HasheousRom) -> RAGameRom:
|
||||
|
||||
@@ -7,6 +7,7 @@ from defusedxml import ElementTree as ET
|
||||
|
||||
from config import (
|
||||
ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA,
|
||||
LAUNCHBOX_API_ENABLED,
|
||||
SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON,
|
||||
)
|
||||
from handler.metadata import meta_launchbox_handler
|
||||
@@ -44,7 +45,10 @@ class UpdateLaunchboxMetadataTask(RemoteFilePullTask):
|
||||
async def run(self, force: bool = False) -> dict[str, Any]:
|
||||
update_stats = UpdateStats()
|
||||
|
||||
if not meta_launchbox_handler.is_enabled():
|
||||
# This task pulls remote metadata from LaunchBox (Metadata.zip) and should
|
||||
# only run when the LaunchBox API integration is enabled.
|
||||
# `meta_launchbox_handler.is_enabled()` may also be true for local-only mode.
|
||||
if not LAUNCHBOX_API_ENABLED:
|
||||
log.warning("Launchbox API is not enabled, skipping metadata update")
|
||||
return update_stats.to_dict()
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"hasheous-requires-hashes": "Hasheous requires hash calculation to be enabled",
|
||||
"retroachievements-requires-hashes": "RetroAchievements requires hash calculation to be enabled",
|
||||
"manage-library": "Manage library",
|
||||
"launchbox-remote": "LaunchBox remote (enrich local with remote)",
|
||||
"metadata-sources": "Metadata sources",
|
||||
"new-platforms": "New platforms",
|
||||
"new-platforms-desc": "Scan new platforms only (fastest)",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"hasheous-requires-hashes": "Hasheous nécessite que le calcul de hachage soit activé",
|
||||
"retroachievements-requires-hashes": "RetroAchievements nécessite que le calcul de hachage soit activé",
|
||||
"manage-library": "Gérer la bibliothèque",
|
||||
"launchbox-remote": "LaunchBox remote (enrichir le local avec le remote)",
|
||||
"metadata-sources": "Sources de métadonnées",
|
||||
"new-platforms": "Nouvelles plateformes",
|
||||
"new-platforms-desc": "Scanner uniquement les plateformes récemment ajoutées (plus rapide)",
|
||||
|
||||
@@ -16,6 +16,7 @@ import storePlatforms from "@/stores/platforms";
|
||||
import storeScanning from "@/stores/scanning";
|
||||
|
||||
const LOCAL_STORAGE_METADATA_SOURCES_KEY = "scan.metadataSources";
|
||||
const LOCAL_STORAGE_LAUNCHBOX_REMOTE_ENABLED_KEY = "scan.launchboxRemoteEnabled";
|
||||
const { t } = useI18n();
|
||||
const { xs, smAndDown } = useDisplay();
|
||||
const scanningStore = storeScanning();
|
||||
@@ -66,12 +67,20 @@ const storedMetadataSources = useLocalStorage(
|
||||
LOCAL_STORAGE_METADATA_SOURCES_KEY,
|
||||
[] as string[],
|
||||
);
|
||||
const launchboxRemoteEnabled = useLocalStorage(
|
||||
LOCAL_STORAGE_LAUNCHBOX_REMOTE_ENABLED_KEY,
|
||||
true,
|
||||
);
|
||||
const metadataSources = ref<MetadataOption[]>(
|
||||
metadataOptions.value.filter(
|
||||
(m) => storedMetadataSources.value.includes(m.value) && !m.disabled,
|
||||
) || heartbeat.getEnabledMetadataOptions(),
|
||||
);
|
||||
|
||||
const isLaunchboxSelected = computed(() =>
|
||||
metadataSources.value.some((s) => s.value === "launchbox"),
|
||||
);
|
||||
|
||||
watch(metadataOptions, (newOptions) => {
|
||||
// Remove any sources that are now disabled
|
||||
metadataSources.value = metadataSources.value.filter((s) =>
|
||||
@@ -137,6 +146,7 @@ async function scan() {
|
||||
platforms: platformsToScan.value,
|
||||
type: scanType.value,
|
||||
apis: metadataSources.value.map((s) => s.value),
|
||||
launchbox_remote_enabled: launchboxRemoteEnabled.value,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -350,6 +360,24 @@ async function stopScan() {
|
||||
<v-img :src="item.raw.logo_path" />
|
||||
</v-avatar>
|
||||
</template>
|
||||
|
||||
<template #append v-if="item.raw.value === 'launchbox'">
|
||||
<div class="d-flex align-center">
|
||||
<span class="text-caption text-medium-emphasis mr-4">
|
||||
Remote
|
||||
</span>
|
||||
<v-switch
|
||||
v-model="launchboxRemoteEnabled"
|
||||
color="primary"
|
||||
density="compact"
|
||||
hide-details
|
||||
:disabled="!isLaunchboxSelected"
|
||||
aria-label="Remote"
|
||||
@click.stop
|
||||
@mousedown.stop
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<template #chip="{ item }">
|
||||
|
||||
Reference in New Issue
Block a user