1
0
forked from Mirrors/RGSX

V2.2.0.5 - Implement support for unknown file extensions in system , ability to deactivate warning (Introduced new settings in rgsx_settings.py for this)

- If file is ZIP and extension supported download and extract without error
- Updated various parts of the codebase to check for this setting before blocking downloads.
- Added Italian translation
This commit is contained in:
skymike03
2025-09-10 18:39:27 +02:00
parent 44bf0eda24
commit 8d1f57d13e
12 changed files with 468 additions and 82 deletions

View File

@@ -27,7 +27,7 @@ from display import (
draw_confirm_dialog, draw_redownload_game_cache_dialog, draw_popup, draw_gradient,
THEME_COLORS
)
from language import handle_language_menu_events, _
from language import _
from network import test_internet, download_rom, is_1fichier_url, download_from_1fichier, check_for_updates
from controls import handle_controls, validate_menu_state, process_key_repeats, get_emergency_controls
from controls_mapper import map_controls, draw_controls_mapping, get_actions
@@ -200,7 +200,7 @@ else:
config.joystick = True
config.keyboard = False
print(f"Joysticks détectés: {joystick_names}")
logger.debug(f"Joysticks détectés: {joystick_names}, utilisation du joystick par défaut.")
logger.debug(f"Joysticks détectés: {joystick_names}")
for idx, name in enumerate(joystick_names):
lname = name.lower()
if ("xbox" in lname) or ("x-box" in lname) or ("xinput" in lname) or ("microsoft x-box" in lname) or ("x-box 360" in lname) or ("360" in lname):
@@ -244,12 +244,6 @@ else:
logger.debug("Aucun contrôleur spécifique détecté, utilisation du profil générique")
# Vérification des dossiers pour le débogage
logger.debug(f"SYSTEM_FOLDER: {config.SYSTEM_FOLDER}")
logger.debug(f"ROMS_FOLDER: {config.ROMS_FOLDER}")
logger.debug(f"SAVE_FOLDER: {config.SAVE_FOLDER}")
logger.debug(f"APP_FOLDER: {config.APP_FOLDER}")
# Initialisation des variables de grille
config.current_page = 0
@@ -589,49 +583,79 @@ async def main():
logger.error("Clé API 1fichier absente")
config.pending_download = None
continue
is_supported, message, is_zip_non_supported = check_extension_before_download(url, platform, game_name)
if not is_supported:
config.pending_download = (url, platform, game_name, is_zip_non_supported)
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
pending = check_extension_before_download(url, platform, game_name)
if not pending:
config.menu_state = "error"
config.error_message = _("error_invalid_download_data") if _ else "Invalid download data"
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour lien 1fichier, passage à extension_warning pour {game_name}")
# Supprimer l'entrée temporaire si erreur
logger.error(f"check_extension_before_download a échoué pour {game_name}")
config.history.pop()
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
# Lancer le téléchargement dans une tâche asynchrone
task_id = str(pygame.time.get_ticks())
config.download_tasks[task_id] = (
asyncio.create_task(download_from_1fichier(url, platform, game_name, is_zip_non_supported)),
url, game_name, platform
)
config.menu_state = "history" # Passer à l'historique
config.needs_redraw = True
logger.debug(f"Téléchargement 1fichier démarré pour {game_name}, passage à l'historique")
from utils import is_extension_supported, load_extensions_json, sanitize_filename
from rgsx_settings import get_allow_unknown_extensions
is_supported = is_extension_supported(sanitize_filename(game_name), platform, load_extensions_json())
zip_ok = bool(pending[3])
allow_unknown = False
try:
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.pending_download = pending
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour lien 1fichier, passage à extension_warning pour {game_name}")
config.history.pop()
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
# Lancer le téléchargement dans une tâche asynchrone
task_id = str(pygame.time.get_ticks())
config.download_tasks[task_id] = (
asyncio.create_task(download_from_1fichier(url, platform, game_name, zip_ok)),
url, game_name, platform
)
config.menu_state = "history" # Passer à l'historique
config.needs_redraw = True
logger.debug(f"Téléchargement 1fichier démarré pour {game_name}, passage à l'historique")
else:
is_supported, message, is_zip_non_supported = check_extension_before_download(url, platform, game_name)
if not is_supported:
config.pending_download = (url, platform, game_name, is_zip_non_supported)
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
pending = check_extension_before_download(url, platform, game_name)
if not pending:
config.menu_state = "error"
config.error_message = _("error_invalid_download_data") if _ else "Invalid download data"
config.needs_redraw = True
logger.debug(f"Extension non reconnue, passage à extension_warning pour {game_name}")
# Supprimer l'entrée temporaire si erreur
logger.error(f"check_extension_before_download a échoué pour {game_name}")
config.history.pop()
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
# Lancer le téléchargement dans une tâche asynchrone
task_id = str(pygame.time.get_ticks())
config.download_tasks[task_id] = (
asyncio.create_task(download_rom(url, platform, game_name, is_zip_non_supported)),
url, game_name, platform
)
config.menu_state = "history" # Passer à l'historique
config.needs_redraw = True
logger.debug(f"Téléchargement démarré pour {game_name}, passage à l'historique")
from utils import is_extension_supported, load_extensions_json, sanitize_filename
from rgsx_settings import get_allow_unknown_extensions
is_supported = is_extension_supported(sanitize_filename(game_name), platform, load_extensions_json())
zip_ok = bool(pending[3])
allow_unknown = False
try:
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.pending_download = pending
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
config.needs_redraw = True
logger.debug(f"Extension non reconnue, passage à extension_warning pour {game_name}")
config.history.pop()
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
# Lancer le téléchargement dans une tâche asynchrone
task_id = str(pygame.time.get_ticks())
config.download_tasks[task_id] = (
asyncio.create_task(download_rom(url, platform, game_name, zip_ok)),
url, game_name, platform
)
config.menu_state = "history" # Passer à l'historique
config.needs_redraw = True
logger.debug(f"Téléchargement démarré pour {game_name}, passage à l'historique")
elif action == "redownload" and config.menu_state == "history" and config.history:
entry = config.history[config.current_history_item]
platform = entry["platform"]
@@ -654,17 +678,32 @@ async def main():
logger.error("Clé API 1fichier absente")
config.pending_download = None
continue
is_supported, message, is_zip_non_supported = check_extension_before_download(url, platform, game_name)
if not is_supported:
config.pending_download = (url, platform, game_name, is_zip_non_supported)
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
pending = check_extension_before_download(url, platform, game_name)
if not pending:
config.menu_state = "error"
config.error_message = _("error_invalid_download_data") if _ else "Invalid download data"
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour lien 1fichier, passage à extension_warning pour {game_name}")
logger.error(f"check_extension_before_download a échoué pour {game_name}")
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
success, message = download_from_1fichier(url, platform, game_name, is_zip_non_supported)
from utils import is_extension_supported, load_extensions_json, sanitize_filename
from rgsx_settings import get_allow_unknown_extensions
is_supported = is_extension_supported(sanitize_filename(game_name), platform, load_extensions_json())
zip_ok = bool(pending[3])
allow_unknown = False
try:
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.pending_download = pending
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour lien 1fichier, passage à extension_warning pour {game_name}")
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
success, message = download_from_1fichier(url, platform, game_name, zip_ok)
# Ancien popup download_result supprimé : retour direct à l'historique
config.download_result_message = message
config.download_result_error = not success
@@ -674,17 +713,32 @@ async def main():
config.needs_redraw = True
logger.debug(f"Retéléchargement 1fichier terminé pour {game_name}, succès={success}, message={message}, retour direct history")
else:
is_supported, message, is_zip_non_supported = check_extension_before_download(url, platform, game_name)
if not is_supported:
config.pending_download = (url, platform, game_name, is_zip_non_supported)
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
pending = check_extension_before_download(url, platform, game_name)
if not pending:
config.menu_state = "error"
config.error_message = _("error_invalid_download_data") if _ else "Invalid download data"
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour retéléchargement, passage à extension_warning pour {game_name}")
logger.error(f"check_extension_before_download a échoué pour {game_name}")
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
success, message = download_rom(url, platform, game_name, is_zip_non_supported)
from utils import is_extension_supported, load_extensions_json, sanitize_filename
from rgsx_settings import get_allow_unknown_extensions
is_supported = is_extension_supported(sanitize_filename(game_name), platform, load_extensions_json())
zip_ok = bool(pending[3])
allow_unknown = False
try:
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.pending_download = pending
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour retéléchargement, passage à extension_warning pour {game_name}")
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
success, message = download_rom(url, platform, game_name, zip_ok)
config.download_result_message = message
config.download_result_error = not success
config.download_progress.clear()

View File

@@ -13,7 +13,7 @@ except Exception:
pygame = None # type: ignore
# Version actuelle de l'application
app_version = "2.2.0.3"
app_version = "2.2.0.5"
def get_operating_system():
"""Renvoie le nom du système d'exploitation."""

View File

@@ -562,7 +562,13 @@ def handle_controls(event, sources, joystick, screen):
load_extensions_json()
)
zip_ok = bool(config.pending_download[3]) # True only if archive and system known
if not is_supported and not zip_ok:
allow_unknown = False
try:
from rgsx_settings import get_allow_unknown_extensions
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
# Stocker comme pending sans dupliquer l'entrée
config.batch_pending_game = (url, platform, game_name, config.pending_download[3])
config.previous_menu_state = config.menu_state
@@ -636,7 +642,13 @@ def handle_controls(event, sources, joystick, screen):
load_extensions_json()
)
zip_ok = bool(config.pending_download[3])
if not is_supported and not zip_ok:
allow_unknown = False
try:
from rgsx_settings import get_allow_unknown_extensions
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.previous_menu_state = config.menu_state
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
@@ -669,7 +681,13 @@ def handle_controls(event, sources, joystick, screen):
load_extensions_json()
)
zip_ok = bool(config.pending_download[3])
if not is_supported and not zip_ok:
allow_unknown = False
try:
from rgsx_settings import get_allow_unknown_extensions
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.previous_menu_state = config.menu_state
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
@@ -688,7 +706,10 @@ def handle_controls(event, sources, joystick, screen):
action = "download"
else:
config.menu_state = "error"
config.error_message = "Extension non supportée ou erreur de téléchargement"
try:
config.error_message = _("error_invalid_download_data")
except Exception:
config.error_message = "Invalid download data"
config.pending_download = None
config.needs_redraw = True
logger.error(f"config.pending_download est None pour {game_name}")
@@ -759,7 +780,13 @@ def handle_controls(event, sources, joystick, screen):
continue
is_supported = is_extension_supported(sanitize_filename(game_name), platform, load_extensions_json())
zip_ok = bool(config.pending_download[3])
if not is_supported and not zip_ok:
allow_unknown = False
try:
from rgsx_settings import get_allow_unknown_extensions
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.batch_pending_game = (url, platform, game_name, config.pending_download[3])
config.previous_menu_state = config.menu_state
config.menu_state = "extension_warning"
@@ -818,7 +845,13 @@ def handle_controls(event, sources, joystick, screen):
continue
is_supported = is_extension_supported(sanitize_filename(game_name), platform, load_extensions_json())
zip_ok = bool(config.pending_download[3])
if not is_supported and not zip_ok:
allow_unknown = False
try:
from rgsx_settings import get_allow_unknown_extensions
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.batch_pending_game = (url, platform, game_name, config.pending_download[3])
config.previous_menu_state = config.menu_state
config.menu_state = "extension_warning"
@@ -951,7 +984,10 @@ def handle_controls(event, sources, joystick, screen):
action = "redownload"
else:
config.menu_state = "error"
config.error_message = "Extension non supportée ou erreur de retéléchargement"
try:
config.error_message = _("error_invalid_download_data")
except Exception:
config.error_message = "Invalid download data"
config.pending_download = None
config.needs_redraw = True
logger.error(f"config.pending_download est None pour {game_name}")
@@ -1163,10 +1199,10 @@ def handle_controls(event, sources, joystick, screen):
elif config.menu_state == "display_menu":
sel = getattr(config, 'display_menu_selection', 0)
if is_input_matched(event, "up"):
config.display_menu_selection = (sel - 1) % 4
config.display_menu_selection = (sel - 1) % 5
config.needs_redraw = True
elif is_input_matched(event, "down"):
config.display_menu_selection = (sel + 1) % 4
config.display_menu_selection = (sel + 1) % 5
config.needs_redraw = True
elif is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm"):
sel = getattr(config, 'display_menu_selection', 0)
@@ -1229,8 +1265,19 @@ def handle_controls(event, sources, joystick, screen):
config.needs_redraw = True
except Exception as e:
logger.error(f"Erreur toggle unsupported: {e}")
# 3: open filter platforms menu
elif sel == 3 and (is_input_matched(event, "confirm") or is_input_matched(event, "right")):
# 3: toggle allow unknown extensions
elif sel == 3 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
try:
from rgsx_settings import get_allow_unknown_extensions, set_allow_unknown_extensions
current = get_allow_unknown_extensions()
new_val = set_allow_unknown_extensions(not current)
config.popup_message = _("menu_allow_unknown_ext_enabled") if new_val else _("menu_allow_unknown_ext_disabled")
config.popup_timer = 3000
config.needs_redraw = True
except Exception as e:
logger.error(f"Erreur toggle allow_unknown_extensions: {e}")
# 4: open filter platforms menu
elif sel == 4 and (is_input_matched(event, "confirm") or is_input_matched(event, "right")):
# Remember return target so the filter menu can go back to display
config.filter_return_to = "display_menu"
config.menu_state = "filter_platforms"

View File

@@ -1130,7 +1130,13 @@ def draw_extension_warning(screen):
if is_zip:
message = _("extension_warning_zip").format(game_name)
else:
message = _("extension_warning_unsupported").format(game_name)
# Ajout d'un indice pour activer le téléchargement des extensions inconnues
try:
hint = _("extension_warning_enable_unknown_hint")
except Exception:
hint = ""
core = _("extension_warning_unsupported").format(game_name)
message = core if not hint else f"{core}{hint}"
max_width = config.screen_width - 80
lines = wrap_text(message, config.font, max_width)
@@ -1269,14 +1275,16 @@ def draw_display_menu(screen):
# États actuels
layout_str = f"{getattr(config, 'GRID_COLS', 3)}x{getattr(config, 'GRID_ROWS', 4)}"
font_scale = config.accessibility_settings.get("font_scale", 1.0)
from rgsx_settings import get_show_unsupported_platforms
from rgsx_settings import get_show_unsupported_platforms, get_allow_unknown_extensions
show_unsupported = get_show_unsupported_platforms()
allow_unknown = get_allow_unknown_extensions()
# Libellés
options = [
f"{_('display_layout')}: {layout_str}",
_("accessibility_font_size").format(f"{font_scale:.1f}"),
_("menu_show_unsupported_on") if show_unsupported else _("menu_show_unsupported_off"),
_("menu_allow_unknown_ext_on") if allow_unknown else _("menu_allow_unknown_ext_off"),
_("menu_filter_platforms"),
]

View File

@@ -58,6 +58,7 @@
"extension_warning_zip": "Die Datei '{0}' ist ein Archiv und Batocera unterstützt keine Archive für dieses System. Die automatische Extraktion der Datei erfolgt nach dem Download, fortfahren?",
"extension_warning_unsupported": "Die Dateierweiterung für '{0}' wird laut der Konfiguration es_systems.cfg von Batocera nicht unterstützt. Möchtest du fortfahren?",
"extension_warning_enable_unknown_hint": "\nUm diese Meldung auszublenden: \"Warnung bei unbekannter Erweiterung ausblenden\" in Pausenmenü > Anzeige aktivieren",
"confirm_exit": "Anwendung beenden?",
"confirm_clear_history": "Verlauf löschen?",
@@ -95,6 +96,10 @@
"menu_show_unsupported_off": "Nicht unterstützte Systeme anzeigen: Nein",
"menu_show_unsupported_enabled": "Sichtbarkeit nicht unterstützter Systeme aktiviert",
"menu_show_unsupported_disabled": "Sichtbarkeit nicht unterstützter Systeme deaktiviert",
"menu_allow_unknown_ext_on": "Warnung bei unbekannter Erweiterung ausblenden: Ja",
"menu_allow_unknown_ext_off": "Warnung bei unbekannter Erweiterung ausblenden: Nein",
"menu_allow_unknown_ext_enabled": "Ausblenden der Warnung bei unbekannter Erweiterung aktiviert",
"menu_allow_unknown_ext_disabled": "Ausblenden der Warnung bei unbekannter Erweiterung deaktiviert",
"menu_quit": "Beenden",
"button_yes": "Ja",

View File

@@ -58,6 +58,7 @@
"extension_warning_zip": "The file '{0}' is an archive and Batocera does not support archives for this system. Automatic extraction will occur after download, continue?",
"extension_warning_unsupported": "The file extension for '{0}' is not supported by Batocera according to the es_systems.cfg configuration. Do you want to continue?",
"extension_warning_enable_unknown_hint": "\nTo hide this message: enable \"Hide unknown extension warning\" in Pause Menu > Display",
"confirm_exit": "Exit application?",
"confirm_clear_history": "Clear history?",
@@ -95,6 +96,10 @@
"menu_show_unsupported_off": "Show unsupported systems: No",
"menu_show_unsupported_enabled": "Unsupported systems visibility enabled",
"menu_show_unsupported_disabled": "Unsupported systems visibility disabled",
"menu_allow_unknown_ext_on": "Hide unknown extension warning: Yes",
"menu_allow_unknown_ext_off": "Hide unknown extension warning: No",
"menu_allow_unknown_ext_enabled": "Hide unknown extension warning enabled",
"menu_allow_unknown_ext_disabled": "Hide unknown extension warning disabled",
"menu_quit": "Quit",
"button_yes": "Yes",

View File

@@ -59,6 +59,7 @@
"extension_warning_zip": "El archivo '{0}' es un archivo comprimido y Batocera no soporta archivos comprimidos para este sistema. La extracción automática del archivo se realizará después de la descarga, ¿continuar?",
"extension_warning_unsupported": "La extensión del archivo '{0}' no está soportada por Batocera según la configuración es_systems.cfg. ¿Deseas continuar?",
"extension_warning_enable_unknown_hint": "\nPara no mostrar este mensaje: activa \"Ocultar aviso de extensión desconocida\" en Menú de pausa > Pantalla",
"confirm_exit": "¿Salir de la aplicación?",
"confirm_clear_history": "¿Vaciar el historial?",
@@ -96,6 +97,10 @@
"menu_show_unsupported_off": "Mostrar sistemas no soportados: No",
"menu_show_unsupported_enabled": "Visibilidad de sistemas no soportados activada",
"menu_show_unsupported_disabled": "Visibilidad de sistemas no soportados desactivada",
"menu_allow_unknown_ext_on": "Ocultar aviso de extensión desconocida: Sí",
"menu_allow_unknown_ext_off": "Ocultar aviso de extensión desconocida: No",
"menu_allow_unknown_ext_enabled": "Aviso de extensión desconocida oculto (activado)",
"menu_allow_unknown_ext_disabled": "Aviso de extensión desconocida visible (desactivado)",
"menu_quit": "Salir",
"button_yes": "Sí",

View File

@@ -55,6 +55,7 @@
"extension_warning_zip": "Le fichier '{0}' est une archive et Batocera ne prend pas en charge les archives pour ce système. L'extraction automatique du fichier aura lieu après le téléchargement, continuer ?",
"extension_warning_unsupported": "L'extension du fichier '{0}' n'est pas supportée par Batocera d'après la configuration es_systems.cfg. Voulez-vous continuer ?",
"extension_warning_enable_unknown_hint": "\nPour ne plus afficher ce messager : Activer l'option \"Masquer avertissement\" dans le Menu Pause>Display",
"confirm_exit": "Quitter l'application ?",
"confirm_clear_history": "Vider l'historique ?",
@@ -93,6 +94,10 @@
"menu_show_unsupported_off": "Afficher systèmes non supportés : Non",
"menu_show_unsupported_enabled": "Affichage systèmes non supportés activé",
"menu_show_unsupported_disabled": "Affichage systèmes non supportés désactivé",
"menu_allow_unknown_ext_on": "Masquer avertissement extension inconnue : Oui",
"menu_allow_unknown_ext_off": "Masquer avertissement extension inconnue : Non",
"menu_allow_unknown_ext_enabled": "Masquer avertissement extension inconnue activé",
"menu_allow_unknown_ext_disabled": "Masquer avertissement extension inconnue désactivé",
"button_yes": "Oui",
"button_no": "Non",

View File

@@ -0,0 +1,220 @@
{
"controls_mapping_title": "Configurazione dei controlli",
"controls_mapping_instruction": "Tieni premuto per 3s per configurare:",
"controls_mapping_waiting": "In attesa di un tasto o pulsante...",
"controls_mapping_press": "Premi un tasto o un pulsante",
"welcome_message": "Benvenuto in RGSX",
"disclaimer_line1": "È pericoloso andare da soli, prendi tutto ciò che ti serve!",
"disclaimer_line2": "Ma scarica solo giochi",
"disclaimer_line3": "che possiedi già!",
"disclaimer_line4": "RGSX non è responsabile dei contenuti scaricati,",
"disclaimer_line5": "e non ospita ROM.",
"loading_test_connection": "Verifica connessione...",
"loading_download_data": "Download cartella Dati iniziale...",
"loading_progress": "Progresso: {0}%",
"loading_check_updates": "Verifica aggiornamenti... Attendere...",
"error_check_updates_failed": "Impossibile verificare gli aggiornamenti.",
"loading_downloading_games_images": "Download giochi e immagini...",
"loading_extracting_data": "Estrazione cartella Dati iniziale...",
"loading_load_systems": "Caricamento sistemi...",
"error_extract_data_failed": "Errore nel download o nell'estrazione della cartella Dati iniziale.",
"error_sources_load_failed": "Errore nel caricamento delle sorgenti. Apri il menu e seleziona Aggiorna cache giochi",
"error_no_internet": "Nessuna connessione Internet. Controlla la rete.",
"error_controls_mapping": "Impossibile mappare i controlli",
"error_api_key": "Inserisci la tua API key (solo premium) nel file {0}",
"error_api_key_extended": "Inserisci la tua API key (solo premium) nel file /userdata/saves/ports/rgsx/1fichierAPI.txt aprendolo in un editor e incollando la chiave",
"error_invalid_download_data": "Dati di download non validi",
"error_delete_sources": "Errore nell'eliminazione del file systems_list.json o delle cartelle",
"error_extension": "Estensione non supportata o errore di download",
"error_no_download": "Nessun download in sospeso.",
"platform_no_platform": "Nessuna piattaforma",
"platform_page": "Pagina {0}/{1}",
"game_no_games": "Nessun gioco disponibile",
"game_count": "{0} ({1} giochi)",
"game_filter": "Filtro attivo: {0}",
"game_search": "Filtro: {0}",
"game_header_name": "Nome",
"game_header_size": "Dimensione",
"history_title": "Download ({0})",
"history_empty": "Nessun download nella cronologia",
"history_column_system": "Sistema",
"history_column_game": "Nome del gioco",
"history_column_size": "Dimensione",
"history_column_status": "Stato",
"history_status_downloading": "Download: {0}%",
"history_status_extracting": "Estrazione: {0}%",
"history_status_completed": "Completato",
"history_status_error": "Errore: {0}",
"history_status_canceled": "Annullato",
"download_status": "{0}: {1}",
"download_progress": "{0}% {1} MB / {2} MB",
"download_canceled": "Download annullato dall'utente.",
"extension_warning_zip": "Il file '{0}' è un archivio e Batocera non supporta archivi per questo sistema. L'estrazione automatica avverrà dopo il download, continuare?",
"extension_warning_unsupported": "L'estensione del file '{0}' non è supportata da Batocera secondo la configurazione di es_systems.cfg. Vuoi continuare?",
"extension_warning_enable_unknown_hint": "\nPer non visualizzare questo messaggio: abilita \"Nascondi avviso estensione sconosciuta\" in Menu Pausa > Schermo",
"confirm_exit": "Uscire dall'applicazione?",
"confirm_clear_history": "Cancellare la cronologia?",
"confirm_redownload_cache": "Aggiornare l'elenco dei giochi?",
"popup_redownload_success": "Cache pulita, riavvia l'applicazione",
"popup_no_cache": "Nessuna cache trovata.\nRiavvia l'applicazione per caricare i giochi.",
"popup_countdown": "Questo messaggio si chiuderà tra {0} secondo{1}",
"language_select_title": "Selezione lingua",
"language_select_instruction": "Usa le frecce per navigare e Invio per selezionare",
"language_changed": "Lingua cambiata in {0}",
"menu_controls": "Controlli",
"menu_remap_controls": "Rimappa controlli",
"menu_history": "Cronologia",
"menu_language": "Lingua",
"menu_accessibility": "Accessibilità",
"menu_display": "Schermo",
"display_layout": "Layout schermo",
"menu_redownload_cache": "Aggiorna elenco giochi",
"menu_music_toggle": "Attiva/Disattiva musica",
"menu_music_enabled": "Musica attivata: {0}",
"menu_music_disabled": "Musica disattivata",
"menu_restart": "Riavvia",
"menu_filter_platforms": "Filtra sistemi",
"filter_platforms_title": "Visibilità sistemi",
"filter_all": "Mostra tutto",
"filter_none": "Nascondi tutto",
"filter_apply": "Applica",
"filter_back": "Indietro",
"filter_platforms_info": "Visibili: {0} | Nascosti: {1} / Totale: {2}",
"filter_unsaved_warning": "Modifiche non salvate",
"menu_show_unsupported_on": "Mostra sistemi non supportati: Sì",
"menu_show_unsupported_off": "Mostra sistemi non supportati: No",
"menu_show_unsupported_enabled": "Visibilità sistemi non supportati abilitata",
"menu_show_unsupported_disabled": "Visibilità sistemi non supportati disabilitata",
"menu_allow_unknown_ext_on": "Nascondi avviso estensione sconosciuta: Sì",
"menu_allow_unknown_ext_off": "Nascondi avviso estensione sconosciuta: No",
"menu_allow_unknown_ext_enabled": "Nascondi avviso estensione sconosciuta abilitato",
"menu_allow_unknown_ext_disabled": "Nascondi avviso estensione sconosciuta disabilitato",
"menu_quit": "Esci",
"button_yes": "Sì",
"button_no": "No",
"button_OK": "OK",
"popup_restarting": "Riavvio...",
"controls_hold_message": "Tieni premuto per 3s per: '{0}'",
"controls_skip_message": "Premi Esc per ignorare (solo PC)",
"controls_waiting": "In attesa...",
"controls_hold": "Tieni premuto 3s",
"controls_action_confirm": "Conferma",
"controls_action_cancel": "Annulla",
"controls_action_up": "Su",
"controls_action_down": "Giù",
"controls_action_left": "Sinistra",
"controls_action_right": "Destra",
"controls_action_page_up": "Pagina precedente",
"controls_action_page_down": "Pagina successiva",
"controls_action_clear_history": "Selezione multipla / Cancella cronologia",
"controls_action_history": "Cronologia",
"controls_action_filter": "Filtro",
"controls_action_delete": "Elimina",
"controls_action_space": "Spazio",
"controls_action_start": "Aiuto / Impostazioni",
"controls_desc_confirm": "Conferma (es. A, Invio)",
"controls_desc_cancel": "Annulla/Indietro (es. B, Backspace)",
"controls_desc_up": "Naviga in alto",
"controls_desc_down": "Naviga in basso",
"controls_desc_left": "Naviga a sinistra",
"controls_desc_right": "Naviga a destra",
"controls_desc_page_up": "Pagina precedente/Scorrimento veloce su (es. PagSu, LB)",
"controls_desc_page_down": "Pagina successiva/Scorrimento veloce giù (es. PagGiù, RB)",
"controls_desc_clear_history": "Selezione multipla (lista giochi) / Cancella cronologia (menu cronologia) (es. X)",
"controls_desc_history": "Apri cronologia (es. H, Y)",
"controls_desc_filter": "Apri filtro (es. F, Select)",
"controls_desc_delete": "Elimina carattere (es. LT, Canc)",
"controls_desc_space": "Aggiungi spazio (es. RT, Spazio)",
"controls_desc_start": "Apri menu pausa (es. Start, AltGr)",
"action_retry": "Riprova",
"action_quit": "Esci",
"action_select": "Seleziona",
"action_history": "Cronologia",
"action_download": "Scarica",
"action_filter": "Filtro",
"action_cancel": "Annulla",
"action_back": "Indietro",
"action_navigate": "Naviga",
"action_page": "Pagina",
"action_cancel_download": "Annulla download",
"action_background": "Sfondo",
"action_confirm": "Conferma",
"action_redownload": "Scarica di nuovo",
"action_clear_history": "Cancella cronologia",
"network_checking_updates": "Verifica aggiornamenti...",
"network_update_available": "Aggiornamento disponibile: {0}",
"network_extracting_update": "Estrazione aggiornamento...",
"network_update_completed": "Aggiornamento completato",
"network_update_success": "Aggiornamento a {0} completato con successo. Riavvia l'applicazione.",
"network_update_success_message": "Aggiornamento completato con successo",
"network_no_update_available": "Nessun aggiornamento disponibile",
"network_update_error": "Errore durante l'aggiornamento: {0}",
"network_check_update_error": "Errore durante il controllo degli aggiornamenti: {0}",
"network_extraction_failed": "Impossibile estrarre l'aggiornamento: {0}",
"network_extraction_partial": "Estrazione riuscita, ma alcuni file sono stati ignorati a causa di errori: {0}",
"network_extraction_success": "Estrazione riuscita",
"network_download_extract_ok": "Download ed estrazione riusciti di {0}",
"network_zip_extraction_error": "Errore durante l'estrazione dello ZIP {0}: {1}",
"network_permission_error": "Nessun permesso di scrittura in {0}",
"network_file_not_found": "Il file {0} non esiste",
"network_cannot_get_filename": "Impossibile ottenere il nome del file",
"network_cannot_get_download_url": "Impossibile ottenere l'URL di download",
"network_download_failed": "Download fallito dopo {0} tentativi",
"network_api_error": "Errore richiesta API, la chiave potrebbe essere errata: {0}",
"network_download_error": "Errore download {0}: {1}",
"network_download_ok": "Download OK: {0}",
"utils_extracted": "Estratto: {0}",
"utils_corrupt_zip": "Archivio ZIP corrotto: {0}",
"utils_permission_denied": "Permesso negato durante l'estrazione: {0}",
"utils_extraction_failed": "Estrazione fallita: {0}",
"utils_unrar_unavailable": "Comando unrar non disponibile",
"utils_rar_list_failed": "Impossibile elencare i file RAR: {0}",
"utils_xdvdfs_unavailable": "Strumento xdvdfs non disponibile (mancante o permesso negato)",
"download_initializing": "Inizializzazione...",
"accessibility_font_size": "Dimensione carattere: {0}",
"confirm_cancel_download": "Annullare il download corrente?",
"controls_help_title": "Guida ai controlli",
"controls_category_navigation": "Navigazione",
"controls_category_main_actions": "Azioni principali",
"controls_category_downloads": "Download",
"controls_category_search": "Ricerca",
"controls_navigation": "Navigazione",
"controls_pages": "Pagine",
"controls_confirm_select": "Conferma/Seleziona",
"controls_cancel_back": "Annulla/Indietro",
"controls_history": "Cronologia",
"controls_clear_history": "Selezione multipla / Cronologia",
"controls_filter_search": "Filtro/Ricerca",
"menu_symlink_option": "Opzione Symlink",
"symlink_option_enabled": "Opzione symlink abilitata",
"symlink_option_disabled": "Opzione symlink disabilitata",
"symlink_settings_saved_successfully": "Impostazioni symlink salvate con successo",
"symlink_settings_save_error": "Errore nel salvataggio delle impostazioni symlink",
"menu_games_source_prefix": "Sorgente giochi",
"games_source_rgsx": "RGSX",
"sources_mode_rgsx_select_info": "RGSX: aggiorna l'elenco dei giochi",
"games_source_custom": "Personalizzato",
"sources_mode_custom_select_info": "Modalità personalizzata: imposta l'URL in {0} poi aggiorna l'elenco giochi",
"sources_mode_custom_missing_url": "Nessun URL personalizzato impostato (modifica {0})",
"sources_mode_custom_download_error": "Download sorgente personalizzata fallito"
}

View File

@@ -58,6 +58,7 @@
"extension_warning_zip": "O arquivo '{0}' é um arquivo compactado e o Batocera não suporta arquivos compactados para este sistema. A extração automática ocorrerá após o download, continuar?",
"extension_warning_unsupported": "A extensão do arquivo '{0}' não é suportada pelo Batocera segundo a configuração es_systems.cfg. Deseja continuar?",
"extension_warning_enable_unknown_hint": "\nPara não ver esta mensagem: ative \"Ocultar aviso de extensão desconhecida\" em Menu de Pausa > Exibição",
"confirm_exit": "Sair da aplicação?",
"confirm_clear_history": "Limpar histórico?",
@@ -95,6 +96,10 @@
"menu_show_unsupported_off": "Mostrar sistemas não suportados: Não",
"menu_show_unsupported_enabled": "Visibilidade de sistemas não suportados ativada",
"menu_show_unsupported_disabled": "Visibilidade de sistemas não suportados desativada",
"menu_allow_unknown_ext_on": "Ocultar aviso de extensão desconhecida: Sim",
"menu_allow_unknown_ext_off": "Ocultar aviso de extensão desconhecida: Não",
"menu_allow_unknown_ext_enabled": "Aviso de extensão desconhecida oculto (ativado)",
"menu_allow_unknown_ext_disabled": "Aviso de extensão desconhecida visível (desativado)",
"menu_quit": "Sair",
"button_yes": "Sim",

View File

@@ -50,7 +50,7 @@ def load_rgsx_settings():
from config import RGSX_SETTINGS_PATH
default_settings = {
"language": "fr",
"language": "en",
"music_enabled": True,
"accessibility": {
"font_scale": 1.0
@@ -66,7 +66,8 @@ def load_rgsx_settings():
"mode": "rgsx",
"custom_url": ""
},
"show_unsupported_platforms": False
"show_unsupported_platforms": False,
"allow_unknown_extensions": False
}
try:
@@ -211,6 +212,22 @@ def set_show_unsupported_platforms(enabled: bool):
save_rgsx_settings(settings)
return settings["show_unsupported_platforms"]
# ----------------------- Unknown extensions toggle ----------------------- #
def get_allow_unknown_extensions(settings=None) -> bool:
"""Retourne True si le téléchargement des extensions inconnues est autorisé."""
if settings is None:
settings = load_rgsx_settings()
return bool(settings.get("allow_unknown_extensions", False))
def set_allow_unknown_extensions(enabled: bool) -> bool:
"""Active/désactive le téléchargement des extensions inconnues et sauvegarde."""
settings = load_rgsx_settings()
settings["allow_unknown_extensions"] = bool(enabled)
save_rgsx_settings(settings)
return settings["allow_unknown_extensions"]
# ----------------------- Display layout (grid) ----------------------- #
def get_display_grid(settings=None):

View File

@@ -247,9 +247,11 @@ def check_extension_before_download(url, platform, game_name):
try:
sanitized_name = sanitize_filename(game_name)
extensions_data = load_extensions_json()
# Si le cache des extensions est vide/introuvable, ne bloquez pas: traitez comme "inconnu"
# afin d'afficher l'avertissement d'extension au lieu d'une erreur fatale.
if not extensions_data:
logger.error(f"Fichier {config.JSON_EXTENSIONS} vide ou introuvable")
return None
logger.warning(f"Fichier {config.JSON_EXTENSIONS} vide ou introuvable; poursuite avec extensions inconnues")
extensions_data = []
is_supported = is_extension_supported(sanitized_name, platform, extensions_data)
extension = os.path.splitext(sanitized_name)[1].lower()
@@ -271,10 +273,23 @@ def check_extension_before_download(url, platform, game_name):
if is_supported:
logger.debug(f"L'extension de {sanitized_name} est supportée pour {platform}")
return (url, platform, game_name, False)
elif is_archive and system_known:
logger.debug(f"Archive {extension.upper()} détectée pour {sanitized_name}, extraction automatique prévue")
elif is_archive:
# Même si le système n'est pas connu ou que l'extension n'est pas listée,
# on force l'extraction des archives (ZIP/RAR) à la fin du téléchargement
# puis suppression du fichier.
logger.debug(f"Archive {extension.upper()} détectée pour {sanitized_name}, extraction automatique prévue (extension non listée)")
return (url, platform, game_name, True)
else:
# Autoriser si l'utilisateur a choisi d'autoriser les extensions inconnues
allow_unknown = False
try:
from rgsx_settings import get_allow_unknown_extensions
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if allow_unknown:
logger.debug(f"Extension non supportée ({extension}) mais autorisée par l'utilisateur pour {sanitized_name}")
return (url, platform, game_name, False)
logger.debug(f"Extension non supportée ({extension}) pour {sanitized_name}, avertissement affiché")
return (url, platform, game_name, False)
except Exception as e: