From ce4809ea9c9fd59ac6687da8bdfe8a3dbe3eac90 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sun, 21 Sep 2025 09:38:00 -0400 Subject: [PATCH] add region and language priority --- backend/config/config_manager.py | 26 ++++++++++++ backend/endpoints/configs.py | 2 + backend/endpoints/responses/config.py | 2 + backend/handler/metadata/ss_handler.py | 42 ++++++++++++++++--- .../__generated__/models/ConfigResponse.ts | 2 + frontend/src/stores/config.ts | 2 + 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/backend/config/config_manager.py b/backend/config/config_manager.py index f3ffab1ce..371f1a7fa 100644 --- a/backend/config/config_manager.py +++ b/backend/config/config_manager.py @@ -63,6 +63,8 @@ class Config: EJS_CONTROLS: dict[str, EjsControls] # core_name -> EjsControls SCAN_METADATA_PRIORITY: list[str] SCAN_ARTWORK_PRIORITY: list[str] + SCAN_REGION_PRIORITY: list[str] + SCAN_LANGUAGE_PRIORITY: list[str] def __init__(self, **entries): self.__dict__.update(entries) @@ -223,6 +225,16 @@ class ConfigManager: "hltb", ], ), + SCAN_REGION_PRIORITY=pydash.get( + self._raw_config, + "scan.region.priority", + ["us", "wor", "ss", "eu", "jp"], + ), + SCAN_LANGUAGE_PRIORITY=pydash.get( + self._raw_config, + "scan.language.priority", + ["en", "fr"], + ), ) def _get_ejs_controls(self) -> dict[str, EjsControls]: @@ -393,6 +405,14 @@ class ConfigManager: log.critical("Invalid config.yml: scan.artwork.priority must be a list") sys.exit(3) + if not isinstance(self.config.SCAN_REGION_PRIORITY, list): + log.critical("Invalid config.yml: scan.region.priority must be a list") + sys.exit(3) + + if not isinstance(self.config.SCAN_LANGUAGE_PRIORITY, list): + log.critical("Invalid config.yml: scan.language.priority must be a list") + sys.exit(3) + def get_config(self) -> Config: try: with open(self.config_file, "r+") as config_file: @@ -449,6 +469,12 @@ class ConfigManager: "artwork": { "priority": self.config.SCAN_ARTWORK_PRIORITY, }, + "region": { + "priority": self.config.SCAN_REGION_PRIORITY, + }, + "language": { + "priority": self.config.SCAN_LANGUAGE_PRIORITY, + }, }, } diff --git a/backend/endpoints/configs.py b/backend/endpoints/configs.py index 98c2303be..bec1350d2 100644 --- a/backend/endpoints/configs.py +++ b/backend/endpoints/configs.py @@ -39,6 +39,8 @@ def get_config() -> ConfigResponse: EJS_SETTINGS=cfg.EJS_SETTINGS, SCAN_METADATA_PRIORITY=cfg.SCAN_METADATA_PRIORITY, SCAN_ARTWORK_PRIORITY=cfg.SCAN_ARTWORK_PRIORITY, + SCAN_REGION_PRIORITY=cfg.SCAN_REGION_PRIORITY, + SCAN_LANGUAGE_PRIORITY=cfg.SCAN_LANGUAGE_PRIORITY, ) diff --git a/backend/endpoints/responses/config.py b/backend/endpoints/responses/config.py index 0bd60389c..487b98b62 100644 --- a/backend/endpoints/responses/config.py +++ b/backend/endpoints/responses/config.py @@ -19,3 +19,5 @@ class ConfigResponse(TypedDict): EJS_CONTROLS: dict[str, EjsControls] SCAN_METADATA_PRIORITY: list[str] SCAN_ARTWORK_PRIORITY: list[str] + SCAN_REGION_PRIORITY: list[str] + SCAN_LANGUAGE_PRIORITY: list[str] diff --git a/backend/handler/metadata/ss_handler.py b/backend/handler/metadata/ss_handler.py index 265778b6b..6ebf9db8a 100644 --- a/backend/handler/metadata/ss_handler.py +++ b/backend/handler/metadata/ss_handler.py @@ -10,6 +10,7 @@ from unidecode import unidecode as uc from adapters.services.screenscraper import ScreenScraperService from adapters.services.screenscraper_types import SSGame, SSGameDate from config import SCREENSCRAPER_PASSWORD, SCREENSCRAPER_USER +from config.config_manager import config_manager as cm from logger.logger import log from .base_handler import ( @@ -25,7 +26,36 @@ from .base_handler import UniversalPlatformSlug as UPS SS_DEV_ID: Final = base64.b64decode("enVyZGkxNQ==").decode() SS_DEV_PASSWORD: Final = base64.b64decode("eFRKd29PRmpPUUc=").decode() -PREFERRED_REGIONS: Final = ["us", "wor", "ss", "eu", "jp"] + +def get_preferred_regions() -> list[str]: + """Get preferred regions from config, merged with defaults""" + config = cm.get_config() + default_regions = ["us", "wor", "ss", "eu", "jp"] + ordered_regions = [ + region for region in config.SCAN_REGION_PRIORITY if region in default_regions + ] + remaining_regions = [ + region + for region in default_regions + if region not in config.SCAN_REGION_PRIORITY + ] + + return ordered_regions + remaining_regions + + +def get_preferred_languages() -> list[str]: + """Get preferred languages from config, merged with defaults""" + config = cm.get_config() + default_languages = ["en", "fr"] + ordered_languages = [ + lang for lang in config.SCAN_LANGUAGE_PRIORITY if lang in default_languages + ] + remaining_languages = [ + lang for lang in default_languages if lang not in config.SCAN_LANGUAGE_PRIORITY + ] + + return ordered_languages + remaining_languages + PS1_SS_ID: Final = 57 PS2_SS_ID: Final = 58 @@ -135,7 +165,7 @@ class SSRom(BaseRom): def build_ss_rom(game: SSGame) -> SSRom: res_name = "" - for region in PREFERRED_REGIONS: + for region in get_preferred_regions(): res_name = next( ( name["text"] @@ -157,7 +187,7 @@ def build_ss_rom(game: SSGame) -> SSRom: ) url_cover = "" - for region in PREFERRED_REGIONS: + for region in get_preferred_regions(): url_cover = next( ( media["url"] @@ -172,7 +202,7 @@ def build_ss_rom(game: SSGame) -> SSRom: break url_manual: str = "" - for region in PREFERRED_REGIONS: + for region in get_preferred_regions(): url_manual = next( ( media["url"] @@ -231,7 +261,7 @@ def extract_metadata_from_ss_rom(rom: SSGame) -> SSMetadata: ] def _get_franchises(rom: SSGame) -> list[str]: - preferred_languages = ["en", "fr"] + preferred_languages = get_preferred_languages() for lang in preferred_languages: franchises = [ franchise_name["text"] @@ -244,7 +274,7 @@ def extract_metadata_from_ss_rom(rom: SSGame) -> SSMetadata: return [] def _get_game_modes(rom: SSGame) -> list[str]: - preferred_languages = ["en", "fr"] + preferred_languages = get_preferred_languages() for lang in preferred_languages: modes = [ mode_name["text"] diff --git a/frontend/src/__generated__/models/ConfigResponse.ts b/frontend/src/__generated__/models/ConfigResponse.ts index f028a22d6..bdcb25a10 100644 --- a/frontend/src/__generated__/models/ConfigResponse.ts +++ b/frontend/src/__generated__/models/ConfigResponse.ts @@ -19,5 +19,7 @@ export type ConfigResponse = { EJS_CONTROLS: Record; SCAN_METADATA_PRIORITY: Array; SCAN_ARTWORK_PRIORITY: Array; + SCAN_REGION_PRIORITY: Array; + SCAN_LANGUAGE_PRIORITY: Array; }; diff --git a/frontend/src/stores/config.ts b/frontend/src/stores/config.ts index abb66b53e..bc8ee7826 100644 --- a/frontend/src/stores/config.ts +++ b/frontend/src/stores/config.ts @@ -27,6 +27,8 @@ const defaultConfig = { EJS_CONTROLS: {}, SCAN_METADATA_PRIORITY: [], SCAN_ARTWORK_PRIORITY: [], + SCAN_REGION_PRIORITY: [], + SCAN_LANGUAGE_PRIORITY: [], } as ConfigResponse; export default defineStore("config", {