Added Automatic Gamelist export support

This commit is contained in:
Cobaltboy
2026-02-03 19:42:45 +05:30
parent db3e3e4cf6
commit 90694133c6
3 changed files with 43 additions and 3 deletions

View File

@@ -76,6 +76,7 @@ class Config:
EXCLUDED_MULTI_FILES: list[str]
EXCLUDED_MULTI_PARTS_EXT: list[str]
EXCLUDED_MULTI_PARTS_FILES: list[str]
GAMELIST_AUTO_EXPORT_ON_SCAN: bool
PLATFORMS_BINDING: dict[str, str]
PLATFORMS_VERSIONS: dict[str, str]
ROMS_FOLDER_NAME: str
@@ -222,6 +223,9 @@ class ConfigManager:
),
FIRMWARE_FOLDER_NAME=pydash.get(
self._raw_config, "filesystem.firmware_folder", "bios"
),
GAMELIST_AUTO_EXPORT_ON_SCAN=pydash.get(
self._raw_config, "gamelist.auto_export_on_scan", False
),
SKIP_HASH_CALCULATION=pydash.get(
self._raw_config, "filesystem.skip_hash_calculation", False
@@ -364,6 +368,12 @@ class ConfigManager:
"Invalid config.yml: exclude.roms.multi_file.parts.names must be a list"
)
sys.exit(3)
if not isinstance(self.config.GAMELIST_AUTO_EXPORT_ON_SCAN, bool):
log.critical(
"Invalid config.yml: gamelist.auto_export_on_scan must be a boolean"
)
sys.exit(3)
if not isinstance(self.config.PLATFORMS_BINDING, dict):
log.critical("Invalid config.yml: system.platforms must be a dictionary")
@@ -571,6 +581,9 @@ class ConfigManager:
},
"media": self.config.SCAN_MEDIA,
},
"gamelist": {
"auto_export_on_scan": self.config.GAMELIST_AUTO_EXPORT_ON_SCAN,
},
}
try:

View File

@@ -22,6 +22,7 @@ from exceptions.fs_exceptions import (
RomsNotFoundException,
)
from exceptions.socket_exceptions import ScanStoppedException
from utils.gamelist_exporter import GamelistExporter
from handler.database import db_firmware_handler, db_platform_handler, db_rom_handler
from handler.filesystem import (
fs_firmware_handler,
@@ -683,6 +684,28 @@ async def scan_platforms(
log.warning(f" - {p.slug} ({p.fs_slug})")
log.info(f"{emoji.EMOJI_CHECK_MARK} Scan completed")
# Export gamelist.xml if enabled in config
if cm.get_config().GAMELIST_AUTO_EXPORT_ON_SCAN:
log.info("Auto-exporting gamelist.xml for all platforms...")
gamelist_exporter = GamelistExporter(local_export=True)
for platform_slug in platform_list:
platform = db_platform_handler.get_platform_by_fs_slug(platform_slug)
if platform:
try:
await gamelist_exporter.export_platform_to_file(
platform.id,
request=None,
)
log.info(
f"Auto-exported gamelist.xml for platform {platform.name} after scan"
)
except Exception as e:
log.error(
f"Failed to auto-export gamelist.xml for platform {platform.name}: {e}"
)
log.info("Gamelist.xml auto-export completed.")
await socket_manager.emit("scan:done", scan_stats.to_dict())
except ScanStoppedException:
await stop_scan()

View File

@@ -25,7 +25,7 @@ class GamelistExporter:
"""Format release date to YYYYMMDDTHHMMSS format"""
return datetime.fromtimestamp(timestamp / 1000).strftime("%Y%m%dT%H%M%S")
def _create_game_element(self, rom: Rom, request: Request) -> Element:
def _create_game_element(self, rom: Rom, request: Request | None) -> Element:
"""Create a <game> element for a ROM"""
game = Element("game")
@@ -33,6 +33,10 @@ class GamelistExporter:
if self.local_export:
SubElement(game, "path").text = f"./{rom.fs_name}"
else:
if request is None:
raise ValueError(
"Request object must be provided for non-local exports"
)
SubElement(game, "path").text = str(
request.url_for(
"get_rom_content",
@@ -155,7 +159,7 @@ class GamelistExporter:
return game
def export_platform_to_xml(self, platform_id: int, request: Request) -> str:
def export_platform_to_xml(self, platform_id: int, request: Request | None) -> str:
"""Export a platform's ROMs to gamelist.xml format
Args:
@@ -188,7 +192,7 @@ class GamelistExporter:
async def export_platform_to_file(
self,
platform_id: int,
request: Request,
request: Request | None,
) -> bool:
"""Export platform ROMs to gamelist.xml file in the platform's directory