Actualiser api.php
This commit is contained in:
@@ -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=®ioncoding=&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)
|
||||
|
||||
Reference in New Issue
Block a user