Intrégration du module de configuration pour ici sauvergarder le volume audio
This commit is contained in:
126
src/config/configure.py
Normal file
126
src/config/configure.py
Normal 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))
|
||||||
@@ -9,9 +9,12 @@ from PySide6.QtUiTools import QUiLoader
|
|||||||
from PySide6.QtWidgets import QMainWindow, QApplication, QGraphicsDropShadowEffect
|
from PySide6.QtWidgets import QMainWindow, QApplication, QGraphicsDropShadowEffect
|
||||||
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
|
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
|
||||||
|
|
||||||
|
from config.configure import ConfigManager
|
||||||
|
|
||||||
# Compile resources.qrc into resources_rc.py
|
# Compile resources.qrc into resources_rc.py
|
||||||
# rcc -g python .\resources.qrc -o .\src\resources_rc.py
|
# rcc -g python .\resources.qrc -o .\src\resources_rc.py
|
||||||
|
|
||||||
|
# import utilisé pour la font custom
|
||||||
import resources as resources # This is generated from the .qrc file # noqa: F401
|
import resources as resources # This is generated from the .qrc file # noqa: F401
|
||||||
|
|
||||||
# Remove this into final release
|
# Remove this into final release
|
||||||
@@ -73,8 +76,10 @@ class MainWindow(QMainWindow):
|
|||||||
self.media_player.setSourceDevice(self.mp3buffer)
|
self.media_player.setSourceDevice(self.mp3buffer)
|
||||||
|
|
||||||
# Définir la valeur initiale du slider (ici: 10%)
|
# Définir la valeur initiale du slider (ici: 10%)
|
||||||
self.ui.audio_volume_adjust.setValue(10)
|
#self.ui.audio_volume_adjust.setValue(10)
|
||||||
self.audio_output.setVolume(0.1)
|
self.ui.audio_volume_adjust.setValue(config.get_volume())
|
||||||
|
#self.audio_output.setVolume(0.1)
|
||||||
|
self.audio_output.setVolume(config.get_volume() / 100)
|
||||||
|
|
||||||
# Initialisation de la mémoire du volume (par défaut 10%)
|
# Initialisation de la mémoire du volume (par défaut 10%)
|
||||||
self.previous_volume = 10
|
self.previous_volume = 10
|
||||||
@@ -181,6 +186,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)
|
||||||
|
|
||||||
def mute_btn_link(self) -> None:
|
def mute_btn_link(self) -> None:
|
||||||
if not self.is_muted:
|
if not self.is_muted:
|
||||||
@@ -196,6 +202,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)
|
||||||
else:
|
else:
|
||||||
# --- RETOUR DU SON ---
|
# --- RETOUR DU SON ---
|
||||||
# On restaure le volume précédent
|
# On restaure le volume précédent
|
||||||
@@ -207,8 +214,11 @@ class MainWindow(QMainWindow):
|
|||||||
self.ui.mute_btn.setStyleSheet("")
|
self.ui.mute_btn.setStyleSheet("")
|
||||||
|
|
||||||
self.is_muted = False
|
self.is_muted = False
|
||||||
|
config.set_volume(self.previous_volume)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# Initialisation de la configuration
|
||||||
|
config = ConfigManager()
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
|
||||||
with open(f"{bundle_dir}/styles/styles.qss", 'r') as f:
|
with open(f"{bundle_dir}/styles/styles.qss", 'r') as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user