Actualiser api.php

This commit is contained in:
2026-06-25 12:05:00 +02:00
parent cb148b4c58
commit 3364c5885c
+71 -74
View File
@@ -115,12 +115,13 @@ function extractYear($dateStr) {
return ''; return '';
} }
// ── DVDcover.com (avec validation du film) ── // ── DVDcover.com (avec vérification du titre) ──
function fetchDVDCover($title, $year = '', $format = 'bluray') { function fetchDVDCover($title, $year = '', $format = 'bluray') {
if (empty($title)) return null; 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'; $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); $cleanTitle = cleanTitle($title);
$cleanTitleLower = strtolower($cleanTitle);
// Mapping des formats // Mapping des formats
$formatMap = [ $formatMap = [
@@ -133,12 +134,12 @@ function fetchDVDCover($title, $year = '', $format = 'bluray') {
$dcFormat = $formatMap[strtolower($format)] ?? 'blu-ray'; $dcFormat = $formatMap[strtolower($format)] ?? 'blu-ray';
// Recherche plus spécifique avec titre + année // URL de recherche DVDcover
$searchUrl = "https://www.dvdcover.com/?s=" . urlencode($cleanTitle . " " . $year); $searchUrl = "https://www.dvdcover.com/?s=" . urlencode($cleanTitle);
$html = httpGet($searchUrl, 8, $ua); $html = httpGet($searchUrl, 8, $ua);
if (!$html) { if (!$html) {
error_log("DVDCover: Échec recherche pour '$title $year'"); error_log("DVDCover: Échec recherche pour '$title'");
return null; return null;
} }
@@ -148,15 +149,15 @@ function fetchDVDCover($title, $year = '', $format = 'bluray') {
'format' => $format, 'format' => $format,
]; ];
// Chercher tous les articles de covers // Chercher tous les articles/résultats
preg_match_all('/<article[^>]*id=["\']post-\d+["\'][^>]*>(.*?)<\/article>/is', $html, $articles); preg_match_all('/<article[^>]*>(.*?)<\/article>/is', $html, $articles);
if (!empty($articles[1])) { if (!empty($articles[1])) {
$bestMatch = null; $bestMatch = null;
$bestScore = 0; $bestScore = 0;
foreach ($articles[1] as $article) { foreach ($articles[1] as $article) {
// Extraire le lien vers la page du cover // Extraire le lien vers la page
if (!preg_match('/<a[^>]+href=["\']([^"\']+)["\'][^>]*>/i', $article, $linkMatch)) { if (!preg_match('/<a[^>]+href=["\']([^"\']+)["\'][^>]*>/i', $article, $linkMatch)) {
continue; continue;
} }
@@ -166,95 +167,91 @@ function fetchDVDCover($title, $year = '', $format = 'bluray') {
$coverPage = 'https://www.dvdcover.com' . $coverPage; $coverPage = 'https://www.dvdcover.com' . $coverPage;
} }
// Extraire le titre du cover depuis l'article // Extraire le titre de l'article
$articleTitle = ''; $pageTitle = '';
if (preg_match('/<h2[^>]*class=["\'][^"\']*entry-title[^"\']*["\'][^>]*>([^<]+)<\/h2>/i', $article, $titleMatch)) { if (preg_match('/<h2[^>]*class=["\'][^"\']*entry-title[^"\']*["\'][^>]*>([^<]+)<\/h2>/i', $article, $titleMatch)) {
$articleTitle = trim(strip_tags($titleMatch[1])); $pageTitle = trim(strip_tags($titleMatch[1]));
} elseif (preg_match('/title=["\']([^"\']+)["\']/i', $article, $titleMatch)) {
$pageTitle = trim($titleMatch[1]);
} }
// Calculer un score de correspondance if (empty($pageTitle)) continue;
$score = 0;
$articleTitleLower = strtolower($articleTitle);
$searchTitleLower = strtolower($cleanTitle);
// Le titre contient-il le film recherché ? // Calculer un score de correspondance
if (strpos($articleTitleLower, $searchTitleLower) !== false) { $pageTitleLower = strtolower($pageTitle);
$score += 50; $score = 0;
// Le titre recherché est-il dans le titre de la page ?
if (strpos($pageTitleLower, $cleanTitleLower) !== false) {
$score += 100;
} }
// L'année correspond-elle ? // L'année correspond-elle ?
if (!empty($year) && strpos($articleTitle, $year) !== false) { if (!empty($year) && strpos($pageTitle, $year) !== false) {
$score += 30; $score += 50;
} }
// Le format correspond-il ? // Le format correspond-il ?
if (stripos($articleTitle, $format) !== false || if (stripos($pageTitle, $format) !== false ||
stripos($articleTitle, $dcFormat) !== false) { ($format === 'Blu-ray' && stripos($pageTitle, 'bluray') !== false) ||
$score += 20; ($format === '4K Ultra HD' && (stripos($pageTitle, '4k') !== false || stripos($pageTitle, 'ultra') !== false))) {
$score += 25;
} }
// Si le score est trop bas, on ignore ce résultat // Si le score est suffisant, visiter la page
if ($score < 30) { if ($score >= 50) {
continue; $coverHtml = httpGet($coverPage, 8, $ua);
} if ($coverHtml) {
// Chercher l'image principale
// Récupérer la page du cover $poster = '';
$coverHtml = httpGet($coverPage, 8, $ua);
if (!$coverHtml) continue; // Méthode 1 : Chercher dans le contenu de l'article
if (preg_match('/<div[^>]*class=["\'][^"\']*entry-content[^"\']*["\'][^>]*>.*?<img[^>]+src=["\']([^"\']+\/wp-content\/uploads\/[^"\']+\.(?:jpg|jpeg|webp))["\'][^>]*>/is', $coverHtml, $imgMatch)) {
// Chercher l'image principale $poster = $imgMatch[1];
$poster = ''; }
// Méthode 2 : Chercher toutes les images uploads
// Méthode 1 : Image dans le contenu principal elseif (preg_match_all('/<img[^>]+src=["\']([^"\']+\/wp-content\/uploads\/[^"\']+\.(?:jpg|jpeg|webp))["\'][^>]*>/i', $coverHtml, $allImages)) {
if (preg_match('/<div[^>]*class=["\'][^"\']*entry-content[^"\']*["\'][^>]*>.*?<img[^>]+src=["\']([^"\']+\/wp-content\/uploads\/[^"\']+\.(?:jpg|jpeg|webp))["\'][^>]*>/is', $coverHtml, $imgMatch)) { foreach ($allImages[1] as $img) {
$poster = $imgMatch[1]; // Exclure les images non pertinentes
} if (strpos($img, 'logo') === false &&
strpos($img, 'icon') === false &&
// Méthode 2 : Image dans figure strpos($img, 'banner') === false &&
if (empty($poster) && preg_match('/<figure[^>]*>.*?<img[^>]+src=["\']([^"\']+\/wp-content\/uploads\/[^"\']+\.(?:jpg|jpeg|webp))["\'][^>]*>/is', $coverHtml, $imgMatch)) { strpos($img, 'bg') === false &&
$poster = $imgMatch[1]; strpos($img, 'button') === false &&
} strpos($img, 'sidebar') === false) {
$poster = $img;
// Méthode 3 : Première image valide break;
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) {
if (strpos($img, 'logo') === false && if (!empty($poster)) {
strpos($img, 'icon') === false && // Extraire le titre de la page
strpos($img, 'banner') === false && $finalTitle = '';
strpos($img, 'bg') === false && if (preg_match('/<h1[^>]*class=["\'][^"\']*entry-title[^"\']*["\'][^>]*>([^<]+)<\/h1>/i', $coverHtml, $titleMatch)) {
strpos($img, 'button') === false && $finalTitle = trim(strip_tags($titleMatch[1]));
strpos($img, '300x200') === false && // Éviter les miniatures }
strpos($img, '150x150') === false) {
$poster = $img; // Garder le meilleur résultat
break; if ($score > $bestScore) {
$bestScore = $score;
$bestMatch = [
'poster' => $poster,
'title' => $finalTitle ?: $pageTitle,
'format' => $format,
];
} }
} }
}
}
// Si on a une image et un bon score, on la garde
if (!empty($poster) && $score > $bestScore) {
$bestScore = $score;
$bestMatch = [
'poster' => $poster,
'title' => $articleTitle,
];
// Si score parfait, on arrête tout de suite
if ($score >= 100) {
break;
} }
} }
} }
if ($bestMatch) { if ($bestMatch) {
$result = $bestMatch; return $bestMatch;
} }
} }
return (!empty($result['poster'])) ? $result : null; return null;
} }
// ── API TMDB (uniquement pour les critiques) ── // ── API TMDB (uniquement pour les critiques) ──