Amélioration de la configuration pour réduire les écritures disque
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user