Actualiser api.php
This commit is contained in:
@@ -115,33 +115,19 @@ function extractYear($dateStr) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// ── NOUVEAU SCRAPER : DVDFr (Version corrigée avec débogage) ──
|
||||
function fetchDVDFrCover($title, $year = '', $format = 'bluray') {
|
||||
// ── DVDCover.com Scraper ──
|
||||
function fetchDVDCover($title, $year = '', $format = 'bluray') {
|
||||
if (empty($title)) return null;
|
||||
|
||||
$ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||||
$cleanTitle = cleanTitle($title);
|
||||
|
||||
// Essayer différentes URLs de recherche
|
||||
$searchUrls = [
|
||||
"https://www.dvdfr.com/search?q=" . urlencode($cleanTitle),
|
||||
"https://www.dvdfr.com/dvd/recherche.html?search=" . urlencode($cleanTitle),
|
||||
"https://www.dvdfr.com/catalogue/recherche?query=" . urlencode($cleanTitle),
|
||||
];
|
||||
|
||||
$html = null;
|
||||
$usedUrl = '';
|
||||
|
||||
foreach ($searchUrls as $url) {
|
||||
$html = httpGet($url, 10, $ua);
|
||||
if ($html && strlen($html) > 1000) {
|
||||
$usedUrl = $url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// URL de recherche DVDCover
|
||||
$searchUrl = "https://www.dvdcover.com/?s=" . urlencode($cleanTitle);
|
||||
|
||||
$html = httpGet($searchUrl, 8, $ua);
|
||||
if (!$html) {
|
||||
error_log("DVDFr: Impossible de récupérer la page de recherche pour '$title'");
|
||||
error_log("DVDCover: Échec recherche pour '$title'");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -149,101 +135,87 @@ function fetchDVDFrCover($title, $year = '', $format = 'bluray') {
|
||||
'poster' => '',
|
||||
'title' => '',
|
||||
'format' => $format,
|
||||
'debug_url' => $usedUrl,
|
||||
];
|
||||
|
||||
// Méthode 1 : Chercher les liens vers les fiches produits (pattern /dvd/f ou /dvd/ suivi de chiffres)
|
||||
$ficheUrl = '';
|
||||
if (preg_match('/href=["\']([^"\']*\/dvd\/f?\d+[^"\']*\.html)["\']/i', $html, $matches)) {
|
||||
$ficheUrl = $matches[1];
|
||||
if (strpos($ficheUrl, 'http') !== 0) {
|
||||
$ficheUrl = 'https://www.dvdfr.com' . $ficheUrl;
|
||||
}
|
||||
}
|
||||
// DVDCover est un site WordPress - les articles ont la classe "post"
|
||||
// Chercher les liens vers les pages individuelles de covers
|
||||
preg_match_all('/<article[^>]*class=["\'][^"\']*post[^"\']*["\'][^>]*>.*?<a[^>]+href=["\']([^"\']+)["\'][^>]*>.*?<\/article>/is', $html, $articles);
|
||||
|
||||
// Méthode 2 : Chercher dans les données JSON-LD ou scripts
|
||||
if (empty($ficheUrl) && preg_match('/"url"\s*:\s*"([^"]*\/dvd\/[^"]+)"/i', $html, $matches)) {
|
||||
$ficheUrl = $matches[1];
|
||||
if (strpos($ficheUrl, 'http') !== 0) {
|
||||
$ficheUrl = 'https://www.dvdfr.com' . $ficheUrl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($ficheUrl)) {
|
||||
error_log("DVDFr: Fiche trouvée - $ficheUrl");
|
||||
$ficheHtml = httpGet($ficheUrl, 10, $ua);
|
||||
|
||||
if ($ficheHtml) {
|
||||
// Extraire le titre
|
||||
if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $ficheHtml, $titleMatch)) {
|
||||
$result['title'] = trim(strip_tags($titleMatch[1]));
|
||||
} elseif (preg_match('/<title[^>]*>([^<]+)<\/title>/i', $ficheHtml, $titleMatch)) {
|
||||
$result['title'] = trim(strip_tags($titleMatch[1]));
|
||||
if (!empty($articles[1])) {
|
||||
foreach ($articles[1] as $coverPage) {
|
||||
if (strpos($coverPage, 'http') !== 0) {
|
||||
$coverPage = 'https://www.dvdcover.com' . $coverPage;
|
||||
}
|
||||
|
||||
// Chercher les images de jaquettes
|
||||
// Pattern 1 : Images dans /images/dvd/ ou /covers/
|
||||
if (preg_match_all('/src=["\']([^"\']*(?:\/images\/dvd\/|\/covers\/|cover|jaquette)[^"\']*\.(?:jpg|jpeg|png|webp))["\']/i', $ficheHtml, $imgMatches)) {
|
||||
foreach ($imgMatches[1] as $img) {
|
||||
if (strpos($img, 'logo') === false &&
|
||||
strpos($img, 'icon') === false &&
|
||||
strpos($img, 'stars') === false &&
|
||||
strpos($img, 'bg-') === false) {
|
||||
$coverHtml = httpGet($coverPage, 8, $ua);
|
||||
if (!$coverHtml) continue;
|
||||
|
||||
$imgUrl = strpos($img, 'http') === 0 ? $img : 'https://www.dvdfr.com' . (strpos($img, '/') === 0 ? '' : '/') . ltrim($img, '/');
|
||||
// Extraire le titre du cover
|
||||
$coverTitle = '';
|
||||
if (preg_match('/<h1[^>]*class=["\'][^"\']*entry-title[^"\']*["\'][^>]*>([^<]+)<\/h1>/i', $coverHtml, $titleMatch)) {
|
||||
$coverTitle = trim(strip_tags($titleMatch[1]));
|
||||
} elseif (preg_match('/<title[^>]*>([^<]+)<\/title>/i', $coverHtml, $titleMatch)) {
|
||||
$coverTitle = trim(strip_tags($titleMatch[1]));
|
||||
}
|
||||
|
||||
// Supprimer les suffixes de taille pour avoir la HD
|
||||
$imgUrl = preg_replace('/[_-](?:small|medium|thumb|mini|s|m|t)\./i', '.', $imgUrl);
|
||||
// Vérifier que le titre correspond au film recherché
|
||||
$coverTitleLower = strtolower($coverTitle);
|
||||
$searchTitleLower = strtolower($cleanTitle);
|
||||
|
||||
$result['poster'] = $imgUrl;
|
||||
break;
|
||||
// Score de correspondance
|
||||
$score = 0;
|
||||
if (strpos($coverTitleLower, $searchTitleLower) !== false) {
|
||||
$score += 50;
|
||||
}
|
||||
if (!empty($year) && strpos($coverTitle, $year) !== false) {
|
||||
$score += 30;
|
||||
}
|
||||
if (stripos($coverTitle, $format) !== false) {
|
||||
$score += 20;
|
||||
}
|
||||
|
||||
// Si le score est trop bas, on ignore ce résultat
|
||||
if ($score < 30) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Chercher l'image principale dans le contenu
|
||||
$poster = '';
|
||||
|
||||
// Méthode 1 : Image dans entry-content
|
||||
if (preg_match('/<div[^>]*class=["\'][^"\']*entry-content[^"\']*["\'][^>]*>.*?<img[^>]+src=["\']([^"\']+)["\'][^>]*>/is', $coverHtml, $imgMatch)) {
|
||||
$poster = $imgMatch[1];
|
||||
}
|
||||
|
||||
// Méthode 2 : Image dans figure
|
||||
if (empty($poster) && preg_match('/<figure[^>]*>.*?<img[^>]+src=["\']([^"\']+)["\'][^>]*>/is', $coverHtml, $imgMatch)) {
|
||||
$poster = $imgMatch[1];
|
||||
}
|
||||
|
||||
// Méthode 3 : Chercher toutes les images et prendre la première valide
|
||||
if (empty($poster)) {
|
||||
preg_match_all('/<img[^>]+src=["\']([^"\']+\/wp-content\/uploads\/[^"\']+\.(?:jpg|jpeg|webp))["\'][^>]*>/i', $coverHtml, $allImages);
|
||||
if (!empty($allImages[1])) {
|
||||
foreach ($allImages[1] as $img) {
|
||||
// Exclure les images de thème, logos, etc.
|
||||
if (strpos($img, 'logo') === false &&
|
||||
strpos($img, 'icon') === false &&
|
||||
strpos($img, 'banner') === false &&
|
||||
strpos($img, 'bg') === false &&
|
||||
strpos($img, 'button') === false &&
|
||||
strpos($img, '300x200') === false &&
|
||||
strpos($img, '150x150') === false) {
|
||||
$poster = $img;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pattern 2 : Meta Open Graph
|
||||
if (empty($result['poster']) && preg_match('/<meta[^>]+property=["\']og:image["\'][^>]+content=["\']([^"\']+)["\']/i', $ficheHtml, $ogMatch)) {
|
||||
$result['poster'] = $ogMatch[1];
|
||||
}
|
||||
|
||||
// Pattern 3 : Chercher toutes les images et filtrer
|
||||
if (empty($result['poster'])) {
|
||||
preg_match_all('/<img[^>]+src=["\']([^"\']+\.(?:jpg|jpeg|png|webp))["\'][^>]*>/i', $ficheHtml, $allImages);
|
||||
foreach ($allImages[1] as $img) {
|
||||
$imgLower = strtolower($img);
|
||||
if (strpos($imgLower, 'dvdfr.com') !== false &&
|
||||
strpos($imgLower, 'logo') === false &&
|
||||
strpos($imgLower, 'icon') === false &&
|
||||
strpos($imgLower, 'banner') === false &&
|
||||
strpos($imgLower, 'bg') === false &&
|
||||
strpos($imgLower, 'button') === false &&
|
||||
strpos($imgLower, 'social') === false) {
|
||||
|
||||
$imgUrl = strpos($img, 'http') === 0 ? $img : 'https://www.dvdfr.com' . (strpos($img, '/') === 0 ? '' : '/') . ltrim($img, '/');
|
||||
$imgUrl = preg_replace('/[_-](?:small|medium|thumb|mini|s|m|t)\./i', '.', $imgUrl);
|
||||
|
||||
$result['poster'] = $imgUrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback : chercher directement dans la page de recherche
|
||||
if (empty($result['poster'])) {
|
||||
preg_match_all('/src=["\']([^"\']+\.(?:jpg|jpeg|png|webp))["\']/i', $html, $searchImages);
|
||||
foreach ($searchImages[1] as $img) {
|
||||
$imgLower = strtolower($img);
|
||||
if (strpos($imgLower, 'dvdfr.com') !== false &&
|
||||
(strpos($imgLower, 'dvd') !== false || strpos($imgLower, 'cover') !== false) &&
|
||||
strpos($imgLower, 'logo') === false &&
|
||||
strpos($imgLower, 'icon') === false) {
|
||||
|
||||
$imgUrl = strpos($img, 'http') === 0 ? $img : 'https://www.dvdfr.com' . (strpos($img, '/') === 0 ? '' : '/') . ltrim($img, '/');
|
||||
$imgUrl = preg_replace('/[_-](?:small|medium|thumb|mini|s|m|t)\./i', '.', $imgUrl);
|
||||
|
||||
$result['poster'] = $imgUrl;
|
||||
// Si on a une image valide, on la garde
|
||||
if (!empty($poster)) {
|
||||
$result['poster'] = $poster;
|
||||
$result['title'] = $coverTitle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -387,7 +359,6 @@ switch ($action) {
|
||||
";
|
||||
$result = $pdo->query($sql)->fetchAll();
|
||||
|
||||
// Formatage des notes : suppression du .0 pour les comptes ronds
|
||||
foreach ($result as $row) {
|
||||
if ($row['rating'] !== null) {
|
||||
$ratingVal = (float)$row['rating'];
|
||||
@@ -431,9 +402,9 @@ switch ($action) {
|
||||
}
|
||||
|
||||
if ($type === 'videotheque') {
|
||||
// DVDFr pour vidéothèque
|
||||
// DVDCover pour vidéothèque
|
||||
$format = $result['format'] ?: 'Blu-ray';
|
||||
$dcData = fetchDVDFrCover($titleForSearch, $result['year'], $format);
|
||||
$dcData = fetchDVDCover($titleForSearch, $result['year'], $format);
|
||||
if (!empty($dcData)) {
|
||||
if (!empty($dcData['poster'])) $result['poster'] = $dcData['poster'];
|
||||
if (!empty($dcData['title'])) $result['title'] = $dcData['title'];
|
||||
@@ -477,10 +448,10 @@ switch ($action) {
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$id, $data['title'] ?? '', $data['year'] ?? '', $data['director'] ?? '', $data['poster'] ?? '', $data['rating'] ?? 3.0, $data['review'] ?? '', $streaming]);
|
||||
} else {
|
||||
// Vidéothèque : DVDFr pour la jaquette
|
||||
// Vidéothèque : DVDCover pour la jaquette
|
||||
if (empty($data['poster']) && !empty($data['title'])) {
|
||||
$format = $data['format'] ?: 'Blu-ray';
|
||||
$dcData = fetchDVDFrCover($data['title'], $data['year'] ?? '', $format);
|
||||
$dcData = fetchDVDCover($data['title'], $data['year'] ?? '', $format);
|
||||
if (!empty($dcData['poster'])) {
|
||||
$data['poster'] = $dcData['poster'];
|
||||
}
|
||||
@@ -527,7 +498,6 @@ switch ($action) {
|
||||
$id = makeStableId($type, $title, $year);
|
||||
|
||||
if ($type === 'videotheque') {
|
||||
// ── VIDÉOTHÈQUE : DVDFr pour jaquette ──
|
||||
$csvActors = $rowData['ensemble'] ?? $rowData['creators'] ?? '';
|
||||
$actors = '';
|
||||
if (!empty($csvActors)) {
|
||||
@@ -559,10 +529,10 @@ switch ($action) {
|
||||
$poster = $rowData['poster'] ?? '';
|
||||
$director = '';
|
||||
|
||||
// Récupération jaquette via DVDFr
|
||||
// Récupération jaquette via DVDCover
|
||||
$cleanTitleForDC = cleanTitle($title);
|
||||
if (!empty($cleanTitleForDC)) {
|
||||
$dcData = fetchDVDFrCover($cleanTitleForDC, $year, $format);
|
||||
$dcData = fetchDVDCover($cleanTitleForDC, $year, $format);
|
||||
if (!empty($dcData)) {
|
||||
if (!empty($dcData['poster'])) {
|
||||
$poster = $dcData['poster'];
|
||||
@@ -591,7 +561,6 @@ switch ($action) {
|
||||
$stmt->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $description, $actors]);
|
||||
|
||||
} else {
|
||||
// ── CRITIQUES : TMDB ──
|
||||
$ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? '';
|
||||
$rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null;
|
||||
$review = $rowData['Review'] ?? $rowData['review'] ?? '';
|
||||
@@ -636,7 +605,7 @@ switch ($action) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'debug_scraper':
|
||||
case 'debug_dvdcover':
|
||||
$title = $_GET['title'] ?? '';
|
||||
$year = $_GET['year'] ?? '';
|
||||
$format = $_GET['format'] ?? 'Blu-ray';
|
||||
@@ -644,7 +613,7 @@ switch ($action) {
|
||||
if (!$title) { echo json_encode(['error' => 'Titre manquant']); exit; }
|
||||
|
||||
$result = ['title' => $title, 'year' => $year, 'format' => $format];
|
||||
$data = fetchDVDFrCover($title, $year, $format);
|
||||
$data = fetchDVDCover($title, $year, $format);
|
||||
$result['data'] = $data;
|
||||
$result['status'] = $data ? 'OK' : 'AUCUN_RÉSULTAT';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user