Amélioration de la configuration pour réduire les écritures disque

This commit is contained in:
2026-03-13 11:21:11 +01:00
parent 61e4e58ccf
commit 13b591a157
2 changed files with 40 additions and 25 deletions

View File

@@ -1,14 +1,21 @@
import json import json
import os
from pathlib import Path from pathlib import Path
from sys import argv, executable
from typing import Any, Callable, NotRequired, TypedDict, cast from typing import Any, Callable, NotRequired, TypedDict, cast
# Configuration du chemin du fichier de configuration avec son nom. # Configuration du chemin du fichier de configuration avec son nom.
def _get_config_path() -> Path: def _get_config_path() -> Path:
base_path = Path(executable if frozenset else os.path.realpath(argv[0])).parent.absolute() from sys import argv, executable
#return base_path / "config.json" import os
return Path(os.path.realpath(argv[0])).parent.absolute() / "config.json" import sys
from pathlib import Path
# Si l'app est packagée (PyInstaller)
if getattr(sys, "frozen", False):
base_path = Path(executable).parent
else:
base_path = Path(os.path.realpath(argv[0])).parent
return base_path / "config.json"
class ConfigData(TypedDict): class ConfigData(TypedDict):
discord_user_id: NotRequired[str] discord_user_id: NotRequired[str]
@@ -41,11 +48,13 @@ CONFIG_SCHEMA: dict[str, ConfigField] = {
} }
class ConfigManager: class ConfigManager:
def __init__(self, path: Path = CONFIG_PATH) -> None: def __init__(self, path: Path | None = None) -> None:
self.path = path self.path = path or _get_config_path()
self._data: ConfigData = self._load()
self._dirty = False
# Lecture du fichier de configuration # Lecture du fichier de configuration
def load(self) -> ConfigData: def _load(self) -> ConfigData:
if not self.path.exists(): if not self.path.exists():
return {} return {}
@@ -61,10 +70,16 @@ class ConfigManager:
return cast(ConfigData, data) return cast(ConfigData, data)
# Sauvegarde du fichier de configuration # Sauvegarde du fichier de configuration
def save(self, data: ConfigData) -> None: def save(self) -> None:
if not self._dirty:
return
self.path.parent.mkdir(parents=True, exist_ok=True) self.path.parent.mkdir(parents=True, exist_ok=True)
with self.path.open("w", encoding="utf-8") as file: with self.path.open("w", encoding="utf-8") as file:
json.dump(data, file, indent=4, ensure_ascii=False) json.dump(self._data, file, indent=4, ensure_ascii=False)
self._dirty = False
def _get_field(self, key: str) -> ConfigField: def _get_field(self, key: str) -> ConfigField:
if key not in CONFIG_SCHEMA: if key not in CONFIG_SCHEMA:
@@ -73,8 +88,7 @@ class ConfigManager:
def get(self, key: str) -> Any: def get(self, key: str) -> Any:
field = self._get_field(key) field = self._get_field(key)
data = self.load() value = self._data.get(key, field["default"])
value = data.get(key, field["default"])
if not field["validator"](value): if not field["validator"](value):
return field["default"] return field["default"]
@@ -83,20 +97,17 @@ class ConfigManager:
def set(self, key: str, value: Any) -> None: def set(self, key: str, value: Any) -> None:
field = self._get_field(key) field = self._get_field(key)
normalized_value = field["normalizer"](value)
if not field["validator"](normalized_value): normalized = field["normalizer"](value)
raise ValueError(f"Invalid value for config key: {key}")
data = self.load() if not field["validator"](normalized):
data[key] = normalized_value raise ValueError(f"Invalid value for {key}")
self.save(data)
def reset_key(self, key: str) -> None: if self._data.get(key) == normalized:
field = self._get_field(key) return
data = self.load()
data[key] = field["default"] self._data[key] = normalized
self.save(data) self._dirty = True
def reset_all(self) -> None: def reset_all(self) -> None:
defaults: ConfigData = cast( defaults: ConfigData = cast(

View File

@@ -190,7 +190,7 @@ class MainWindow(QMainWindow):
# On convertit en float pour QAudioOutput (0.0 à 1.0) # On convertit en float pour QAudioOutput (0.0 à 1.0)
volume = value / 100.0 volume = value / 100.0
self.audio_output.setVolume(volume) self.audio_output.setVolume(volume)
config.set_volume(value) self.config.set_volume(value)
def mute_btn_link(self) -> None: def mute_btn_link(self) -> None:
if not self.is_muted: if not self.is_muted:
@@ -206,7 +206,7 @@ class MainWindow(QMainWindow):
self.ui.mute_btn.setStyleSheet("background-color: red;") self.ui.mute_btn.setStyleSheet("background-color: red;")
self.is_muted = True self.is_muted = True
config.set_volume(0) self.config.set_volume(0)
else: else:
# --- RETOUR DU SON --- # --- RETOUR DU SON ---
# On restaure le volume précédent # On restaure le volume précédent
@@ -220,6 +220,10 @@ class MainWindow(QMainWindow):
self.is_muted = False self.is_muted = False
self.config.set_volume(self.previous_volume) self.config.set_volume(self.previous_volume)
def closeEvent(self, event):
self.config.save()
super().closeEvent(event)
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication(sys.argv) app = QApplication(sys.argv)