Intrégration du module de configuration pour ici sauvergarder le volume audio

This commit is contained in:
2026-03-13 10:59:05 +01:00
parent b2ba3964d3
commit 83200c4932
2 changed files with 138 additions and 2 deletions

126
src/config/configure.py Normal file
View File

@@ -0,0 +1,126 @@
import json
import os
from pathlib import Path
from sys import argv, executable
from typing import Any, Callable, NotRequired, TypedDict, cast
# Configuration du chemin du fichier de configuration avec son nom.
def _get_config_path() -> Path:
base_path = Path(executable if frozenset else os.path.realpath(argv[0])).parent.absolute()
#return base_path / "config.json"
return Path(os.path.realpath(argv[0])).parent.absolute() / "config.json"
class ConfigData(TypedDict):
discord_user_id: NotRequired[str]
volume: NotRequired[int]
Validator = Callable[[Any], bool]
Normalizer = Callable[[Any], Any]
class ConfigField(TypedDict):
default: Any
validator: Validator
normalizer: Normalizer
CONFIG_PATH = _get_config_path()
DISCORD_USER_KEY = "discord_user_id"
VOLUME_KEY = "volume"
CONFIG_SCHEMA: dict[str, ConfigField] = {
DISCORD_USER_KEY: {
"default": "",
"validator": lambda value: isinstance(value, str),
"normalizer": lambda value: str(value).strip(),
},
VOLUME_KEY: {
"default": 25,
"validator": lambda value: isinstance(value, int) and 0 <= value <= 100,
"normalizer": lambda value: max(0, min(int(value), 100)),
},
}
class ConfigManager:
def __init__(self, path: Path = CONFIG_PATH) -> None:
self.path = path
# Lecture du fichier de configuration
def load(self) -> ConfigData:
if not self.path.exists():
return {}
try:
with self.path.open("r", encoding="utf-8") as file:
data = json.load(file)
except (json.JSONDecodeError, OSError):
return {}
if not isinstance(data, dict):
return {}
return cast(ConfigData, data)
# Sauvegarde du fichier de configuration
def save(self, data: ConfigData) -> None:
self.path.parent.mkdir(parents=True, exist_ok=True)
with self.path.open("w", encoding="utf-8") as file:
json.dump(data, file, indent=4, ensure_ascii=False)
def _get_field(self, key: str) -> ConfigField:
if key not in CONFIG_SCHEMA:
raise KeyError(f"Unknown config key: {key}")
return CONFIG_SCHEMA[key]
def get(self, key: str) -> Any:
field = self._get_field(key)
data = self.load()
value = data.get(key, field["default"])
if not field["validator"](value):
return field["default"]
return value
def set(self, key: str, value: Any) -> None:
field = self._get_field(key)
normalized_value = field["normalizer"](value)
if not field["validator"](normalized_value):
raise ValueError(f"Invalid value for config key: {key}")
data = self.load()
data[key] = normalized_value
self.save(data)
def reset_key(self, key: str) -> None:
field = self._get_field(key)
data = self.load()
data[key] = field["default"]
self.save(data)
def reset_all(self) -> None:
defaults: ConfigData = cast(
ConfigData,
{key: field["default"] for key, field in CONFIG_SCHEMA.items()},
)
self.save(defaults)
def get_all(self) -> ConfigData:
return cast(
ConfigData,
{key: self.get(key) for key in CONFIG_SCHEMA},
)
# --------------- SETTERS MÉTIER -------------------------------
def set_discord_user(self, user_id: str) -> None:
self.set(DISCORD_USER_KEY, user_id)
def set_volume(self, volume: int) -> None:
self.set(VOLUME_KEY, volume)
# --------------- GETTERS MÉTIER -------------------------------
def get_discord_user(self) -> str:
return cast(str, self.get(DISCORD_USER_KEY))
def get_volume(self) -> int:
return cast(int, self.get(VOLUME_KEY))