Actualiser api.php

This commit is contained in:
2026-06-27 11:25:38 +02:00
parent fe4414c302
commit 84303fea95
+61 -219
View File
@@ -154,132 +154,6 @@ function fetchPosterTMDB($title, $year = '', $pdo = null) {
return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => 'Blu-ray']; return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => 'Blu-ray'];
} }
// ── FONCTION POUR RÉCUPÉRER LES INFOS PHYSIQUES DEPUIS BLU-RAY.COM ──
function fetchBluRayPhysicalInfo($ean, $title = '', $pdo = null) {
$defaultPoster = 'assets/img/default_physical_media.jpg';
$result = [
'poster' => $defaultPoster,
'format' => '',
'publisher' => '',
'length' => '',
'number_of_discs'=> '',
'aspect_ratio' => '',
'description' => '',
'year' => '',
'director' => '',
'actors' => ''
];
// Nettoyer l'EAN/UPC
$cleanEan = preg_replace('/[^0-9]/', '', $ean);
if (empty($cleanEan) && empty($title)) return $result;
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
$productUrl = null;
// ── ÉTAPE 1 : Recherche par EAN/UPC ──
if (!empty($cleanEan)) {
$searchUrl = "https://www.blu-ray.com/search/?quicksearch=1&searchtype=products&q=" . urlencode($cleanEan);
$searchRes = httpGet($searchUrl, 10, $userAgent);
if ($searchRes && preg_match('/<a\s+href="\/products\/\?id=(\d+)"[^>]*>/i', $searchRes, $matches)) {
$productUrl = "https://www.blu-ray.com/products/?id=" . $matches[1];
}
}
// ── ÉTAPE 2 : Fallback par titre ──
if (!$productUrl && !empty($title)) {
$cleanTitle = cleanTitle($title);
$searchUrl = "https://www.blu-ray.com/search/?quicksearch=1&searchtype=movies&q=" . urlencode($cleanTitle);
$searchRes = httpGet($searchUrl, 10, $userAgent);
if ($searchRes && preg_match('/<a\s+href="\/movies\/\?id=(\d+)"[^>]*>/i', $searchRes, $matches)) {
$productUrl = "https://www.blu-ray.com/movies/?id=" . $matches[1];
}
}
if (!$productUrl) {
error_log("BluRay.com: Film non trouvé pour EAN '{$ean}' / titre '{$title}'");
return $result;
}
error_log("BluRay.com: Accès à {$productUrl}");
$productRes = httpGet($productUrl, 10, $userAgent);
if (!$productRes) {
error_log("BluRay.com: Page inaccessible {$productUrl}");
return $result;
}
// ── ÉTAPE 3 : Extraire l'affiche ──
if (preg_match('/<img[^>]*id="home_release_img"[^>]*src="([^"]+)"/i', $productRes, $imgMatches)) {
$posterUrl = $imgMatches[1];
$posterUrl = str_replace('/resized/', '/', $posterUrl);
$posterUrl = str_replace('http://', 'https://', $posterUrl);
$result['poster'] = $posterUrl;
}
// ── ÉTAPE 4 : Extraire les informations techniques ──
// ── ÉTAPE 4 : Extraire les informations techniques ──
if (preg_match('/<div[^>]*class="[^"]*productdetails[^"]*"[^>]*>.*?<\/div>/is', $productRes, $detailsBlock)) {
$detailsHtml = $detailsBlock[0];
} else {
$detailsHtml = $productRes;
}
// Détection du format
if (preg_match('/<b>Format<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
$formatRaw = trim(strip_tags($m[1]));
if (stripos($formatRaw, '4K') !== false || stripos($formatRaw, 'UHD') !== false) {
$result['format'] = '4K Ultra HD';
} elseif (stripos($formatRaw, 'DVD') !== false) {
$result['format'] = 'DVD';
} elseif (stripos($formatRaw, 'Blu') !== false) {
$result['format'] = 'Blu-ray';
}
}
// Nombre de disques
if (preg_match('/<b>(?:Discs?|Disques?)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
if (preg_match('/(\d+)/', $m[1], $num)) {
$result['number_of_discs'] = (int)$num[1];
}
}
// Aspect ratio
if (preg_match('/<b>Aspect\s*ratio<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
$result['aspect_ratio'] = trim(strip_tags($m[1]));
}
// Durée (runtime)
if (preg_match('/<b>(?:Runtime|Durée|Length)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
if (preg_match('/(\d+)/', $m[1], $num)) {
$result['length'] = $num[1] . ' min';
}
}
// Studio / Éditeur (Corrigé, ne crashe plus sur la balise <a>)
if (preg_match('/<b>(?:Studio|Label|Distributor)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
$result['publisher'] = trim(strip_tags($m[1]));
}
// Année de sortie
if (preg_match('/<b>(?:Release\s*Date|Country\s*&\s*Date)<\/b>.*?<td[^>]*>(.*?)<\/td>/is', $detailsHtml, $m)) {
if (preg_match('/(\d{4})/', $m[1], $num)) {
$result['year'] = $num[1];
}
}
// Synopsis
if (preg_match('/<div[^>]*class="[^"]*synopsis[^"]*"[^>]*>(.*?)<\/div>/is', $productRes, $m)) {
$result['description'] = trim(strip_tags($m[1]));
}
error_log("BluRay.com: Infos récupérées pour '{$title}' → " . json_encode($result));
return $result;
}
// ── FONCTION POUR RÉCUPÉRER LE SYNOPSIS DEPUIS TMDB ── // ── FONCTION POUR RÉCUPÉRER LE SYNOPSIS DEPUIS TMDB ──
function fetchTmdbSynopsis($title, $year = '', $pdo = null) { function fetchTmdbSynopsis($title, $year = '', $pdo = null) {
$tmdbKey = getTmdbApiKey($pdo); $tmdbKey = getTmdbApiKey($pdo);
@@ -545,7 +419,7 @@ switch ($action) {
else { http_response_code(400); echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]); } else { http_response_code(400); echo json_encode(["success" => false, "error" => "Aucun élément sélectionné."]); }
break; break;
case 'import_batch': case 'import_batch':
checkAuth($pdo); checkAuth($pdo);
$data = json_decode(file_get_contents("php://input"), true); $data = json_decode(file_get_contents("php://input"), true);
$type = $data['type'] ?? 'critique'; $type = $data['type'] ?? 'critique';
@@ -555,110 +429,77 @@ switch ($action) {
$imported = 0; $imported = 0;
try { try {
if ($type === 'videotheque') { // ── On récupère la clé d'API une seule fois pour tout le monde ──
$stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director) $tmdbApiKey = getTmdbApiKey($pdo);
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
ean_isbn13 = VALUES(ean_isbn13),
poster = VALUES(poster),
description = VALUES(description),
format = VALUES(format),
length = VALUES(length),
number_of_discs = VALUES(number_of_discs),
aspect_ratio = VALUES(aspect_ratio),
actors = VALUES(actors),
publisher = VALUES(publisher),
director = VALUES(director),
year = VALUES(year)");
foreach ($items as $item) { if ($type === 'videotheque') {
$title = $item['title'] ?? ''; $stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description, length, number_of_discs, aspect_ratio, actors, publisher, director)
if (empty($title)) continue; VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
ean_isbn13 = VALUES(ean_isbn13),
poster = VALUES(poster),
description = VALUES(description),
format = VALUES(format),
length = VALUES(length),
number_of_discs = VALUES(number_of_discs),
aspect_ratio = VALUES(aspect_ratio),
actors = VALUES(actors),
publisher = VALUES(publisher),
director = VALUES(director),
year = VALUES(year)");
$year = $item['year'] ?? ''; foreach ($items as $item) {
$ean = $item['ean'] ?? ''; $title = $item['title'] ?? '';
$descCsv = $item['description'] ?? ''; if (empty($title)) continue;
$lengthCsv = $item['length'] ?? '';
$discsCsv = $item['number_of_discs'] ?? 1;
$aspectCsv = $item['aspect_ratio'] ?? '';
$actorsCsv = $item['actors'] ?? '';
$publisherCsv = $item['publisher'] ?? '';
$directorCsv = $item['director'] ?? '';
$formatCsv = $item['format'] ?? ''; // 👈 LIGNE À AJOUTER
$id = makeStableId('videotheque', $title, $year); $year = $item['year'] ?? '';
$id = makeStableId('videotheque', $title, $year);
// ── SOURCE 1 : BLU-RAY.COM (infos physiques) ── // ── 1. RECUPERATION DE TOUTES LES INFOS PHYSIQUES DEPUIS LE CSV ──
$bluRayData = fetchBluRayPhysicalInfo($ean, $title, $pdo); $ean = $item['ean'] ?? '';
$format = $item['format'] ?? 'Inconnu';
$publisher = $item['publisher'] ?? '';
$discs = $item['number_of_discs'] ?? 1;
$aspect = $item['aspect_ratio'] ?? '';
$length = $item['length'] ?? '';
// ── SOURCE 2 : TMDB (affiche + synopsis + métadonnées) ── // Champs cinématographiques de base (du CSV s'ils existent)
$tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo); $desc = $item['description'] ?? '';
$director = $item['director'] ?? '';
$actors = $item['actors'] ?? '';
$poster = 'assets/img/default_physical_media.jpg'; // Image par défaut
// ── FUSION DES DONNÉES ── // ── 2. APPEL API (TMDB ou OMDb) POUR COMBLER LES MANQUES ──
if ($tmdbApiKey && !empty($title)) {
$apiData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo);
$poster = ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg') if ($apiData) {
? $tmdbData['poster'] if (empty($director)) $director = $apiData['director'] ?? '';
: $bluRayData['poster']; if (empty($actors)) $actors = $apiData['actors'] ?? '';
if (empty($desc)) $desc = $apiData['synopsis'] ?? '';
if (empty($length) && !empty($apiData['length'])) $length = $apiData['length'];
// Priorité au CSV, puis BluRay.com, puis détection du titre if (!empty($apiData['poster'])) {
$format = !empty($formatCsv) $poster = $apiData['poster'];
? $formatCsv }
: (!empty($bluRayData['format']) ? $bluRayData['format'] : detectFormat($title, $descCsv)); }
}
// Affiche : TMDB en priorité (meilleure qualité) error_log("Import vidéotheque '{$title}' : poster=" . ($poster !== 'assets/img/default_physical_media.jpg' ? 'OK' : 'DEFAULT') . ", format={$format}, discs={$discs}, aspect={$aspect}");
$poster = ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg')
? $tmdbData['poster']
: $bluRayData['poster'];
// Format : BluRay.com > détection depuis titre // Exécution remise À L'INTÉRIEUR de la boucle, avec les bonnes variables ($year, $desc)
$format = !empty($bluRayData['format']) $stmtVideo->execute([
? $bluRayData['format'] $id, $title, $year, $format, $poster, $ean, $desc,
: detectFormat($title, $descCsv); $length, $discs, $aspect, $actors, $publisher, $director
]);
$imported++;
}
// Éditeur : CSV > BluRay.com
$publisher = !empty($publisherCsv) ? $publisherCsv : $bluRayData['publisher'];
// Nombre de disques : CSV > BluRay.com
$discs = !empty($discsCsv) && $discsCsv != 1
? $discsCsv
: (!empty($bluRayData['number_of_discs']) ? $bluRayData['number_of_discs'] : ($discsCsv ?: 1));
// Aspect ratio : CSV > BluRay.com
$aspect = !empty($aspectCsv) ? $aspectCsv : $bluRayData['aspect_ratio'];
// Durée : CSV > BluRay.com > TMDB
$length = !empty($lengthCsv)
? $lengthCsv
: (!empty($bluRayData['length']) ? $bluRayData['length'] : $tmdbData['length']);
// Description : CSV > TMDB > BluRay.com
$description = !empty($descCsv)
? $descCsv
: (!empty($tmdbData['description']) ? $tmdbData['description'] : $bluRayData['description']);
// Réalisateur : CSV > TMDB
$director = !empty($directorCsv) ? $directorCsv : $tmdbData['director'];
// Acteurs : CSV > TMDB
$actors = !empty($actorsCsv) ? $actorsCsv : $tmdbData['actors'];
// Année : CSV > TMDB > BluRay.com
$finalYear = !empty($year) ? $year : (!empty($tmdbData['year']) ? $tmdbData['year'] : $bluRayData['year']);
error_log("Import vidéotheque '{$title}' : poster=" . ($poster !== 'assets/img/default_physical_media.jpg' ? 'OK' : 'DEFAULT') . ", format={$format}, discs={$discs}, aspect={$aspect}");
$stmtVideo->execute([
$id, $title, $finalYear, $format, $poster, $ean, $description,
$length, $discs, $aspect, $actors, $publisher, $director
]);
$imported++;
}
} else { } else {
$stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming) $stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=VALUES(director), ON DUPLICATE KEY UPDATE title=VALUES(title), year=VALUES(year), director=VALUES(director),
poster=VALUES(poster), rating=VALUES(rating), review=VALUES(review), streaming=VALUES(streaming)"); poster=VALUES(poster), rating=VALUES(rating), review=VALUES(review), streaming=VALUES(streaming)");
$tmdbApiKey = getTmdbApiKey($pdo);
foreach ($items as $rowData) { foreach ($items as $rowData) {
$title = $rowData['Title'] ?? $rowData['title'] ?? ''; $title = $rowData['Title'] ?? $rowData['title'] ?? '';
@@ -675,10 +516,10 @@ switch ($action) {
if ($tmdbApiKey && !empty($title)) { if ($tmdbApiKey && !empty($title)) {
$tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo); $tmdbData = fetchTMDBFull($title, $year, $tmdbApiKey, $pdo);
if ($tmdbData) { if ($tmdbData) {
$director = $tmdbData['director']; $director = $tmdbData['director'] ?? '';
$poster = $tmdbData['poster']; $poster = $tmdbData['poster'] ?? '';
$streaming = $tmdbData['streaming']; $streaming = $tmdbData['streaming'] ?? '';
if (empty($year)) $year = $tmdbData['year']; if (empty($year)) $year = $tmdbData['year'] ?? '';
if (!empty($tmdbData['title'])) $title = $tmdbData['title']; if (!empty($tmdbData['title'])) $title = $tmdbData['title'];
} }
} }
@@ -688,6 +529,7 @@ switch ($action) {
$imported++; $imported++;
} }
} }
$pdo->commit(); $pdo->commit();
echo json_encode(["success" => true, "imported" => $imported]); echo json_encode(["success" => true, "imported" => $imported]);
} catch (Exception $e) { } catch (Exception $e) {