Actualiser api.php

This commit is contained in:
2026-06-30 14:43:28 +02:00
parent 037605dbf6
commit bbfcf54fb5
+67 -30
View File
@@ -338,9 +338,10 @@ function fetchTmdbPosterAndSynopsis($title, $year = '', $pdo = null) {
return $default;
}
// ── FONCTION POUR RÉCUPÉRER LES DONNÉES DEPUIS BLU-RAY.COM ──
function fetchFromBlurayCom($ean) {
static $lastRequest = 0;
static $requestCount = 0;
$empty = [
'title' => '', 'year' => '', 'director' => '', 'actors' => '',
'poster' => '', 'description' => '', 'length' => '',
@@ -349,44 +350,74 @@ function fetchFromBlurayCom($ean) {
];
$ean = preg_replace('/[^0-9]/', '', (string)$ean);
if (strlen($ean) < 8) return $empty;
if (strlen($ean) < 8) {
error_log("Blu-ray.com: ❌ EAN invalide: $ean");
return $empty;
}
// ✅ THROTTLE : 2 secondes entre chaque requête
// ✅ THROTTLE : 5 secondes entre chaque requête (anti-blocage)
$now = microtime(true);
if ($lastRequest > 0 && ($now - $lastRequest) < 2) {
usleep((int)((2 - ($now - $lastRequest)) * 1000000));
if ($lastRequest > 0 && ($now - $lastRequest) < 5) {
$sleepTime = 5 - ($now - $lastRequest);
error_log("Blu-ray.com: ⏱️ Attente de " . round($sleepTime, 2) . "s avant requête");
usleep((int)($sleepTime * 1000000));
}
$lastRequest = microtime(true);
$requestCount++;
// ÉTAPE 1 : Recherche par EAN sur Blu-ray.com
$searchUrl = "https://www.blu-ray.com/movies/search.php?ean=" . urlencode($ean) . "&action=search";
// ✅ URL de recherche complète (comme dans le navigateur)
$searchUrl = "https://www.blu-ray.com/movies/search.php?keyword=&studioid=&videocodec=&disc=&yearfrom=&yearto=&regioncoding=&aspectratio=&aspectratio_original=&releaseyear=&synopsis=&retailerexclusive=&mpaa=&runtimemin=&runtimemax=&videoresolutionid=&sourceid=&subtitles=&audio=&upc=&ean=" . urlencode($ean) . "&asin=&casingid=&slipcoverfront=&slipcoverback=&submit=Search&action=search";
error_log("Blu-ray.com: 🔍 Recherche EAN $ean (requête #$requestCount)");
$ch = curl_init($searchUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 20,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3,
// ✅ User-Agent réaliste (Chrome complet)
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
// ✅ Headers complets
CURLOPT_HTTPHEADER => [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
'Referer: https://www.blu-ray.com/',
'Connection: keep-alive'
]
'Accept-Encoding: gzip, deflate, br',
'Referer: https://www.blu-ray.com/movies/',
'Connection: keep-alive',
'Upgrade-Insecure-Requests: 1',
'Sec-Fetch-Dest: document',
'Sec-Fetch-Mode: navigate',
'Sec-Fetch-Site: same-origin',
'Sec-Fetch-User: ?1',
'Cache-Control: max-age=0'
],
// ✅ Compression
CURLOPT_ENCODING => '',
]);
$searchHtml = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if (!$searchHtml || $httpCode !== 200) {
error_log("Blu-ray.com: ❌ Échec recherche EAN $ean (HTTP $httpCode)");
error_log("Blu-ray.com: ❌ Échec recherche EAN $ean (HTTP $httpCode) - Erreur: $curlError");
// ✅ Si bloqué (429), attendre plus longtemps
if ($httpCode === 429) {
error_log("Blu-ray.com: ⚠️ Rate limit atteint, attente de 30s");
sleep(30);
}
return $empty;
}
// Extraire l'URL du film depuis les résultats
if (!preg_match('/href="(https?:\/\/www\.blu-ray\.com\/movies\/[^\/]+\/(\d+)\/)"/i', $searchHtml, $matches)) {
// ✅ Regex amélioré pour extraire l'URL du film
// Structure réelle : <a class="hoverlink" ... href="https://www.blu-ray.com/movies/.../132053/" ...>
if (!preg_match('/href="(https:\/\/www\.blu-ray\.com\/movies\/[^"]+\/(\d+)\/)"/i', $searchHtml, $matches)) {
error_log("Blu-ray.com: ❌ Film non trouvé pour EAN $ean");
return $empty;
}
@@ -394,31 +425,35 @@ function fetchFromBlurayCom($ean) {
$movieUrl = $matches[1];
$movieId = $matches[2];
// ✅ THROTTLE avant la 2ème requête
usleep(1000000);
error_log("Blu-ray.com: ✅ Film trouvé → $movieUrl");
// ✅ Délai avant la 2ème requête
sleep(3);
// ÉTAPE 2 : Récupérer la page du film
$ch2 = curl_init($movieUrl);
curl_setopt_array($ch2, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 20,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
CURLOPT_HTTPHEADER => [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
'Referer: https://www.blu-ray.com/',
'Referer: https://www.blu-ray.com/movies/search.php',
'Connection: keep-alive'
]
],
CURLOPT_ENCODING => '',
]);
$movieHtml = curl_exec($ch2);
$httpCode2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
curl_close($ch2);
if (!$movieHtml || $httpCode2 !== 200) {
error_log("Blu-ray.com: ❌ Impossible de charger la page du film $movieUrl (HTTP $httpCode2)");
error_log("Blu-ray.com: ❌ Impossible de charger la page du film (HTTP $httpCode2)");
return $empty;
}
@@ -652,7 +687,7 @@ case 'import_batch':
$pdo->beginTransaction();
$imported = 0; $skipped = 0;
try {
if ($type === 'videotheque') {
if ($type === 'videotheque') {
$stmt = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE
title=VALUES(title), year=VALUES(year), format=VALUES(format),
@@ -668,22 +703,21 @@ case 'import_batch':
foreach ($items as $item) {
$ean = preg_replace('/[^0-9]/', '', (string)($item['ean'] ?? ''));
$csvTitle = trim($item['title'] ?? ''); // ✅ Titre issu du CSV
$csvTitle = trim($item['title'] ?? ''); // ✅ Titre du CSV
// ✅ On ne skip que si on n'a ni EAN ni titre
if (strlen($ean) < 8 && empty($csvTitle)) {
$skipped++;
continue;
}
// 1. ✅ Données physiques via BLU-RAY.COM (prioritaire)
// 1. Essayer Blu-ray.com (avec throttling)
$blurayData = !empty($ean) ? fetchFromBlurayCom($ean) : [];
// ✅ Si Blu-ray.com trouve le film, on prend son titre. Sinon, on prend celui du CSV.
// ✅ Si Blu-ray.com trouve le film, utiliser son titre. Sinon, utiliser celui du CSV.
$title = !empty($blurayData['title']) ? $blurayData['title'] : $csvTitle;
// ✅ Si toujours pas de titre, on skip
if (empty($title)) {
error_log("Import: ❌ Pas de titre pour EAN $ean - ignoré");
$skipped++;
continue;
}
@@ -701,6 +735,7 @@ case 'import_batch':
// 2. ✅ FALLBACK TMDB si Blu-ray.com n'a pas trouvé certaines données
if (empty($poster) || empty($director) || empty($actors) || empty($desc) || empty($year)) {
error_log("Import: 🔄 Fallback TMDB pour '$title'");
$tmdb = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') {
@@ -716,6 +751,8 @@ case 'import_batch':
$id = makeStableId('videotheque', $title, $year);
$stmt->execute([$id, $title, $year, $format, $poster, $ean, $desc, $length, $discs, $aspect, $actors, $publisher, $director]);
$imported++;
error_log("Import: ✅ Importé '$title' ($ean)");
}
} else { // ── IMPORTATION CRITIQUES ──
$stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)