From 450d2593c689d6cdbce0e4a154451e0c8a6ecfbc Mon Sep 17 00:00:00 2001 From: Zurdi Date: Mon, 19 Feb 2024 00:13:18 +0100 Subject: [PATCH] fix read config when updated from UI --- backend/config/config_manager.py | 131 ++++++++++-------- backend/endpoints/config.py | 12 +- .../fs_handler/fs_platforms_handler.py | 6 +- backend/handler/fs_handler/fs_roms_handler.py | 12 +- backend/handler/fs_handler/tests/test_fs.py | 10 +- backend/handler/scan_handler.py | 10 +- backend/watcher.py | 4 +- 7 files changed, 103 insertions(+), 82 deletions(-) diff --git a/backend/config/config_manager.py b/backend/config/config_manager.py index f096cbce5..ab4b5939b 100644 --- a/backend/config/config_manager.py +++ b/backend/config/config_manager.py @@ -3,7 +3,6 @@ import sys from pathlib import Path from typing import Final from urllib.parse import quote_plus - import pydash import yaml from config import ( @@ -69,7 +68,7 @@ class ConfigManager: with open(config_file, "w") as file: file.write("") try: - self.read_config() + self.get_config() except ConfigNotReadableException as e: log.critical(e.message) sys.exit(5) @@ -96,9 +95,7 @@ class ConfigManager: # DEPRECATED if ROMM_DB_DRIVER == "sqlite": - log.critical( - "Sqlite is not supported anymore, migrate to mariaDB" - ) + log.critical("Sqlite is not supported anymore, migrate to mariaDB") sys.exit(6) # DEPRECATED @@ -200,7 +197,7 @@ class ConfigManager: ) sys.exit(3) - def read_config(self) -> None: + def get_config(self) -> None: try: with open(self.config_file) as config_file: self._raw_config = yaml.load(config_file, Loader=SafeLoader) or {} @@ -209,10 +206,37 @@ class ConfigManager: except PermissionError: self._raw_config = {} raise ConfigNotReadableException + self._parse_config() self._validate_config() - def update_config(self) -> None: + return self.config + + def update_config_file(self) -> None: + self._raw_config = { + "exclude": { + "platforms": self.config.EXCLUDED_PLATFORMS, + "roms": { + "single_file": { + "extensions": self.config.EXCLUDED_SINGLE_EXT, + "names": self.config.EXCLUDED_SINGLE_FILES, + }, + "multi_file": { + "names": self.config.EXCLUDED_MULTI_FILES, + "parts": { + "extensions": self.config.EXCLUDED_MULTI_PARTS_EXT, + "names": self.config.EXCLUDED_MULTI_PARTS_FILES, + }, + }, + }, + }, + "filesystem": {"roms_folder": self.config.ROMS_FOLDER_NAME}, + "system": { + "platforms": self.config.PLATFORMS_BINDING, + "versions": self.config.PLATFORMS_VERSIONS, + }, + } + try: with open(self.config_file, "w") as config_file: yaml.dump(self._raw_config, config_file) @@ -221,66 +245,65 @@ class ConfigManager: except PermissionError: self._raw_config = {} raise ConfigNotWritableException - finally: - self._parse_config() - def add_binding(self, fs_slug: str, slug: str) -> None: - try: - _ = self._raw_config["system"] - except KeyError: - self._raw_config = {"system": {"platforms": {}}} - try: - _ = self._raw_config["system"]["platforms"] - except KeyError: - self._raw_config["system"]["platforms"] = {} - self._raw_config["system"]["platforms"][fs_slug] = slug - self.update_config() + def add_platform_binding(self, fs_slug: str, slug: str) -> None: + platform_bindings = self.config.PLATFORMS_BINDING + if fs_slug in platform_bindings: + log.warn(f"Binding for {fs_slug} already exists") + return + + platform_bindings[fs_slug] = slug + self.config.PLATFORMS_BINDING = platform_bindings + self.update_config_file() + + def remove_platform_binding(self, fs_slug: str) -> None: + platform_bindings = self.config.PLATFORMS_BINDING - def remove_binding(self, fs_slug: str) -> None: try: - del self._raw_config["system"]["platforms"][fs_slug] + del platform_bindings[fs_slug] except KeyError: pass - self.update_config() - def add_version(self, fs_slug: str, slug: str) -> None: - try: - _ = self._raw_config["system"] - except KeyError: - self._raw_config = {"system": {"versions": {}}} - try: - _ = self._raw_config["system"]["versions"] - except KeyError: - self._raw_config["system"]["versions"] = {} - self._raw_config["system"]["versions"][fs_slug] = slug - self.update_config() + self.config.PLATFORMS_BINDING = platform_bindings + self.update_config_file() + + def add_platform_version(self, fs_slug: str, slug: str) -> None: + platform_versions = self.config.PLATFORMS_VERSIONS + if fs_slug in platform_versions: + log.warn(f"Version for {fs_slug} already exists") + return + + platform_versions[fs_slug] = slug + self.config.PLATFORMS_VERSIONS = platform_versions + self.update_config_file() + + def remove_platform_version(self, fs_slug: str) -> None: + platform_versions = self.config.PLATFORMS_VERSIONS - def remove_version(self, fs_slug: str) -> None: try: - del self._raw_config["system"]["versions"][fs_slug] + del platform_versions[fs_slug] except KeyError: pass - self.update_config() - # def _get_exclude_path(self, exclude): - # exclude_base = self._raw_config["exclude"] - # exclusions = { - # "platforms": exclude_base["platforms"], - # "single_ext": exclude_base["roms"]["single_file"]["extensions"], - # "single_file": exclude_base["roms"]["single_file"]["names"], - # "multi_file": exclude_base["roms"]["multi_file"]["names"], - # "multi_part_ext": exclude_base["roms"]["multi_file"]["parts"]["extensions"], - # "multi_part_file": exclude_base["roms"]["multi_file"]["parts"]["names"], - # } - # return exclusions[exclude] + self.config.PLATFORMS_VERSIONS = platform_versions + self.update_config_file() - # def add_exclusion(self, exclude: str, exclusion: str): - # config = self._get_exclude_path(exclude) - # config.append(exclusion) + def add_exclusion(self, config_key: str, exclusion: str): + config_item = self.config.__getattribute__(config_key) + config_item.append(exclusion) + self.config.__setattr__(config_key, config_item) + self.update_config_file() - # def remove_exclusion(self, exclude: str, exclusion: str): - # config = self._get_exclude_path(exclude) - # config.remove(exclusion) + def remove_exclusion(self, config_key: str, exclusion: str): + config_item = self.config.__getattribute__(config_key) + + try: + config_item.remove(exclusion) + except ValueError: + pass + + self.config.__setattr__(config_key, config_item) + self.update_config_file() config_manager = ConfigManager() diff --git a/backend/endpoints/config.py b/backend/endpoints/config.py index e8c45ce3f..07c6eb488 100644 --- a/backend/endpoints/config.py +++ b/backend/endpoints/config.py @@ -21,15 +21,13 @@ def get_config() -> ConfigResponse: """ try: - cm.read_config() + return cm.get_config().__dict__ except ConfigNotReadableException as e: log.critical(e.message) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=e.message ) - return cm.config.__dict__ - @protected_route(router.post, "/config/system/platforms", ["platforms.write"]) async def add_platform_binding(request: Request) -> MessageResponse: @@ -40,7 +38,7 @@ async def add_platform_binding(request: Request) -> MessageResponse: slug = data["slug"] try: - cm.add_binding(fs_slug, slug) + cm.add_platform_binding(fs_slug, slug) except ConfigNotWritableException as e: log.critical(e.message) raise HTTPException( @@ -57,7 +55,7 @@ async def delete_platform_binding(request: Request, fs_slug: str) -> MessageResp """Delete platform binding from the configuration""" try: - cm.remove_binding(fs_slug) + cm.remove_platform_binding(fs_slug) except ConfigNotWritableException as e: log.critical(e.message) raise HTTPException( @@ -76,7 +74,7 @@ async def add_platform_version(request: Request) -> MessageResponse: slug = data["slug"] try: - cm.add_version(fs_slug, slug) + cm.add_platform_version(fs_slug, slug) except ConfigNotWritableException as e: log.critical(e.message) raise HTTPException( @@ -93,7 +91,7 @@ async def delete_platform_version(request: Request, fs_slug: str) -> MessageResp """Delete platform version from the configuration""" try: - cm.remove_version(fs_slug) + cm.remove_platform_version(fs_slug) except ConfigNotWritableException as e: log.critical(e.message) raise HTTPException( diff --git a/backend/handler/fs_handler/fs_platforms_handler.py b/backend/handler/fs_handler/fs_platforms_handler.py index 0c032eca0..ab2a17846 100644 --- a/backend/handler/fs_handler/fs_platforms_handler.py +++ b/backend/handler/fs_handler/fs_platforms_handler.py @@ -14,7 +14,7 @@ class FSPlatformsHandler(FSHandler): return [ platform for platform in platforms - if platform not in cm.config.EXCLUDED_PLATFORMS + if platform not in cm.get_config().EXCLUDED_PLATFORMS ] def get_platforms(self) -> list[str]: @@ -25,8 +25,8 @@ class FSPlatformsHandler(FSHandler): """ try: platforms: list[str] = ( - list(os.walk(cm.config.HIGH_PRIO_STRUCTURE_PATH))[0][1] - if os.path.exists(cm.config.HIGH_PRIO_STRUCTURE_PATH) + list(os.walk(cm.get_config().HIGH_PRIO_STRUCTURE_PATH))[0][1] + if os.path.exists(cm.get_config().HIGH_PRIO_STRUCTURE_PATH) else list(os.walk(LIBRARY_BASE_PATH))[0][1] ) return self._exclude_platforms(platforms) diff --git a/backend/handler/fs_handler/fs_roms_handler.py b/backend/handler/fs_handler/fs_roms_handler.py index acbfd6a1a..3ed407d42 100644 --- a/backend/handler/fs_handler/fs_roms_handler.py +++ b/backend/handler/fs_handler/fs_roms_handler.py @@ -24,9 +24,9 @@ class FSRomsHandler(FSHandler): def get_fs_structure(self, fs_slug: str): return ( - f"{cm.config.ROMS_FOLDER_NAME}/{fs_slug}" - if os.path.exists(cm.config.HIGH_PRIO_STRUCTURE_PATH) - else f"{fs_slug}/{cm.config.ROMS_FOLDER_NAME}" + f"{cm.get_config().ROMS_FOLDER_NAME}/{fs_slug}" + if os.path.exists(cm.get_config().HIGH_PRIO_STRUCTURE_PATH) + else f"{fs_slug}/{cm.get_config().ROMS_FOLDER_NAME}" ) def remove_file(self, file_name: str, file_path: str): @@ -81,8 +81,8 @@ class FSRomsHandler(FSHandler): return regs, rev, langs, other_tags def _exclude_files(self, files, filetype) -> list[str]: - excluded_extensions = getattr(cm.config, f"EXCLUDED_{filetype.upper()}_EXT") - excluded_names = getattr(cm.config, f"EXCLUDED_{filetype.upper()}_FILES") + excluded_extensions = getattr(cm.get_config(), f"EXCLUDED_{filetype.upper()}_EXT") + excluded_names = getattr(cm.get_config(), f"EXCLUDED_{filetype.upper()}_FILES") excluded_files: list = [] for file_name in files: @@ -105,7 +105,7 @@ class FSRomsHandler(FSHandler): return [f for f in files if f not in excluded_files] def _exclude_multi_roms(self, roms) -> list[str]: - excluded_names = cm.config.EXCLUDED_MULTI_FILES + excluded_names = cm.get_config().EXCLUDED_MULTI_FILES filtered_files: list = [] for rom in roms: diff --git a/backend/handler/fs_handler/tests/test_fs.py b/backend/handler/fs_handler/tests/test_fs.py index f2d37a9d3..7e452fbaf 100644 --- a/backend/handler/fs_handler/tests/test_fs.py +++ b/backend/handler/fs_handler/tests/test_fs.py @@ -117,9 +117,9 @@ def test_rom_size(): def test_exclude_files(): from config.config_manager import config_manager as cm - cm.config.EXCLUDED_SINGLE_FILES = ["Super Mario 64 (J) (Rev A) [Part 1].z64"] + cm.add_exclusion("EXCLUDED_SINGLE_FILES", "Super Mario 64 (J) (Rev A) [Part 1].z64") - patch("utils.fs.config", cm.config) + patch("utils.fs.config", cm.get_config()) filtered_files = fs_rom_handler._exclude_files( files=[ @@ -131,7 +131,7 @@ def test_exclude_files(): assert len(filtered_files) == 1 - cm.config.EXCLUDED_SINGLE_EXT = ["z64"] + cm.add_exclusion("EXCLUDED_SINGLE_EXT", "z64") filtered_files = fs_rom_handler._exclude_files( files=[ @@ -143,7 +143,7 @@ def test_exclude_files(): assert len(filtered_files) == 0 - cm.config.EXCLUDED_SINGLE_FILES = ["*.z64"] + cm.add_exclusion("EXCLUDED_SINGLE_FILES", "*.z64") filtered_files = fs_rom_handler._exclude_files( files=[ @@ -155,7 +155,7 @@ def test_exclude_files(): assert len(filtered_files) == 0 - cm.config.EXCLUDED_SINGLE_FILES = ["_.*"] + cm.add_exclusion("EXCLUDED_SINGLE_FILES", "_.*") filtered_files = fs_rom_handler._exclude_files( files=[ diff --git a/backend/handler/scan_handler.py b/backend/handler/scan_handler.py index aa7d2e838..fd3fa07be 100644 --- a/backend/handler/scan_handler.py +++ b/backend/handler/scan_handler.py @@ -15,12 +15,12 @@ from models.platform import Platform from models.rom import Rom from models.user import User -SWAPPED_PLATFORM_BINDINGS = dict((v, k) for k, v in cm.config.PLATFORMS_BINDING.items()) +SWAPPED_PLATFORM_BINDINGS = dict((v, k) for k, v in cm.get_config().PLATFORMS_BINDING.items()) def _get_main_platform_igdb_id(platform: Platform): - if platform.fs_slug in cm.config.PLATFORMS_VERSIONS.keys(): - main_platform_slug = cm.config.PLATFORMS_VERSIONS[platform.fs_slug] + if platform.fs_slug in cm.get_config().PLATFORMS_VERSIONS.keys(): + main_platform_slug = cm.get_config().PLATFORMS_VERSIONS[platform.fs_slug] main_platform = db_platform_handler.get_platform_by_fs_slug(main_platform_slug) if main_platform: main_platform_igdb_id = main_platform.igdb_id @@ -60,8 +60,8 @@ def scan_platform(fs_slug: str, fs_platforms) -> Platform: platform_attrs["fs_slug"] = SWAPPED_PLATFORM_BINDINGS[platform.slug] try: - if fs_slug in cm.config.PLATFORMS_BINDING.keys(): - platform_attrs["slug"] = cm.config.PLATFORMS_BINDING[fs_slug] + if fs_slug in cm.get_config().PLATFORMS_BINDING.keys(): + platform_attrs["slug"] = cm.get_config().PLATFORMS_BINDING[fs_slug] else: platform_attrs["slug"] = fs_slug except (KeyError, TypeError, AttributeError): diff --git a/backend/watcher.py b/backend/watcher.py index a0ce1d605..65c411b8e 100644 --- a/backend/watcher.py +++ b/backend/watcher.py @@ -15,8 +15,8 @@ from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer path = ( - cm.config.HIGH_PRIO_STRUCTURE_PATH - if os.path.exists(cm.config.HIGH_PRIO_STRUCTURE_PATH) + cm.get_config().HIGH_PRIO_STRUCTURE_PATH + if os.path.exists(cm.get_config().HIGH_PRIO_STRUCTURE_PATH) else LIBRARY_BASE_PATH )