Unify configuration files into rgsx_settings.json and implement migration logic

This commit is contained in:
skymike03
2025-08-21 13:27:46 +02:00
parent f1bd6ff3e5
commit f19edc9e1e
17 changed files with 377 additions and 147 deletions
+2 -1
View File
@@ -10,4 +10,5 @@ ports/gamelist.xml
*.rar *.rar
*.zip *.zip
.vscode/ .vscode/
ports/RGSX.bat ports/RGSX.bat
.venv/
+71
View File
@@ -0,0 +1,71 @@
# Migration vers rgsx_settings.json
## Résumé des changements
Ce commit unifie les fichiers de configuration suivants en un seul fichier `rgsx_settings.json` :
- `accessibility.json``rgsx_settings.json` (clé: `accessibility`)
- `language.json``rgsx_settings.json` (clé: `language`)
- `music_config.json``rgsx_settings.json` (clé: `music_enabled`)
- `symlink_settings.json``rgsx_settings.json` (clé: `symlink`)
## Structure du nouveau fichier rgsx_settings.json
```json
{
"language": "fr",
"music_enabled": true,
"accessibility": {
"font_scale": 1.0
},
"symlink": {
"enabled": false,
"target_directory": ""
}
}
```
## Nouveau module rgsx_settings.py
Un nouveau module `rgsx_settings.py` a été créé pour centraliser la gestion des paramètres :
### Fonctions principales :
- `load_rgsx_settings()` : Charge tous les paramètres depuis rgsx_settings.json
- `save_rgsx_settings(settings)` : Sauvegarde tous les paramètres
- `migrate_old_settings()` : Migre automatiquement les anciens fichiers
## Fichiers modifiés
### Nouveau fichier : rgsx_settings.py
- Module dédié à la gestion des paramètres RGSX
- Contient toute la logique de chargement, sauvegarde et migration
- Documentation complète des fonctions
### config.py
- Ajout de `RGSX_SETTINGS_PATH`
- Import des fonctions depuis `rgsx_settings.py`
- Conservation temporaire des anciens chemins pour la migration
- Suppression des fonctions de gestion des paramètres (déplacées vers rgsx_settings.py)
### accessibility.py
- Import des fonctions depuis `rgsx_settings.py`
- Utilisation directe des fonctions importées au lieu de `config.`
### utils.py
- Import des fonctions depuis `rgsx_settings.py`
- Fonctions `load_music_config()` et `save_music_config()` mises à jour
### symlink_settings.py
- Import des fonctions depuis `rgsx_settings.py`
- Fonctions `load_symlink_settings()` et `save_symlink_settings()` mises à jour
- Compatibilité maintenue avec l'ancien format (`use_symlink_path`)
## Migration automatique
Le système détecte automatiquement les anciens fichiers et les migre vers le nouveau format :
1. Au premier lancement, `load_rgsx_settings()` vérifie si `rgsx_settings.json` existe
2. Si absent, il tente de migrer les données depuis les anciens fichiers
3. Les valeurs par défaut sont utilisées si aucun ancien fichier n'est trouvé
4. Le nouveau fichier unifié est créé automatiquement
5. Les anciens fichiers sont automatiquement supprimés après migration réussie
+13 -7
View File
@@ -104,6 +104,13 @@ config.repeat_last_action = 0
# Initialisation des variables pour la popup de musique # Initialisation des variables pour la popup de musique
# Initialisation du mixer Pygame
pygame.mixer.pre_init(44100, -16, 2, 4096)
pygame.mixer.init()
# Charger la configuration de la musique AVANT de lancer la musique
load_music_config()
# Dossier musique Batocera # Dossier musique Batocera
music_folder = os.path.join(config.APP_FOLDER, "assets", "music") music_folder = os.path.join(config.APP_FOLDER, "assets", "music")
music_files = [f for f in os.listdir(music_folder) if f.lower().endswith(('.ogg', '.mp3'))] music_files = [f for f in os.listdir(music_folder) if f.lower().endswith(('.ogg', '.mp3'))]
@@ -112,8 +119,12 @@ config.music_folder = music_folder
config.music_files = music_files config.music_files = music_files
config.current_music = current_music config.current_music = current_music
if music_files: # Lancer la musique seulement si elle est activée dans la configuration
if music_files and config.music_enabled:
current_music = play_random_music(music_files, music_folder, current_music) current_music = play_random_music(music_files, music_folder, current_music)
logger.debug("Musique lancée car activée dans la configuration")
elif music_files and not config.music_enabled:
logger.debug("Musique désactivée dans la configuration, pas de lecture")
else: else:
logger.debug("Aucune musique trouvée dans config.APP_FOLDER/assets/music") logger.debug("Aucune musique trouvée dans config.APP_FOLDER/assets/music")
@@ -149,11 +160,6 @@ if pygame.joystick.get_count() > 0:
joystick.init() joystick.init()
logger.debug("Gamepad initialisé") logger.debug("Gamepad initialisé")
# Initialisation du mixer Pygame
pygame.mixer.pre_init(44100, -16, 2, 4096)
pygame.mixer.init()
load_music_config()
# Boucle principale # Boucle principale
async def main(): async def main():
@@ -683,7 +689,7 @@ async def main():
elif config.menu_state == "loading": elif config.menu_state == "loading":
if loading_step == "none": if loading_step == "none":
loading_step = "test_internet" loading_step = "test_internet"
config.current_loading_system = _("loading_test_internet") config.current_loading_system = _("loading_test_connection")
config.loading_progress = 0.0 config.loading_progress = 0.0
config.needs_redraw = True config.needs_redraw = True
logger.debug(f"Étape chargement : {loading_step}, progress={config.loading_progress}") logger.debug(f"Étape chargement : {loading_step}, progress={config.loading_progress}")
+14 -16
View File
@@ -1,33 +1,31 @@
import pygame #type:ignore import pygame #type:ignore
import config import config
import os from rgsx_settings import load_rgsx_settings, save_rgsx_settings
import json
from logging import getLogger from logging import getLogger
from language import _ from language import _
logger = getLogger(__name__) logger = getLogger(__name__)
def load_accessibility_settings(): def load_accessibility_settings():
"""Charge les paramètres d'accessibilité depuis accessibility.json.""" """Charge les paramètres d'accessibilité depuis rgsx_settings.json."""
accessibility_path = os.path.join(config.SAVE_FOLDER, "accessibility.json")
try: try:
if os.path.exists(accessibility_path): settings = load_rgsx_settings()
with open(accessibility_path, 'r', encoding='utf-8') as f: return settings.get("accessibility", {"font_scale": 1.0})
return json.load(f)
except Exception as e: except Exception as e:
logger.error(f"Erreur lors du chargement de accessibility.json: {str(e)}") logger.error(f"Erreur lors du chargement des paramètres d'accessibilité: {str(e)}")
return {"font_scale": 1.0} return {"font_scale": 1.0}
def save_accessibility_settings(settings): def save_accessibility_settings(accessibility_settings):
"""Sauvegarde les paramètres d'accessibilité dans accessibility.json.""" """Sauvegarde les paramètres d'accessibilité dans rgsx_settings.json."""
accessibility_path = os.path.join(config.SAVE_FOLDER, "accessibility.json")
try: try:
os.makedirs(config.SAVE_FOLDER, exist_ok=True) settings = load_rgsx_settings()
with open(accessibility_path, 'w', encoding='utf-8') as f: settings["accessibility"] = accessibility_settings
json.dump(settings, f, indent=2) save_rgsx_settings(settings)
logger.debug(f"Paramètres d'accessibilité sauvegardés: {settings}") logger.debug(f"Paramètres d'accessibilité sauvegardés: {accessibility_settings}")
except Exception as e: except Exception as e:
logger.error(f"Erreur lors de la sauvegarde de accessibility.json: {str(e)}") logger.error(f"Erreur lors de la sauvegarde des paramètres d'accessibilité: {str(e)}")
def draw_accessibility_menu(screen): def draw_accessibility_menu(screen):
"""Affiche le menu d'accessibilité avec curseur pour la taille de police.""" """Affiche le menu d'accessibilité avec curseur pour la taille de police."""
+17 -5
View File
@@ -59,23 +59,35 @@ UPDATE_FOLDER = os.path.join(APP_FOLDER, "update")
GAMELISTXML = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms", "ports", "gamelist.xml") GAMELISTXML = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms", "ports", "gamelist.xml")
IMAGES_FOLDER = os.path.join(APP_FOLDER, "images", "systemes") IMAGES_FOLDER = os.path.join(APP_FOLDER, "images", "systemes")
GAMES_FOLDER = os.path.join(APP_FOLDER, "games") GAMES_FOLDER = os.path.join(APP_FOLDER, "games")
LANGUAGES_FOLDER = os.path.join(APP_FOLDER, "languages")
CONTROLS_CONFIG_PATH = os.path.join(SAVE_FOLDER, "controls.json") CONTROLS_CONFIG_PATH = os.path.join(SAVE_FOLDER, "controls.json")
HISTORY_PATH = os.path.join(SAVE_FOLDER, "history.json") HISTORY_PATH = os.path.join(SAVE_FOLDER, "history.json")
LANGUAGE_CONFIG_PATH = os.path.join(SAVE_FOLDER, "language.json")
JSON_EXTENSIONS = os.path.join(APP_FOLDER, "rom_extensions.json") JSON_EXTENSIONS = os.path.join(APP_FOLDER, "rom_extensions.json")
MUSIC_CONFIG_PATH = os.path.join(SAVE_FOLDER, "music_config.json")
UNRAR_EXE = os.path.join(APP_FOLDER,"assets", "unrar.exe")
XDVDFS_EXE = os.path.join(APP_FOLDER,"assets", "xdvdfs.exe")
XDVDFS_LINUX = os.path.join(APP_FOLDER,"assets", "xdvdfs")
# Nouveau fichier unifié pour les paramètres RGSX
RGSX_SETTINGS_PATH = os.path.join(SAVE_FOLDER, "rgsx_settings.json")
# Anciens chemins des fichiers de config (conservés temporairement pour la migration)
ACCESSIBILITY_FOLDER = os.path.join(SAVE_FOLDER, "accessibility.json")
LANGUAGE_CONFIG_PATH = os.path.join(SAVE_FOLDER, "language.json")
MUSIC_CONFIG_PATH = os.path.join(SAVE_FOLDER, "music_config.json")
SYMLINK_SETTINGS_PATH = os.path.join(SAVE_FOLDER, "symlink_settings.json")
# URL # URL
OTA_SERVER_URL = "https://retrogamesets.fr/softs/" OTA_SERVER_URL = "https://retrogamesets.fr/softs/"
OTA_VERSION_ENDPOINT = os.path.join(OTA_SERVER_URL, "version.json") OTA_VERSION_ENDPOINT = os.path.join(OTA_SERVER_URL, "version.json")
OTA_UPDATE_ZIP = os.path.join(OTA_SERVER_URL, "RGSX.zip") OTA_UPDATE_ZIP = os.path.join(OTA_SERVER_URL, "RGSX.zip")
OTA_data_ZIP = os.path.join(OTA_SERVER_URL, "rgsx-data.zip") OTA_data_ZIP = os.path.join(OTA_SERVER_URL, "rgsx-data.zip")
#CHEMINS DES EXECUTABLES
UNRAR_EXE = os.path.join(APP_FOLDER,"assets", "unrar.exe")
XDVDFS_EXE = os.path.join(APP_FOLDER,"assets", "xdvdfs.exe")
XDVDFS_LINUX = os.path.join(APP_FOLDER,"assets", "xdvdfs")
unrar_download_exe = os.path.join(OTA_SERVER_URL, "unrar.exe") unrar_download_exe = os.path.join(OTA_SERVER_URL, "unrar.exe")
xdvdfs_download_exe = os.path.join(OTA_SERVER_URL, "xdvdfs.exe") xdvdfs_download_exe = os.path.join(OTA_SERVER_URL, "xdvdfs.exe")
# Import des fonctions de gestion des paramètres RGSX
from rgsx_settings import load_rgsx_settings, save_rgsx_settings, migrate_old_settings
xdvdfs_download_linux = os.path.join(OTA_SERVER_URL, "xdvdfs") xdvdfs_download_linux = os.path.join(OTA_SERVER_URL, "xdvdfs")
# Constantes pour la répétition automatique dans pause_menu # Constantes pour la répétition automatique dans pause_menu
+1 -1
View File
@@ -889,7 +889,7 @@ def handle_controls(event, sources, joystick, screen):
config.needs_redraw = True config.needs_redraw = True
logger.info(f"Musique {'activée' if config.music_enabled else 'désactivée'} via menu pause") logger.info(f"Musique {'activée' if config.music_enabled else 'désactivée'} via menu pause")
elif config.selected_option == 7: # Symlink option elif config.selected_option == 7: # Symlink option
from symlink_settings import set_symlink_option, get_symlink_option from rgsx_settings import set_symlink_option, get_symlink_option
current_status = get_symlink_option() current_status = get_symlink_option()
success, message = set_symlink_option(not current_status) success, message = set_symlink_option(not current_status)
config.popup_message = message config.popup_message = message
+1 -1
View File
@@ -1215,7 +1215,7 @@ def draw_pause_menu(screen, selected_option):
music_option = _("menu_music_disabled") music_option = _("menu_music_disabled")
# Option symlink dynamique # Option symlink dynamique
from symlink_settings import get_symlink_option from rgsx_settings import get_symlink_option
if get_symlink_option(): if get_symlink_option():
symlink_option = _("symlink_option_enabled") symlink_option = _("symlink_option_enabled")
else: else:
+4 -5
View File
@@ -7,11 +7,10 @@ from datetime import datetime
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Chemin par défaut pour history.json # Chemin par défaut pour history.json
DEFAULT_HISTORY_PATH = os.path.join(config.SAVE_FOLDER, "history.json")
def init_history(): def init_history():
"""Initialise le fichier history.json s'il n'existe pas.""" """Initialise le fichier history.json s'il n'existe pas."""
history_path = getattr(config, 'HISTORY_PATH', DEFAULT_HISTORY_PATH) history_path = getattr(config, 'HISTORY_PATH')
# Vérifie si le fichier history.json existe, sinon le crée # Vérifie si le fichier history.json existe, sinon le crée
if not os.path.exists(history_path): if not os.path.exists(history_path):
try: try:
@@ -27,7 +26,7 @@ def init_history():
def load_history(): def load_history():
"""Charge l'historique depuis history.json.""" """Charge l'historique depuis history.json."""
history_path = getattr(config, 'HISTORY_PATH', DEFAULT_HISTORY_PATH) history_path = getattr(config, 'HISTORY_PATH')
try: try:
if not os.path.exists(history_path): if not os.path.exists(history_path):
logger.debug(f"Aucun fichier d'historique trouvé à {history_path}") logger.debug(f"Aucun fichier d'historique trouvé à {history_path}")
@@ -47,7 +46,7 @@ def load_history():
def save_history(history): def save_history(history):
"""Sauvegarde l'historique dans history.json.""" """Sauvegarde l'historique dans history.json."""
history_path = getattr(config, 'HISTORY_PATH', DEFAULT_HISTORY_PATH) history_path = getattr(config, 'HISTORY_PATH')
try: try:
os.makedirs(os.path.dirname(history_path), exist_ok=True) os.makedirs(os.path.dirname(history_path), exist_ok=True)
with open(history_path, "w", encoding='utf-8') as f: with open(history_path, "w", encoding='utf-8') as f:
@@ -76,7 +75,7 @@ def add_to_history(platform, game_name, status, url=None, progress=0, message=No
def clear_history(): def clear_history():
"""Vide l'historique.""" """Vide l'historique."""
history_path = getattr(config, 'HISTORY_PATH', DEFAULT_HISTORY_PATH) history_path = getattr(config, 'HISTORY_PATH')
try: try:
with open(history_path, "w", encoding='utf-8') as f: with open(history_path, "w", encoding='utf-8') as f:
json.dump([], f) json.dump([], f)
+14 -28
View File
@@ -4,6 +4,7 @@ import pygame #type: ignore
import logging import logging
import config import config
import subprocess import subprocess
from rgsx_settings import load_rgsx_settings, save_rgsx_settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -13,6 +14,7 @@ current_language = DEFAULT_LANGUAGE
translations = {} translations = {}
show_language_selector_on_startup = False show_language_selector_on_startup = False
# Mapping optionnel pour normaliser les locales Batocera -> codes 2 lettres # Mapping optionnel pour normaliser les locales Batocera -> codes 2 lettres
BATOCERA_LOCALE_MAP = { BATOCERA_LOCALE_MAP = {
"en_US": "en", "en_US": "en",
@@ -43,6 +45,7 @@ def load_language(lang_code=None):
logger.error(f"Fichier de langue par défaut {lang_file} non trouvé") logger.error(f"Fichier de langue par défaut {lang_file} non trouvé")
return False return False
with open(lang_file, 'r', encoding='utf-8') as f: with open(lang_file, 'r', encoding='utf-8') as f:
translations = json.load(f) translations = json.load(f)
@@ -74,14 +77,13 @@ def get_text(key, default=None):
def get_available_languages(): def get_available_languages():
"""Récupère la liste des langues disponibles.""" """Récupère la liste des langues disponibles."""
languages_dir = os.path.join(config.APP_FOLDER, "languages")
if not os.path.exists(languages_dir): if not os.path.exists(config.LANGUAGES_FOLDER):
logger.warning(f"Dossier des langues {languages_dir} non trouvé") logger.warning(f"Dossier des langues {config.LANGUAGES_FOLDER} non trouvé")
return [] return []
languages = [] languages = []
for file in os.listdir(languages_dir): for file in os.listdir(config.LANGUAGES_FOLDER):
if file.endswith(".json"): if file.endswith(".json"):
lang_code = os.path.splitext(file)[0] lang_code = os.path.splitext(file)[0]
languages.append(lang_code) languages.append(lang_code)
@@ -97,14 +99,11 @@ def set_language(lang_code):
return False return False
def save_language_preference(lang_code): def save_language_preference(lang_code):
"""Sauvegarde la préférence de langue dans un fichier.""" """Sauvegarde la préférence de langue dans rgsx_settings.json."""
try: try:
# S'assurer que le dossier existe settings = load_rgsx_settings()
os.makedirs(os.path.dirname(config.LANGUAGE_CONFIG_PATH), exist_ok=True) settings["language"] = lang_code
save_rgsx_settings(settings)
# Sauvegarder la préférence
with open(config.LANGUAGE_CONFIG_PATH, 'w', encoding='utf-8') as f:
json.dump({"language": lang_code}, f)
logger.debug(f"Préférence de langue sauvegardée: {lang_code}") logger.debug(f"Préférence de langue sauvegardée: {lang_code}")
return True return True
@@ -113,26 +112,13 @@ def save_language_preference(lang_code):
return False return False
def load_language_preference(): def load_language_preference():
"""Charge la préférence de langue depuis le fichier.""" """Charge la préférence de langue depuis rgsx_settings.json."""
global show_language_selector_on_startup global show_language_selector_on_startup
try: try:
if not os.path.exists(config.LANGUAGE_CONFIG_PATH): settings = load_rgsx_settings()
logger.info("Aucune préférence de langue trouvée, utilisation du français par défaut") lang_code = settings.get("language", DEFAULT_LANGUAGE)
# Créer le fichier avec le français par défaut
save_language_preference(DEFAULT_LANGUAGE)
return DEFAULT_LANGUAGE
with open(config.LANGUAGE_CONFIG_PATH, 'r', encoding='utf-8') as f:
data = json.load(f)
lang_code = data.get("language", DEFAULT_LANGUAGE)
return lang_code return lang_code
except json.JSONDecodeError:
logger.warning("Fichier de préférence de langue corrompu, utilisation du français par défaut")
# Recréer le fichier avec le français par défaut
save_language_preference(DEFAULT_LANGUAGE)
return DEFAULT_LANGUAGE
except Exception as e: except Exception as e:
logger.error(f"Erreur lors du chargement de la préférence de langue: {str(e)}") logger.error(f"Erreur lors du chargement de la préférence de langue: {str(e)}")
# Recréer le fichier avec le français par défaut # Recréer le fichier avec le français par défaut
@@ -368,7 +354,7 @@ def initialize_language():
global show_language_selector_on_startup global show_language_selector_on_startup
# Vérifier si le fichier de préférence de langue existe # Vérifier si le fichier de préférence de langue existe
language_file_exists = os.path.exists(config.LANGUAGE_CONFIG_PATH) language_file_exists = os.path.exists(config.RGSX_SETTINGS_PATH)
if not language_file_exists: if not language_file_exists:
# Tentative de détection Batocera # Tentative de détection Batocera
-1
View File
@@ -17,7 +17,6 @@
"loading_extract_initial": "Extrahieren des initialen Datenordners...", "loading_extract_initial": "Extrahieren des initialen Datenordners...",
"loading_systems": "Systeme werden geladen...", "loading_systems": "Systeme werden geladen...",
"loading_progress": "Fortschritt: {0}%", "loading_progress": "Fortschritt: {0}%",
"loading_test_internet": "Verbindung wird getestet...",
"loading_check_updates": "Aktualisierungen werden geprüft... Bitte warten...", "loading_check_updates": "Aktualisierungen werden geprüft... Bitte warten...",
"error_check_updates_failed": "Überprüfung auf Updates fehlgeschlagen.", "error_check_updates_failed": "Überprüfung auf Updates fehlgeschlagen.",
"loading_downloading_games_images": "Spiele und Bilder werden heruntergeladen...", "loading_downloading_games_images": "Spiele und Bilder werden heruntergeladen...",
+8
View File
@@ -13,9 +13,17 @@
"loading_test_connection": "Testing connection...", "loading_test_connection": "Testing connection...",
"loading_update_check": "Checking for updates... Please wait...", "loading_update_check": "Checking for updates... Please wait...",
"loading_download_data": "Downloading initial Data folder...", "loading_download_data": "Downloading initial Data folder...",
"loading_download_initial": "Downloading initial Data folder...",
"loading_extract_initial": "Extracting initial Data folder...", "loading_extract_initial": "Extracting initial Data folder...",
"loading_systems": "Loading systems...", "loading_systems": "Loading systems...",
"loading_progress": "Progress: {0}%", "loading_progress": "Progress: {0}%",
"loading_check_updates": "Checking for updates... Please wait...",
"error_check_updates_failed": "Failed to check updates.",
"loading_downloading_games_images": "Downloading games and images...",
"loading_extracting_data": "Extracting initial Data folder...",
"loading_load_systems": "Loading systems...",
"error_extract_data_failed": "Failed to download or extract the initial Data folder.",
"error_sources_load_failed": "Failed to load sources.json",
"error_no_internet": "No Internet connection. Check your network.", "error_no_internet": "No Internet connection. Check your network.",
"error_load_sources": "Failed to load sources.json", "error_load_sources": "Failed to load sources.json",
-2
View File
@@ -17,8 +17,6 @@
"loading_extract_initial": "Extrayendo la carpeta de datos inicial...", "loading_extract_initial": "Extrayendo la carpeta de datos inicial...",
"loading_systems": "Cargando sistemas...", "loading_systems": "Cargando sistemas...",
"loading_progress": "Progreso: {0}%", "loading_progress": "Progreso: {0}%",
"loading_test_internet": "Probando la conexión...",
"loading_check_updates": "Buscando actualizaciones... Espere...", "loading_check_updates": "Buscando actualizaciones... Espere...",
"error_check_updates_failed": "Error al comprobar actualizaciones.", "error_check_updates_failed": "Error al comprobar actualizaciones.",
"loading_downloading_games_images": "Descargando juegos e imágenes...", "loading_downloading_games_images": "Descargando juegos e imágenes...",
-1
View File
@@ -13,7 +13,6 @@
"loading_extract_initial": "Extraction du dossier de données initial...", "loading_extract_initial": "Extraction du dossier de données initial...",
"loading_systems": "Chargement des systèmes...", "loading_systems": "Chargement des systèmes...",
"loading_progress": "Progression : {0}%", "loading_progress": "Progression : {0}%",
"loading_test_internet": "Test de la connexion...",
"loading_check_updates": "Vérification des mises à jour... Veuillez patienter...", "loading_check_updates": "Vérification des mises à jour... Veuillez patienter...",
"error_check_updates_failed": "Échec de la vérification des mises à jour.", "error_check_updates_failed": "Échec de la vérification des mises à jour.",
"loading_downloading_games_images": "Téléchargement des jeux et images...", "loading_downloading_games_images": "Téléchargement des jeux et images...",
+2 -2
View File
@@ -177,7 +177,7 @@ async def download_rom(url, platform, game_name, is_zip_non_supported=False, tas
logger.debug(f"Thread téléchargement démarré pour {url}, task_id={task_id}") logger.debug(f"Thread téléchargement démarré pour {url}, task_id={task_id}")
try: try:
# Use symlink path if enabled # Use symlink path if enabled
from symlink_settings import apply_symlink_path from rgsx_settings import apply_symlink_path
dest_dir = None dest_dir = None
for platform_dict in config.platform_dicts: for platform_dict in config.platform_dicts:
@@ -383,7 +383,7 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
link = url.split('&af=')[0] link = url.split('&af=')[0]
logger.debug(f"URL nettoyée: {link}") logger.debug(f"URL nettoyée: {link}")
# Use symlink path if enabled # Use symlink path if enabled
from symlink_settings import apply_symlink_path from rgsx_settings import apply_symlink_path
dest_dir = None dest_dir = None
for platform_dict in config.platform_dicts: for platform_dict in config.platform_dicts:
+219
View File
@@ -0,0 +1,219 @@
#!/usr/bin/env python3
"""
Module de gestion des paramètres RGSX
Gère le fichier unifié rgsx_settings.json qui remplace les anciens fichiers :
- accessibility.json
- language.json
- music_config.json
- symlink_settings.json
"""
import json
import os
import logging
logger = logging.getLogger(__name__)
def load_rgsx_settings():
"""Charge tous les paramètres depuis rgsx_settings.json."""
from config import RGSX_SETTINGS_PATH
default_settings = {
"language": "fr",
"music_enabled": True,
"accessibility": {
"font_scale": 1.0
},
"symlink": {
"enabled": False,
"target_directory": ""
}
}
try:
if os.path.exists(RGSX_SETTINGS_PATH):
with open(RGSX_SETTINGS_PATH, 'r', encoding='utf-8') as f:
settings = json.load(f)
# Fusionner avec les valeurs par défaut pour assurer la compatibilité
for key, value in default_settings.items():
if key not in settings:
settings[key] = value
return settings
else:
# Tenter de migrer depuis les anciens fichiers
migrated_settings = migrate_old_settings()
if migrated_settings:
save_rgsx_settings(migrated_settings)
return migrated_settings
except Exception as e:
print(f"Erreur lors du chargement de rgsx_settings.json: {str(e)}")
return default_settings
def save_rgsx_settings(settings):
"""Sauvegarde tous les paramètres dans rgsx_settings.json."""
from config import RGSX_SETTINGS_PATH, SAVE_FOLDER
try:
os.makedirs(SAVE_FOLDER, exist_ok=True)
with open(RGSX_SETTINGS_PATH, 'w', encoding='utf-8') as f:
json.dump(settings, f, indent=2, ensure_ascii=False)
except Exception as e:
print(f"Erreur lors de la sauvegarde de rgsx_settings.json: {str(e)}")
def migrate_old_settings():
"""Migre les anciens fichiers de configuration vers le nouveau format."""
from config import LANGUAGE_CONFIG_PATH, MUSIC_CONFIG_PATH, ACCESSIBILITY_FOLDER, SYMLINK_SETTINGS_PATH
migrated_settings = {
"language": "en",
"music_enabled": True,
"accessibility": {
"font_scale": 1.0
},
"symlink": {
"enabled": False,
"target_directory": ""
}
}
files_to_remove = [] # Liste des fichiers à supprimer après migration réussie
# Migrer language.json
if os.path.exists(LANGUAGE_CONFIG_PATH):
try:
with open(LANGUAGE_CONFIG_PATH, 'r', encoding='utf-8') as f:
content = f.read().strip()
# Gérer le cas où le fichier contient juste une chaîne (pas de JSON)
if content.startswith('"') and content.endswith('"'):
migrated_settings["language"] = content.strip('"')
elif not content.startswith('{'):
# Fichier texte simple sans guillemets
migrated_settings["language"] = content
else:
# Fichier JSON normal
lang_data = json.loads(content)
migrated_settings["language"] = lang_data.get("language", "en")
files_to_remove.append(LANGUAGE_CONFIG_PATH)
except:
pass
# Migrer music_config.json
if os.path.exists(MUSIC_CONFIG_PATH):
try:
with open(MUSIC_CONFIG_PATH, 'r', encoding='utf-8') as f:
content = f.read().strip()
# Gérer le cas où le fichier contient juste un booléen
if content.lower() in ['true', 'false']:
migrated_settings["music_enabled"] = content.lower() == 'true'
else:
# Fichier JSON normal
music_data = json.loads(content)
migrated_settings["music_enabled"] = music_data.get("music_enabled", True)
files_to_remove.append(MUSIC_CONFIG_PATH)
except:
pass
# Migrer accessibility.json
if os.path.exists(ACCESSIBILITY_FOLDER):
try:
with open(ACCESSIBILITY_FOLDER, 'r', encoding='utf-8') as f:
acc_data = json.load(f)
migrated_settings["accessibility"] = {
"font_scale": acc_data.get("font_scale", 1.0)
}
files_to_remove.append(ACCESSIBILITY_FOLDER)
except:
pass
# Migrer symlink_settings.json
if os.path.exists(SYMLINK_SETTINGS_PATH):
try:
with open(SYMLINK_SETTINGS_PATH, 'r', encoding='utf-8') as f:
symlink_data = json.load(f)
migrated_settings["symlink"] = {
"enabled": symlink_data.get("use_symlink_path", False),
"target_directory": symlink_data.get("target_directory", "")
}
files_to_remove.append(SYMLINK_SETTINGS_PATH)
except:
pass
# Supprimer les anciens fichiers après migration réussie
if files_to_remove:
print(f"Migration réussie. Suppression des anciens fichiers de configuration...")
for file_path in files_to_remove:
try:
os.remove(file_path)
print(f" - Supprimé: {os.path.basename(file_path)}")
except Exception as e:
print(f" - Erreur lors de la suppression de {os.path.basename(file_path)}: {e}")
return migrated_settings
def load_symlink_settings():
"""Load symlink settings from rgsx_settings.json."""
try:
settings = load_rgsx_settings()
symlink_settings = settings.get("symlink", {"enabled": False, "target_directory": ""})
# Convertir l'ancien format si nécessaire
if not isinstance(symlink_settings, dict):
symlink_settings = {"enabled": False, "target_directory": ""}
# Compatibilité avec l'ancien nom "use_symlink_path"
if "use_symlink_path" in symlink_settings:
symlink_settings["enabled"] = symlink_settings.pop("use_symlink_path")
return {"use_symlink_path": symlink_settings.get("enabled", False)}
except Exception as e:
logger.error(f"Error loading symlink settings: {str(e)}")
# Return default settings (disabled)
return {"use_symlink_path": False}
def save_symlink_settings(settings_to_save):
"""Save symlink settings to rgsx_settings.json."""
try:
settings = load_rgsx_settings()
# Convertir le format pour le nouveau système
settings["symlink"] = {
"enabled": settings_to_save.get("use_symlink_path", False),
"target_directory": settings_to_save.get("target_directory", "")
}
save_rgsx_settings(settings)
logger.debug(f"Symlink settings saved: {settings_to_save}")
return True
except Exception as e:
logger.error(f"Error saving symlink settings: {str(e)}")
return False
def set_symlink_option(enabled):
"""Enable or disable the symlink option."""
settings = load_symlink_settings()
settings["use_symlink_path"] = enabled
if save_symlink_settings(settings):
return True, "symlink_settings_saved_successfully"
else:
return False, "symlink_settings_save_error"
def get_symlink_option():
"""Get current symlink option status."""
settings = load_symlink_settings()
return settings.get("use_symlink_path", False)
def apply_symlink_path(base_path, platform_folder):
"""Apply symlink path modification if enabled."""
if get_symlink_option():
# Append the platform folder name to create symlink path
return os.path.join(base_path, platform_folder, platform_folder)
else:
# Return original path
return os.path.join(base_path, platform_folder)
-63
View File
@@ -1,63 +0,0 @@
import os
import json
import logging
import config
from language import _
logger = logging.getLogger(__name__)
# Path for symlink settings
SYMLINK_SETTINGS_PATH = os.path.join(config.SAVE_FOLDER, "symlink_settings.json")
def load_symlink_settings():
"""Load symlink settings from file."""
try:
if os.path.exists(SYMLINK_SETTINGS_PATH):
with open(SYMLINK_SETTINGS_PATH, 'r', encoding='utf-8') as f:
settings = json.load(f)
if not isinstance(settings, dict):
settings = {}
if "use_symlink_path" not in settings:
settings["use_symlink_path"] = False
return settings
except Exception as e:
logger.error(f"Error loading symlink settings: {str(e)}")
# Return default settings (disabled)
return {"use_symlink_path": False}
def save_symlink_settings(settings):
"""Save symlink settings to file."""
try:
os.makedirs(config.SAVE_FOLDER, exist_ok=True)
with open(SYMLINK_SETTINGS_PATH, 'w', encoding='utf-8') as f:
json.dump(settings, f, indent=2)
logger.debug(f"Symlink settings saved: {settings}")
return True
except Exception as e:
logger.error(f"Error saving symlink settings: {str(e)}")
return False
def set_symlink_option(enabled):
"""Enable or disable the symlink option."""
settings = load_symlink_settings()
settings["use_symlink_path"] = enabled
if save_symlink_settings(settings):
return True, _("symlink_settings_saved_successfully")
else:
return False, _("symlink_settings_save_error")
def get_symlink_option():
"""Get current symlink option status."""
settings = load_symlink_settings()
return settings.get("use_symlink_path", False)
def apply_symlink_path(base_path, platform_folder):
"""Apply symlink path modification if enabled."""
if get_symlink_option():
# Append the platform folder name to create symlink path
return os.path.join(base_path, platform_folder, platform_folder)
else:
# Return original path
return os.path.join(base_path, platform_folder)
+11 -14
View File
@@ -8,6 +8,7 @@ import platform
import subprocess import subprocess
import config import config
import threading import threading
from rgsx_settings import load_rgsx_settings, save_rgsx_settings
import zipfile import zipfile
import time import time
import random import random
@@ -820,29 +821,25 @@ def load_api_key_1fichier():
return "" return ""
def load_music_config(): def load_music_config():
"""Charge la configuration musique depuis music_config.json.""" """Charge la configuration musique depuis rgsx_settings.json."""
path = config.MUSIC_CONFIG_PATH
try: try:
if os.path.exists(path): settings = load_rgsx_settings()
with open(path, "r", encoding="utf-8") as f: config.music_enabled = settings.get("music_enabled", True)
data = json.load(f) return config.music_enabled
config.music_enabled = data.get("music_enabled", True)
return config.music_enabled
except Exception as e: except Exception as e:
logger.error(f"Erreur lors du chargement de music_config.json: {str(e)}") logger.error(f"Erreur lors du chargement de la configuration musique: {str(e)}")
config.music_enabled = True config.music_enabled = True
return True return True
def save_music_config(): def save_music_config():
"""Sauvegarde la configuration musique dans music_config.json.""" """Sauvegarde la configuration musique dans rgsx_settings.json."""
path = config.MUSIC_CONFIG_PATH
try: try:
os.makedirs(config.SAVE_FOLDER, exist_ok=True) settings = load_rgsx_settings()
with open(path, "w", encoding="utf-8") as f: settings["music_enabled"] = config.music_enabled
json.dump({"music_enabled": config.music_enabled}, f, indent=2) save_rgsx_settings(settings)
logger.debug(f"Configuration musique sauvegardée: {config.music_enabled}") logger.debug(f"Configuration musique sauvegardée: {config.music_enabled}")
except Exception as e: except Exception as e:
logger.error(f"Erreur lors de la sauvegarde de music_config.json: {str(e)}") logger.error(f"Erreur lors de la sauvegarde de la configuration musique: {str(e)}")
def normalize_platform_name(platform): def normalize_platform_name(platform):