Actualiser api.php
This commit is contained in:
@@ -372,7 +372,7 @@ function fetchFromBlurayCom($ean) {
|
||||
static $lastRequest = 0;
|
||||
$empty = [
|
||||
'title' => '', 'year' => '', 'director' => '', 'actors' => '',
|
||||
'poster' => '', 'description' => '', 'length' => '',
|
||||
'poster' => '', 'description' => '', 'length' => '',
|
||||
'publisher' => '', 'format' => 'Blu-ray', 'number_of_discs' => 1,
|
||||
'aspect_ratio' => ''
|
||||
];
|
||||
@@ -394,9 +394,8 @@ function fetchFromBlurayCom($ean) {
|
||||
|
||||
error_log("Blu-ray.com: 🔍 Recherche EAN $ean");
|
||||
|
||||
// Recherche simple par EAN
|
||||
// Recherche par EAN
|
||||
$searchUrl = "https://www.blu-ray.com/movies/search.php?ean=" . urlencode($ean) . "&action=search";
|
||||
|
||||
$ch = curl_init($searchUrl);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
@@ -422,7 +421,7 @@ function fetchFromBlurayCom($ean) {
|
||||
return $empty;
|
||||
}
|
||||
|
||||
// Extraire l'URL du film
|
||||
// Extraire l'URL du film - regex améliorée
|
||||
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;
|
||||
@@ -432,6 +431,9 @@ function fetchFromBlurayCom($ean) {
|
||||
$movieId = $matches[2];
|
||||
error_log("Blu-ray.com: ✅ Film trouvé → $movieUrl");
|
||||
|
||||
// Délai avant la 2ème requête
|
||||
sleep(2);
|
||||
|
||||
// Récupérer la page du film
|
||||
$ch2 = curl_init($movieUrl);
|
||||
curl_setopt_array($ch2, [
|
||||
@@ -455,28 +457,34 @@ function fetchFromBlurayCom($ean) {
|
||||
return $empty;
|
||||
}
|
||||
|
||||
// Extraction des données
|
||||
// Extraction des données - regex améliorées
|
||||
// Titre
|
||||
if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $movieHtml, $m)) {
|
||||
$rawTitle = trim(strip_tags($m[1]));
|
||||
$empty['title'] = trim(preg_replace('/\s*(Blu-ray|4K|3D|DVD|UHD).*$/i', '', $rawTitle));
|
||||
}
|
||||
|
||||
// Année
|
||||
if (preg_match('/href="[^"]*year=(\d{4})[^"]*"[^>]*>(\d{4})<\/a>/i', $movieHtml, $m)) {
|
||||
$empty['year'] = $m[1];
|
||||
}
|
||||
|
||||
// Studio/Éditeur
|
||||
if (preg_match('/href="[^"]*studioid=\d+[^"]*"[^>]*>([^<]+)<\/a>/i', $movieHtml, $m)) {
|
||||
$empty['publisher'] = trim($m[1]);
|
||||
}
|
||||
|
||||
// Durée
|
||||
if (preg_match('/<span[^>]*id="runtime"[^>]*>(\d+)\s*min<\/span>/i', $movieHtml, $m)) {
|
||||
$empty['length'] = $m[1] . ' min';
|
||||
}
|
||||
|
||||
// Aspect ratio
|
||||
if (preg_match('/Aspect[\s-]*ratio:\s*([\d\.]+:[\d\.]+)/i', $movieHtml, $m)) {
|
||||
$empty['aspect_ratio'] = trim($m[1]);
|
||||
}
|
||||
|
||||
// Nombre de disques - plusieurs patterns
|
||||
if (preg_match('/(\w+)-disc\s+set/i', $movieHtml, $m)) {
|
||||
$wordToNum = ['single' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5, 'six' => 6];
|
||||
$word = strtolower($m[1]);
|
||||
@@ -485,6 +493,7 @@ function fetchFromBlurayCom($ean) {
|
||||
$empty['number_of_discs'] = (int)$m[1];
|
||||
}
|
||||
|
||||
// Format
|
||||
if (strpos($movieUrl, '/4k/') !== false || stripos($movieHtml, '4K Ultra HD') !== false) {
|
||||
$empty['format'] = '4K Ultra HD';
|
||||
} elseif (strpos($movieUrl, '/3d/') !== false) {
|
||||
@@ -493,36 +502,42 @@ function fetchFromBlurayCom($ean) {
|
||||
$empty['format'] = 'Blu-ray';
|
||||
}
|
||||
|
||||
// Affiche HD
|
||||
// Affiche HD - plusieurs patterns
|
||||
if (preg_match('/src="(https:\/\/images\.static-bluray\.com\/movies\/covers\/\d+_front\.jpg[^"]*)"/i', $movieHtml, $m)) {
|
||||
$empty['poster'] = $m[1];
|
||||
} elseif (preg_match('/<img[^>]*class="coverfront"[^>]*src="([^"]+)"/i', $movieHtml, $m)) {
|
||||
$empty['poster'] = $m[1];
|
||||
$posterUrl = $m[1];
|
||||
$posterUrl = preg_replace('/_large\.jpg/', '_front.jpg', $posterUrl);
|
||||
$empty['poster'] = $posterUrl;
|
||||
}
|
||||
|
||||
// Synopsis, Réalisateur, Acteurs
|
||||
if (preg_match('/<div[^>]*id="movie_info"[^>]*>(.*?)<div[^>]*id="movie_review_intro"/is', $movieHtml, $infoBlock)) {
|
||||
$infoHtml = $infoBlock[1];
|
||||
|
||||
// Synopsis
|
||||
if (preg_match('/<\/center><br>\s*(.*?)<br><br><br>Director:/is', $infoHtml, $m)) {
|
||||
$synopsis = trim(strip_tags($m[1]));
|
||||
$synopsis = preg_replace('/\s+/', ' ', $synopsis);
|
||||
$empty['description'] = $synopsis;
|
||||
}
|
||||
|
||||
// Réalisateur
|
||||
if (preg_match('/Director:\s*<a[^>]*>([^<]+)<\/a>/i', $infoHtml, $m)) {
|
||||
$empty['director'] = trim($m[1]);
|
||||
}
|
||||
|
||||
// Acteurs
|
||||
if (preg_match('/Starring:\s*(.*?)(?:<br>|<\/div>)/is', $infoHtml, $m)) {
|
||||
preg_match_all('/<a[^>]*>([^<]+)<\/a>/i', $m[1], $actorMatches);
|
||||
$actorsHtml = $m[1];
|
||||
preg_match_all('/<a[^>]*>([^<]+)<\/a>/i', $actorsHtml, $actorMatches);
|
||||
if (!empty($actorMatches[1])) {
|
||||
$empty['actors'] = implode(', ', array_map('trim', array_slice($actorMatches[1], 0, 6)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_log("Blu-ray.com: ✅ Données récupérées → " . $empty['title']);
|
||||
error_log("Blu-ray.com: ✅ Données récupérées pour EAN $ean → " . $empty['title']);
|
||||
return $empty;
|
||||
}
|
||||
|
||||
@@ -534,6 +549,8 @@ function fetchFromMovieCovers($title, $year = '') {
|
||||
'aspect_ratio' => ''
|
||||
];
|
||||
|
||||
if (empty($title)) return $empty;
|
||||
|
||||
// Nettoyer le titre pour l'URL
|
||||
$urlTitle = strtoupper(str_replace(' ', '+', $title));
|
||||
$url = "https://moviecovers.com/film/titre_{$urlTitle}.html";
|
||||
@@ -546,13 +563,18 @@ function fetchFromMovieCovers($title, $year = '') {
|
||||
$empty['title'] = trim($m[1]);
|
||||
}
|
||||
|
||||
// Extraire l'affiche
|
||||
// Extraire l'affiche - plusieurs patterns
|
||||
if (preg_match('/<img[^>]*src="(https:\/\/moviecovers\.com\/DATA\/thumbs\/[^"]+)"[^>]*title="Recto/i', $html, $m)) {
|
||||
$empty['poster'] = $m[1];
|
||||
} elseif (preg_match('/<meta[^>]*property="og:image"[^>]*content="([^"]+)"/i', $html, $m)) {
|
||||
$empty['poster'] = $m[1];
|
||||
}
|
||||
|
||||
// Format haute qualité de l'affiche
|
||||
if ($empty['poster']) {
|
||||
$empty['poster'] = str_replace('/thumbs/', '/films-l/', $empty['poster']);
|
||||
}
|
||||
|
||||
// Extraire le réalisateur
|
||||
if (preg_match('/Réalisateur<\/TH>\s*<TD[^>]*>.*?<a[^>]*>([^<]+)<\/a>/is', $html, $m)) {
|
||||
$empty['director'] = trim($m[1]);
|
||||
@@ -578,11 +600,6 @@ function fetchFromMovieCovers($title, $year = '') {
|
||||
$empty['description'] = html_entity_decode($m[1]);
|
||||
}
|
||||
|
||||
// Format haute qualité de l'affiche
|
||||
if ($empty['poster']) {
|
||||
$empty['poster'] = str_replace('/thumbs/', '/films-l/', $empty['poster']);
|
||||
}
|
||||
|
||||
return $empty;
|
||||
}
|
||||
|
||||
@@ -725,109 +742,125 @@ case 'import_batch':
|
||||
$data = json_decode(file_get_contents("php://input"), true);
|
||||
$type = $data['type'] ?? '';
|
||||
$items = $data['items'] ?? [];
|
||||
|
||||
$pdo->beginTransaction();
|
||||
$imported = 0; $skipped = 0;
|
||||
try {
|
||||
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),
|
||||
poster=IF(VALUES(poster)!='assets/img/default_physical_media.jpg', VALUES(poster), poster),
|
||||
ean_isbn13=IF(VALUES(ean_isbn13)!='', VALUES(ean_isbn13), ean_isbn13),
|
||||
description=IF(VALUES(description)!='', VALUES(description), description),
|
||||
length=IF(VALUES(length)!='', VALUES(length), length),
|
||||
number_of_discs=IF(VALUES(number_of_discs)!=1, VALUES(number_of_discs), number_of_discs),
|
||||
aspect_ratio=IF(VALUES(aspect_ratio)!='', VALUES(aspect_ratio), aspect_ratio),
|
||||
actors=IF(VALUES(actors)!='', VALUES(actors), actors),
|
||||
publisher=IF(VALUES(publisher)!='', VALUES(publisher), publisher),
|
||||
director=IF(VALUES(director)!='', VALUES(director), director)");
|
||||
|
||||
foreach ($items as $item) {
|
||||
$csvTitle = trim($item['title'] ?? '');
|
||||
$ean = preg_replace('/[^0-9]/', '', (string)($item['ean'] ?? ''));
|
||||
|
||||
if (empty($csvTitle)) {
|
||||
error_log("Import: ❌ Pas de titre pour EAN $ean - ignoré");
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
error_log("Import: 🎬 Traitement de '$csvTitle' (EAN: $ean)");
|
||||
|
||||
// 1. Essayer Blu-ray.com (peut échouer sans bloquer)
|
||||
$blurayData = !empty($ean) ? fetchFromBlurayCom($ean) : [];
|
||||
|
||||
// 2. Utiliser le titre du CSV comme base
|
||||
$title = $csvTitle;
|
||||
$year = $blurayData['year'] ?? '';
|
||||
$format = $blurayData['format'] ?: detectFormat($title);
|
||||
$publisher = $blurayData['publisher'] ?? '';
|
||||
$discs = $blurayData['number_of_discs'] ?: 1;
|
||||
$aspect = $blurayData['aspect_ratio'] ?? '';
|
||||
$length = $blurayData['length'] ?? '';
|
||||
$poster = $blurayData['poster'] ?? '';
|
||||
$desc = $blurayData['description'] ?? '';
|
||||
$director = $blurayData['director'] ?? '';
|
||||
$actors = $blurayData['actors'] ?? '';
|
||||
|
||||
// 3. COMPLÉTER avec TMDB (toujours appelé pour garantir les données)
|
||||
error_log("Import: 🔄 Appel TMDB pour '$title'");
|
||||
$tmdb = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
|
||||
|
||||
// TMDB complète ce qui manque
|
||||
if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') {
|
||||
$poster = $tmdb['poster'];
|
||||
}
|
||||
if (empty($director)) $director = $tmdb['director'] ?? '';
|
||||
if (empty($actors)) $actors = $tmdb['actors'] ?? '';
|
||||
if (empty($desc)) $desc = $tmdb['description'] ?? '';
|
||||
if (empty($length) && !empty($tmdb['length'])) $length = $tmdb['length'];
|
||||
if (empty($year) && !empty($tmdb['year'])) $year = $tmdb['year'];
|
||||
|
||||
$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' (ID: $id)");
|
||||
}
|
||||
} else { // ── IMPORTATION CRITIQUES ──
|
||||
$stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
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)");
|
||||
|
||||
foreach ($items as $rowData) {
|
||||
$title = $rowData['Title'] ?? $rowData['title'] ?? '';
|
||||
if (empty($title)) continue;
|
||||
|
||||
$year = $rowData['Year'] ?? $rowData['year'] ?? '';
|
||||
$id = makeStableId('critique', $title, $year);
|
||||
|
||||
$ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? '';
|
||||
$rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null;
|
||||
$review = $rowData['Review'] ?? $rowData['review'] ?? '';
|
||||
$director = ''; $poster = 'assets/img/default_physical_media.jpg'; $streaming = 'Support physique / Cinéma';
|
||||
|
||||
// ── CORRECTION ICI : Utilisation de la bonne fonction TMDB ──
|
||||
$tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
|
||||
if ($tmdbData) {
|
||||
if (!empty($tmdbData['director'])) $director = $tmdbData['director'];
|
||||
if ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg') $poster = $tmdbData['poster'];
|
||||
if (empty($year) && !empty($tmdbData['year'])) $year = $tmdbData['year'];
|
||||
}
|
||||
|
||||
$stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]);
|
||||
$imported++;
|
||||
}
|
||||
}
|
||||
$pdo->commit();
|
||||
echo json_encode(["success" => true, "imported" => $imported, "skipped" => $skipped]);
|
||||
try {
|
||||
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),
|
||||
poster=IF(VALUES(poster)!='assets/img/default_physical_media.jpg', VALUES(poster), poster),
|
||||
ean_isbn13=IF(VALUES(ean_isbn13)!='', VALUES(ean_isbn13), ean_isbn13),
|
||||
description=IF(VALUES(description)!='', VALUES(description), description),
|
||||
length=IF(VALUES(length)!='', VALUES(length), length),
|
||||
number_of_discs=IF(VALUES(number_of_discs)!=1, VALUES(number_of_discs), number_of_discs),
|
||||
aspect_ratio=IF(VALUES(aspect_ratio)!='', VALUES(aspect_ratio), aspect_ratio),
|
||||
actors=IF(VALUES(actors)!='', VALUES(actors), actors),
|
||||
publisher=IF(VALUES(publisher)!='', VALUES(publisher), publisher),
|
||||
director=IF(VALUES(director)!='', VALUES(director), director)");
|
||||
|
||||
} catch (Throwable $e) { // ── CORRECTION ICI : Throwable capture les Crash Fatals PHP ──
|
||||
$pdo->rollBack();
|
||||
error_log("import_batch error: " . $e->getMessage());
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "error" => $e->getMessage(), "line" => $e->getLine()]);
|
||||
foreach ($items as $item) {
|
||||
$ean = preg_replace('/[^0-9]/', '', (string)($item['ean'] ?? ''));
|
||||
$csvTitle = trim($item['title'] ?? '');
|
||||
|
||||
if (strlen($ean) < 8 && empty($csvTitle)) {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Essayer Blu-ray.com (avec throttling)
|
||||
$blurayData = !empty($ean) ? fetchFromBlurayCom($ean) : [];
|
||||
|
||||
// 2. Si Blu-ray.com échoue, essayer MovieCovers avec le titre CSV
|
||||
if (empty($blurayData['title']) && !empty($csvTitle)) {
|
||||
error_log("Import: 🔄 Blu-ray.com échoué, essai MovieCovers pour '$csvTitle'");
|
||||
$blurayData = array_merge($blurayData, fetchFromMovieCovers($csvTitle, ''));
|
||||
}
|
||||
|
||||
// 3. Utiliser le titre trouvé ou le titre CSV
|
||||
$title = !empty($blurayData['title']) ? $blurayData['title'] : $csvTitle;
|
||||
|
||||
if (empty($title)) {
|
||||
error_log("Import: ❌ Pas de titre pour EAN $ean - ignoré");
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$year = $blurayData['year'] ?? '';
|
||||
$format = $blurayData['format'] ?: detectFormat($title);
|
||||
$publisher = $blurayData['publisher'] ?? '';
|
||||
$discs = $blurayData['number_of_discs'] ?: 1;
|
||||
$aspect = $blurayData['aspect_ratio'] ?? '';
|
||||
$length = $blurayData['length'] ?? '';
|
||||
$poster = $blurayData['poster'] ?? '';
|
||||
$desc = $blurayData['description'] ?? '';
|
||||
$director = $blurayData['director'] ?? '';
|
||||
$actors = $blurayData['actors'] ?? '';
|
||||
|
||||
// 4. Fallback TMDB si données manquantes
|
||||
if (empty($poster) || empty($director) || empty($actors) || empty($desc)) {
|
||||
error_log("Import: 🔄 Fallback TMDB pour '$title'");
|
||||
$tmdb = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
|
||||
|
||||
if (empty($poster) || $poster === 'assets/img/default_physical_media.jpg') {
|
||||
$poster = $tmdb['poster'];
|
||||
}
|
||||
if (empty($director)) $director = $tmdb['director'] ?? '';
|
||||
if (empty($actors)) $actors = $tmdb['actors'] ?? '';
|
||||
if (empty($desc)) $desc = $tmdb['description'] ?? '';
|
||||
if (empty($length) && !empty($tmdb['length'])) $length = $tmdb['length'];
|
||||
if (empty($year) && !empty($tmdb['year'])) $year = $tmdb['year'];
|
||||
}
|
||||
|
||||
$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) - Disques: $discs, Format: $format");
|
||||
}
|
||||
} else {
|
||||
// Import critiques (inchangé)
|
||||
$stmtCritiques = $pdo->prepare("INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
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)");
|
||||
|
||||
foreach ($items as $rowData) {
|
||||
$title = $rowData['Title'] ?? $rowData['title'] ?? '';
|
||||
if (empty($title)) continue;
|
||||
|
||||
$year = $rowData['Year'] ?? $rowData['year'] ?? '';
|
||||
$id = makeStableId('critique', $title, $year);
|
||||
$ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? '';
|
||||
$rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null;
|
||||
$review = $rowData['Review'] ?? $rowData['review'] ?? '';
|
||||
|
||||
$director = '';
|
||||
$poster = 'assets/img/default_physical_media.jpg';
|
||||
$streaming = 'Support physique / Cinéma';
|
||||
|
||||
$tmdbData = fetchTmdbPosterAndSynopsis($title, $year, $pdo);
|
||||
if ($tmdbData) {
|
||||
if (!empty($tmdbData['director'])) $director = $tmdbData['director'];
|
||||
if ($tmdbData['poster'] !== 'assets/img/default_physical_media.jpg') $poster = $tmdbData['poster'];
|
||||
if (empty($year) && !empty($tmdbData['year'])) $year = $tmdbData['year'];
|
||||
}
|
||||
|
||||
$stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]);
|
||||
$imported++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
$pdo->commit();
|
||||
echo json_encode(["success" => true, "imported" => $imported, "skipped" => $skipped]);
|
||||
|
||||
} catch (Throwable $e) {
|
||||
$pdo->rollBack();
|
||||
error_log("import_batch error: " . $e->getMessage());
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "error" => $e->getMessage(), "line" => $e->getLine()]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
Reference in New Issue
Block a user