v2.2.0.8 - test feat: add AllDebrid API support as fallback for 1Fichier downloads and update documentation

This commit is contained in:
skymike03
2025-09-11 02:41:43 +02:00
parent ea565f7c46
commit 74ef8b4bdf
13 changed files with 240 additions and 95 deletions

View File

@@ -570,18 +570,27 @@ async def main():
config.current_history_item = len(config.history) - 1 # Sélectionner l'entrée en cours
if is_1fichier_url(url):
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
from utils import load_api_key_alldebrid
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.previous_menu_state = config.menu_state
config.menu_state = "error"
config.error_message = (
f"Attention il faut renseigner sa clé API (premium only) dans le fichier {os.path.join(config.SAVE_FOLDER, '1fichierAPI.txt')}"
)
try:
both_paths = f"{os.path.join(config.SAVE_FOLDER,'1FichierAPI.txt')} or {os.path.join(config.SAVE_FOLDER,'AllDebridAPI.txt')}"
config.error_message = _("error_api_key").format(both_paths)
except Exception:
config.error_message = "Please enter API key (1fichier or AllDebrid)"
# Mettre à jour l'entrée temporaire avec l'erreur
config.history[-1]["status"] = "Erreur"
config.history[-1]["progress"] = 0
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
config.needs_redraw = True
logger.error("Clé API 1fichier absente")
logger.error("Clé API 1fichier et AllDebrid absentes")
config.pending_download = None
continue
pending = check_extension_before_download(url, platform_name, game_name)
@@ -670,13 +679,22 @@ async def main():
logger.debug(f"Vérification pour retéléchargement de {game_name}, URL: {url}")
if is_1fichier_url(url):
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
from utils import load_api_key_alldebrid
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.previous_menu_state = config.menu_state
config.menu_state = "error"
config.error_message = (
f"Attention il faut renseigner sa clé API (premium only) dans le fichier {os.path.join(config.SAVE_FOLDER, '1fichierAPI.txt')}"
)
try:
both_paths = f"{os.path.join(config.SAVE_FOLDER,'1FichierAPI.txt')} or {os.path.join(config.SAVE_FOLDER,'AllDebridAPI.txt')}"
config.error_message = _("error_api_key").format(both_paths)
except Exception:
config.error_message = "Please enter API key (1fichier or AllDebrid)"
config.needs_redraw = True
logger.error("Clé API 1fichier absente")
logger.error("Clé API 1fichier et AllDebrid absentes")
config.pending_download = None
continue
pending = check_extension_before_download(url, platform_name, game_name)

View File

@@ -104,7 +104,7 @@ JSON_EXTENSIONS = os.path.join(SAVE_FOLDER, "rom_extensions.json")
PRECONF_CONTROLS_PATH = os.path.join(APP_FOLDER, "assets", "controls")
CONTROLS_CONFIG_PATH = os.path.join(SAVE_FOLDER, "controls.json")
HISTORY_PATH = os.path.join(SAVE_FOLDER, "history.json")
API_KEY_1FICHIER = os.path.join(SAVE_FOLDER, "1fichierAPI.txt")
API_KEY_1FICHIER = os.path.join(SAVE_FOLDER, "1FichierAPI.txt")
RGSX_SETTINGS_PATH = os.path.join(SAVE_FOLDER, "rgsx_settings.json")
# URL

View File

@@ -14,7 +14,7 @@ from network import download_rom, download_from_1fichier, is_1fichier_url, reque
from utils import (
load_games, check_extension_before_download, is_extension_supported,
load_extensions_json, play_random_music, sanitize_filename,
load_api_key_1fichier, save_music_config
load_api_key_1fichier, load_api_key_alldebrid, save_music_config
)
from history import load_history, clear_history, add_to_history, save_history
import logging
@@ -584,8 +584,14 @@ def handle_controls(event, sources, joystick, screen):
if is_1fichier_url(url):
config.API_KEY_1FICHIER = load_api_key_1fichier()
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.history[-1]["status"] = "Erreur"
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
continue
task = asyncio.create_task(download_from_1fichier(url, platform, game_name, config.pending_download[3], task_id))
@@ -620,19 +626,26 @@ def handle_controls(event, sources, joystick, screen):
if is_1fichier_url(url):
config.API_KEY_1FICHIER = load_api_key_1fichier()
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.previous_menu_state = config.menu_state
config.menu_state = "error"
try:
config.error_message = _("error_api_key_extended")
both_paths = f"{os.path.join(config.SAVE_FOLDER,'1FichierAPI.txt')} or {os.path.join(config.SAVE_FOLDER,'AllDebridAPI.txt')}"
config.error_message = _("error_api_key").format(both_paths)
except Exception as e:
logger.error(f"Erreur lors de la traduction de error_api_key_extended: {str(e)}")
config.error_message = "Missing 1fichier API key" # Message de secours
logger.error(f"Erreur lors de la traduction de error_api_key: {str(e)}")
config.error_message = "Please enter API key (1fichier or AllDebrid)"
config.history[-1]["status"] = "Erreur"
config.history[-1]["progress"] = 0
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
config.needs_redraw = True
logger.error("Clé API 1fichier absente, téléchargement impossible.")
logger.error("Clé API 1fichier et AllDebrid absentes, téléchargement impossible.")
config.pending_download = None
return action
config.pending_download = check_extension_before_download(url, platform, game_name)
@@ -734,17 +747,25 @@ def handle_controls(event, sources, joystick, screen):
config.current_history_item = len(config.history) - 1
if is_1fichier_url(url):
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.previous_menu_state = config.menu_state
config.menu_state = "error"
config.error_message = _(
"error_api_key"
).format(os.path.join(config.SAVE_FOLDER,"1fichierAPI.txt"))
try:
both_paths = f"{os.path.join(config.SAVE_FOLDER,'1FichierAPI.txt')} or {os.path.join(config.SAVE_FOLDER,'AllDebridAPI.txt')}"
config.error_message = _("error_api_key").format(both_paths)
except Exception:
config.error_message = "Please enter API key (1fichier or AllDebrid)"
config.history[-1]["status"] = "Erreur"
config.history[-1]["progress"] = 0
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
config.needs_redraw = True
logger.error("Clé API 1fichier absente, téléchargement impossible.")
logger.error("Clé API 1fichier et AllDebrid absentes, téléchargement impossible.")
config.pending_download = None
return action
task_id = str(pygame.time.get_ticks())
@@ -800,8 +821,14 @@ def handle_controls(event, sources, joystick, screen):
if is_1fichier_url(url):
config.API_KEY_1FICHIER = load_api_key_1fichier()
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.history[-1]["status"] = "Erreur"
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
continue
task = asyncio.create_task(download_from_1fichier(url, platform, game_name, config.pending_download[3], task_id))
@@ -865,8 +892,14 @@ def handle_controls(event, sources, joystick, screen):
if is_1fichier_url(url):
config.API_KEY_1FICHIER = load_api_key_1fichier()
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.history[-1]["status"] = "Erreur"
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
continue
task = asyncio.create_task(download_from_1fichier(url, platform, game_name, config.pending_download[3], task_id))
@@ -960,17 +993,27 @@ def handle_controls(event, sources, joystick, screen):
task_id = str(pygame.time.get_ticks())
if is_1fichier_url(url):
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.previous_menu_state = config.menu_state
config.menu_state = "error"
logger.warning("clé api absente dans os.path.join(config.SAVE_FOLDER, '1fichierAPI.txt')\n")
config.error_message = _("error_api_key").format(os.path.join(config.SAVE_FOLDER, "1fichierAPI.txt"))
logger.warning("clé api absente pour 1fichier et AllDebrid")
try:
both_paths = f"{os.path.join(config.SAVE_FOLDER,'1FichierAPI.txt')} or {os.path.join(config.SAVE_FOLDER,'AllDebridAPI.txt')}"
config.error_message = _("error_api_key").format(both_paths)
except Exception:
config.error_message = "Please enter API key (1fichier or AllDebrid)"
config.history[-1]["status"] = "Erreur"
config.history[-1]["progress"] = 0
config.history[-1]["message"] = "Erreur API : Clé API 1fichier absente"
config.history[-1]["message"] = "API NOT FOUND"
save_history(config.history)
config.needs_redraw = True
logger.error("Clé API 1fichier absente, retéléchargement impossible.")
logger.error("Clé API 1fichier et AllDebrid absentes, retéléchargement impossible.")
config.pending_download = None
return action
task = asyncio.create_task(download_from_1fichier(url, platform, game_name, is_zip_non_supported, task_id))

View File

@@ -24,7 +24,7 @@
"error_no_internet": "Keine Internetverbindung. Überprüfe dein Netzwerk.",
"error_controls_mapping": "Fehler beim Zuordnen der Steuerung",
"error_api_key": "Achtung, du musst deinen API-Schlüssel (nur Premium) in der Datei {0} eingeben",
"error_api_key_extended": "Achtung, du musst deinen API-Schlüssel (nur Premium) in der Datei /userdata/saves/ports/rgsx/1fichierAPI.txt einfügen. Öffne die Datei in einem Texteditor und füge den API-Schlüssel ein",
"error_api_key_extended": "Achtung, du musst deinen API-Schlüssel (nur Premium) in der Datei /userdata/saves/ports/rgsx/1FichierAPI.txt einfügen. Öffne die Datei in einem Texteditor und füge den API-Schlüssel ein",
"error_invalid_download_data": "Ungültige Downloaddaten",
"error_delete_sources": "Fehler beim Löschen der Datei systems_list.json oder Ordner",
"error_extension": "Nicht unterstützte Erweiterung oder Downloadfehler",

View File

@@ -24,7 +24,7 @@
"error_no_internet": "No Internet connection. Check your network.",
"error_controls_mapping": "Failed to map controls",
"error_api_key": "Please enter your API key (premium only) in the file {0}",
"error_api_key_extended": "Please enter your API key (premium only) in the file /userdata/saves/ports/rgsx/1fichierAPI.txt by opening it in a text editor and pasting your API key",
"error_api_key_extended": "Please enter your API key (premium only) in the file /userdata/saves/ports/rgsx/1FichierAPI.txt by opening it in a text editor and pasting your API key",
"error_invalid_download_data": "Invalid download data",
"error_delete_sources": "Error deleting systems_list.json file or folders",
"error_extension": "Unsupported extension or download error",

View File

@@ -25,7 +25,7 @@
"error_no_internet": "Sin conexión a Internet. Verifica tu red.",
"error_controls_mapping": "Error al mapear los controles",
"error_api_key": "Atención, debes ingresar tu clave API (solo premium) en el archivo {0}",
"error_api_key_extended": "Atención, debes ingresar tu clave API (solo premium) en el archivo /userdata/saves/ports/rgsx/1fichierAPI.txt, abrirlo en un editor de texto y pegar la clave API",
"error_api_key_extended": "Atención, debes ingresar tu clave API (solo premium) en el archivo /userdata/saves/ports/rgsx/1FichierAPI.txt, abrirlo en un editor de texto y pegar la clave API",
"error_invalid_download_data": "Datos de descarga no válidos",
"error_delete_sources": "Error al eliminar el archivo systems_list.json o carpetas",
"error_extension": "Extensión no soportada o error de descarga",

View File

@@ -21,7 +21,7 @@
"error_no_internet": "Pas de connexion Internet. Vérifiez votre réseau.",
"error_controls_mapping": "Échec du mappage des contrôles",
"error_api_key": "Attention il faut renseigner sa clé API (premium only) dans le fichier {0}",
"error_api_key_extended": "Attention il faut renseigner sa clé API (premium only) dans le fichier /userdata/saves/ports/rgsx/1fichierAPI.txt à ouvrir dans un éditeur de texte et coller la clé API",
"error_api_key_extended": "Attention il faut renseigner sa clé API (premium only) dans le fichier /userdata/saves/ports/rgsx/1FichierAPI.txt à ouvrir dans un éditeur de texte et coller la clé API",
"error_invalid_download_data": "Données de téléchargement invalides",
"error_delete_sources": "Erreur lors de la suppression du fichier systems_list.json ou dossiers",
"error_extension": "Extension non supportée ou erreur de téléchargement",

View File

@@ -24,7 +24,7 @@
"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_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",

View File

@@ -24,7 +24,7 @@
"error_no_internet": "Sem conexão com a Internet. Verifique sua rede.",
"error_controls_mapping": "Falha ao mapear controles",
"error_api_key": "Insira sua chave API (somente premium) no arquivo {0}",
"error_api_key_extended": "Insira sua chave API (somente premium) no arquivo /userdata/saves/ports/rgsx/1fichierAPI.txt abrindo-o em um editor de texto e colando sua chave",
"error_api_key_extended": "Insira sua chave API (somente premium) no arquivo /userdata/saves/ports/rgsx/1FichierAPI.txt abrindo-o em um editor de texto e colando sua chave",
"error_invalid_download_data": "Dados de download inválidos",
"error_delete_sources": "Erro ao deletar arquivo sources.json ou pastas",
"error_extension": "Extensão não suportada ou erro no download",

View File

@@ -15,7 +15,7 @@ try:
except Exception:
pygame = None # type: ignore
from config import OTA_VERSION_ENDPOINT,APP_FOLDER, UPDATE_FOLDER, OTA_UPDATE_ZIP
from utils import sanitize_filename, extract_zip, extract_rar, load_api_key_1fichier, normalize_platform_name
from utils import sanitize_filename, extract_zip, extract_rar, load_api_key_1fichier, load_api_key_alldebrid, normalize_platform_name
from history import save_history
import logging
import datetime
@@ -635,6 +635,10 @@ async def download_rom(url, platform, game_name, is_zip_non_supported=False, tas
async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=False, task_id=None):
config.API_KEY_1FICHIER = load_api_key_1fichier()
if not config.API_KEY_1FICHIER:
# Fallback: essayer AllDebrid
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
logger.debug(f"Clé API 1fichier absente, fallback AllDebrid: {'présente' if config.API_KEY_ALLDEBRID else 'absente'}")
logger.debug(f"Début téléchargement 1fichier: {game_name} depuis {url}, is_zip_non_supported={is_zip_non_supported}, task_id={task_id}")
logger.debug(f"Clé API 1fichier: {'présente' if config.API_KEY_1FICHIER else 'absente'}")
result = [None, None]
@@ -679,50 +683,83 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
logger.error(f"Pas de permission d'écriture dans {dest_dir}")
raise PermissionError(f"Pas de permission d'écriture dans {dest_dir}")
headers = {
"Authorization": f"Bearer {config.API_KEY_1FICHIER}",
"Content-Type": "application/json"
}
payload = {
"url": link,
"pretty": 1
}
logger.debug(f"Préparation requête file/info pour {link}")
response = requests.post("https://api.1fichier.com/v1/file/info.cgi", headers=headers, json=payload, timeout=30)
logger.debug(f"Réponse file/info reçue, code: {response.status_code}")
response.raise_for_status()
file_info = response.json()
if "error" in file_info and file_info["error"] == "Resource not found":
logger.error(f"Le fichier {game_name} n'existe pas sur 1fichier")
result[0] = False
result[1] = _("network_file_not_found").format(game_name)
return
filename = file_info.get("filename", "").strip()
if not filename:
logger.error(f"Impossible de récupérer le nom du fichier")
result[0] = False
result[1] = _("network_cannot_get_filename")
return
sanitized_filename = sanitize_filename(filename)
dest_path = os.path.join(dest_dir, sanitized_filename)
logger.debug(f"Chemin destination: {dest_path}")
logger.debug(f"Envoi requête get_token pour {link}")
response = requests.post("https://api.1fichier.com/v1/download/get_token.cgi", headers=headers, json=payload, timeout=30)
logger.debug(f"Réponse get_token reçue, code: {response.status_code}")
response.raise_for_status()
download_info = response.json()
final_url = download_info.get("url")
if not final_url:
logger.error(f"Impossible de récupérer l'URL de téléchargement")
result[0] = False
result[1] = _("network_cannot_get_download_url")
return
logger.debug(f"URL de téléchargement obtenue: {final_url}")
# Choisir la stratégie d'accès: 1fichier direct via API, sinon AllDebrid pour débrider
if config.API_KEY_1FICHIER:
headers = {
"Authorization": f"Bearer {config.API_KEY_1FICHIER}",
"Content-Type": "application/json"
}
payload = {
"url": link,
"pretty": 1
}
logger.debug(f"Préparation requête 1fichier file/info pour {link}")
response = requests.post("https://api.1fichier.com/v1/file/info.cgi", headers=headers, json=payload, timeout=30)
logger.debug(f"Réponse file/info reçue, code: {response.status_code}")
response.raise_for_status()
file_info = response.json()
if "error" in file_info and file_info["error"] == "Resource not found":
logger.error(f"Le fichier {game_name} n'existe pas sur 1fichier")
result[0] = False
result[1] = _("network_file_not_found").format(game_name)
return
filename = file_info.get("filename", "").strip()
if not filename:
logger.error("Impossible de récupérer le nom du fichier")
result[0] = False
result[1] = _("network_cannot_get_filename")
return
sanitized_filename = sanitize_filename(filename)
dest_path = os.path.join(dest_dir, sanitized_filename)
logger.debug(f"Chemin destination: {dest_path}")
logger.debug(f"Envoi requête 1fichier get_token pour {link}")
response = requests.post("https://api.1fichier.com/v1/download/get_token.cgi", headers=headers, json=payload, timeout=30)
logger.debug(f"Réponse get_token reçue, code: {response.status_code}")
response.raise_for_status()
download_info = response.json()
final_url = download_info.get("url")
if not final_url:
logger.error("Impossible de récupérer l'URL de téléchargement")
result[0] = False
result[1] = _("network_cannot_get_download_url")
return
logger.debug(f"URL de téléchargement obtenue via 1fichier: {final_url}")
else:
# AllDebrid: débrider l'URL 1fichier vers une URL directe
if not getattr(config, 'API_KEY_ALLDEBRID', ''):
logger.error("Aucune clé API (1fichier/AllDebrid) disponible")
result[0] = False
result[1] = _("network_api_error").format("Missing API key") if _ else "API key missing"
return
ad_key = config.API_KEY_ALLDEBRID
# AllDebrid API v4 example: GET https://api.alldebrid.com/v4/link/unlock?agent=<app>&apikey=<key>&link=<url>
params = {
'agent': 'RGSX',
'apikey': ad_key,
'link': link
}
logger.debug("Requête AllDebrid link/unlock en cours")
response = requests.get("https://api.alldebrid.com/v4/link/unlock", params=params, timeout=30)
logger.debug(f"Réponse AllDebrid reçue, code: {response.status_code}")
response.raise_for_status()
ad_json = response.json()
if ad_json.get('status') != 'success':
err = ad_json.get('error', {}).get('code') or ad_json
logger.error(f"AllDebrid échec débridage: {err}")
result[0] = False
result[1] = _("network_api_error").format(f"AllDebrid unlock failed: {err}") if _ else f"AllDebrid unlock failed: {err}"
return
data = ad_json.get('data', {})
filename = data.get('filename') or game_name
final_url = data.get('link') or data.get('download') or data.get('streamingLink')
if not final_url:
logger.error("AllDebrid n'a pas renvoyé de lien direct")
result[0] = False
result[1] = _("network_cannot_get_download_url")
return
sanitized_filename = sanitize_filename(filename)
dest_path = os.path.join(dest_dir, sanitized_filename)
logger.debug(f"URL directe obtenue via AllDebrid: {final_url}")
lock = threading.Lock()
retries = 10
retry_delay = 10
@@ -754,6 +791,7 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
downloaded = 0
chunk_size = 8192
last_update_time = time.time()
last_downloaded = 0
update_interval = 0.1 # Mettre à jour toutes les 0,1 secondes
logger.debug(f"Ouverture fichier: {dest_path}")
with open(dest_path, 'wb') as f:
@@ -789,8 +827,12 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
entry["total_size"] = total_size
config.needs_redraw = True
break
progress_queues[task_id].put((task_id, downloaded, total_size))
# Calcul de la vitesse en Mo/s
delta = downloaded - last_downloaded
speed = (delta / (current_time - last_update_time) / (1024 * 1024)) if (current_time - last_update_time) > 0 else 0.0
last_downloaded = downloaded
last_update_time = current_time
progress_queues[task_id].put((task_id, downloaded, total_size, speed))
if is_zip_non_supported:
with lock:
@@ -893,7 +935,11 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
logger.debug(f"Mise à jour finale historique: status={entry['status']}, progress={entry['progress']}%, message={message}, task_id={task_id}")
break
else:
downloaded, total_size = data[1], data[2]
if len(data) >= 4:
downloaded, total_size, speed = data[1], data[2], data[3]
else:
downloaded, total_size = data[1], data[2]
speed = 0.0
progress_percent = int(downloaded / total_size * 100) if total_size > 0 else 0
progress_percent = max(0, min(100, progress_percent))
@@ -904,6 +950,7 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
entry["status"] = "Téléchargement"
entry["downloaded_size"] = downloaded
entry["total_size"] = total_size
entry["speed"] = speed # Ajout de la vitesse
config.needs_redraw = True
break
await asyncio.sleep(0.1)

View File

@@ -1284,6 +1284,33 @@ def load_api_key_1fichier():
logger.error(f"Erreur lors de la lecture de la clé API : {e}")
return ""
def load_api_key_alldebrid():
"""Charge la clé API AllDebrid depuis le dossier de sauvegarde, crée le fichier si absent."""
try:
api_file = os.path.join(config.SAVE_FOLDER, "AllDebridAPI.txt")
logger.debug(f"Chemin du fichier de clé API AllDebrid: {api_file}")
if not os.path.exists(api_file):
logger.info("Fichier de clé API AllDebrid non trouvé")
os.makedirs(config.SAVE_FOLDER, exist_ok=True)
with open(api_file, "w", encoding="utf-8") as f:
f.write("")
logger.info(f"Fichier de clé API AllDebrid créé : {api_file}")
return ""
with open(api_file, "r", encoding="utf-8") as f:
api_key = f.read().strip()
logger.debug(f"Clé API AllDebrid lue: '{api_key}' (longueur: {len(api_key)})")
if not api_key:
logger.warning("Clé API AllDebrid vide, renseignez-la dans AllDebridAPI.txt pour activer le débridage.")
# Stocke dans la config pour usage global
try:
config.API_KEY_ALLDEBRID = api_key
except Exception:
pass
return api_key
except Exception as e:
logger.error(f"Erreur lors du chargement de la clé API AllDebrid: {e}")
return ""
def load_music_config():
"""Charge la configuration musique depuis rgsx_settings.json."""
try: