Compare commits

..

7 Commits

Author SHA1 Message Date
skymike03
21b39c66b9 v2.6.1.4 (2026.03.30)
- Add browser-like headers for file downloads with debrids and enhance AllDebrid link handling
2026-03-30 21:12:59 +02:00
skymike03
42b2204aeb Reverted back to original version after test 2026-03-22 12:25:45 +01:00
skymike03
67a38c45aa ## v2.6.3.1.0 TEST (2026.03.22)
- Test discord auto release changelog
- Test
2026-03-22 12:20:46 +01:00
skymike03
893b73ecc5 Refactor Discord changelog notification step in release workflow 2026-03-22 12:09:32 +01:00
skymike03
5e1a684275 Enhance Discord notifications with changelog and bot details 2026-03-22 12:06:06 +01:00
skymike03
9226a818f3 v2.6.3.1 (test update) 2026-03-22 11:56:58 +01:00
skymike03
2fd1bcaf01 test discord 2026-03-22 11:55:58 +01:00
4 changed files with 84 additions and 5 deletions

View File

@@ -148,3 +148,16 @@ jobs:
dist/RGSX_full_latest.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Send changelog to Discord
run: |
CHANGELOG=$(git log -1 --format=%B ${{ github.ref_name }} | sed ':a;N;$!ba;s/\n/\\n/g')
curl -H "Content-Type: application/json" \
-X POST \
-d "{
\"username\": \"RGSX Releases Bot\",
\"avatar_url\": \"https://retrogamesets.fr/assets/images/avatar.png\",
\"content\": \"📦 **RGSX ${{ github.ref_name }}**\n\n📝 **Changelog :**\n${CHANGELOG}\"
}" \
${{ secrets.DISCORD_WEBHOOK }}

View File

@@ -27,7 +27,7 @@ except Exception:
pygame = None # type: ignore
# Version actuelle de l'application
app_version = "2.6.1.3"
app_version = "2.6.1.4"
# Nombre de jours avant de proposer la mise à jour de la liste des jeux
GAMELIST_UPDATE_DAYS = 1

View File

@@ -39,6 +39,21 @@ import urllib.parse
logger = logging.getLogger(__name__)
def _build_browser_download_headers(referer: str | None = None, accept: str = 'application/octet-stream,*/*;q=0.8') -> dict:
"""Build browser-like headers for file downloads that reject minimal clients."""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
'Accept': accept,
'Accept-Language': 'en-US,en;q=0.9,fr;q=0.8',
'Accept-Encoding': 'identity',
'Connection': 'keep-alive',
'DNT': '1',
}
if referer:
headers['Referer'] = referer
return headers
def _redact_headers(headers: dict) -> dict:
"""Return a copy of headers with sensitive fields redacted for logs."""
if not isinstance(headers, dict):
@@ -1913,6 +1928,25 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
logger.debug(f"Thread téléchargement 1fichier démarré pour {url}, task_id={task_id}")
# Assurer l'accès à provider_used dans cette closure (lecture/écriture)
nonlocal provider_used
def _refresh_alldebrid_final_url(current_link):
"""Request a fresh AllDebrid unlock URL after transient download failures."""
ad_key = getattr(config, 'API_KEY_ALLDEBRID', '')
if not ad_key:
return None, None
params = {'agent': 'RGSX', 'apikey': ad_key, 'link': current_link}
refresh_resp = requests.get("https://api.alldebrid.com/v4/link/unlock", params=params, timeout=30)
refresh_resp.raise_for_status()
refresh_json = refresh_resp.json()
if refresh_json.get('status') != 'success':
logger.warning(f"AllDebrid refresh status != success: {refresh_json}")
return None, None
refresh_data = refresh_json.get('data', {})
return (
refresh_data.get('link') or refresh_data.get('download') or refresh_data.get('streamingLink'),
refresh_data.get('filename'),
)
try:
cancel_ev = cancel_events.get(task_id)
link = url.split('&af=')[0]
@@ -2552,17 +2586,23 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
filename = game_name
sanitized_filename = sanitize_filename(filename)
dest_path = os.path.join(dest_dir, sanitized_filename)
provider_download_session = requests.Session()
provider_download_headers = _build_browser_download_headers()
provider_download_session.headers.update(provider_download_headers)
# Essayer de récupérer la taille du serveur via HEAD request
remote_size = None
try:
if final_url:
head_response = requests.head(final_url, timeout=10, allow_redirects=True)
if final_url and provider_used not in {'AD', 'DL', 'RD'}:
head_response = provider_download_session.head(final_url, timeout=10, allow_redirects=True)
if head_response.status_code == 200:
content_length = head_response.headers.get('content-length')
if content_length:
remote_size = int(content_length)
logger.debug(f"Taille du fichier serveur (AllDebrid/Debrid-Link/RealDebrid): {remote_size} octets")
elif final_url:
logger.debug(f"Saut du HEAD préliminaire pour provider {provider_used}: URL temporaire potentiellement sensible ({final_url})")
except Exception as e:
logger.debug(f"Impossible de vérifier la taille serveur (AllDebrid/Debrid-Link/RealDebrid): {e}")
@@ -2650,13 +2690,39 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
lock = threading.Lock()
retries = 10
retry_delay = 10
download_header_variants = [
provider_download_headers,
_build_browser_download_headers(accept='*/*'),
{
'User-Agent': 'curl/8.4.0',
'Accept': '*/*',
'Accept-Encoding': 'identity',
'Connection': 'keep-alive',
},
]
logger.debug(f"Initialisation progression avec taille inconnue pour task_id={task_id}")
progress_queues[task_id].put((task_id, 0, 0)) # Taille initiale inconnue
for attempt in range(retries):
logger.debug(f"Début tentative {attempt + 1} pour télécharger {final_url}")
try:
with requests.get(final_url, stream=True, headers={'User-Agent': 'Mozilla/5.0'}, timeout=30) as response:
attempt_headers = download_header_variants[min(attempt, len(download_header_variants) - 1)]
logger.debug(f"Headers tentative {attempt + 1}: {_redact_headers(attempt_headers)}")
with provider_download_session.get(final_url, stream=True, headers=attempt_headers, timeout=(30, 120), allow_redirects=True) as response:
logger.debug(f"Réponse GET reçue, code: {response.status_code}")
if response.status_code == 503 and provider_used == 'AD' and attempt < retries - 1:
logger.warning("AllDebrid a renvoyé 503 sur l'URL débridée, tentative de régénération du lien")
try:
refreshed_url, refreshed_filename = _refresh_alldebrid_final_url(link)
if refreshed_url:
if refreshed_url != final_url:
logger.debug(f"Nouvelle URL AllDebrid obtenue: {refreshed_url}")
final_url = refreshed_url
if refreshed_filename:
filename = refreshed_filename
sanitized_filename = sanitize_filename(filename)
dest_path = os.path.join(dest_dir, sanitized_filename)
except Exception as refresh_error:
logger.warning(f"Impossible de régénérer le lien AllDebrid après 503: {refresh_error}")
response.raise_for_status()
total_size = int(response.headers.get('content-length', 0))
logger.debug(f"Taille totale: {total_size} octets")

View File

@@ -1,3 +1,3 @@
{
"version": "2.6.1.3"
"version": "2.6.1.4"
}