diff --git a/api.php b/api.php index b24c484..7d02780 100644 --- a/api.php +++ b/api.php @@ -120,50 +120,42 @@ function extractYear($dateStr) { return ''; } -// ── Fanart.tv API (Jaquettes exclusives) ── +// ── 1. Fonction Fanart.tv EXCLUSIVE (Aucune jaquette TMDB ou OpenLibrary) ── function fetchFanartTv($title, $year = '', $format = 'bluray', $pdo = null) { - if (empty($title)) return null; - + // Image locale par défaut si aucun résultat + $defaultPoster = 'assets/img/default_physical_media.jpg'; $cleanTitle = cleanTitle($title); - if (empty($cleanTitle)) return null; - // Récupérer la clé API fanart.tv - $apiKey = '70f9747dafe9b27f9b14ef80ee0cacc9'; // Clé par défaut + if (empty($cleanTitle)) return ['poster' => $defaultPoster, 'title' => $title, 'format' => $format]; + + // Récupération des clés API + $apiKey = '70f9747dafe9b27f9b14ef80ee0cacc9'; if ($pdo) { $stmt = $pdo->prepare("SELECT key_value FROM config WHERE key_name = 'fanart_api_key'"); $stmt->execute(); $row = $stmt->fetch(); - if ($row) { - $apiKey = decryptData($row['key_value']); - } + if ($row) $apiKey = decryptData($row['key_value']); } - // 1. Récupération silencieuse de l'ID via TMDB $tmdbKey = getTmdbApiKey($pdo); - if (!$tmdbKey) { - error_log("Fanart.tv: Clé TMDB requise"); - return null; - } + if (!$tmdbKey) return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => $format]; + // Étape A : Obtenir l'ID TMDB (Recherche silencieuse) $searchUrl = "https://api.themoviedb.org/3/search/movie?api_key={$tmdbKey}&query=" . urlencode($cleanTitle); - if (!empty($year)) { - $searchUrl .= "&year={$year}"; - } + if (!empty($year)) $searchUrl .= "&year={$year}"; $searchUrl .= "&language=fr-FR"; $searchRes = httpGet($searchUrl, 5); $searchData = $searchRes ? json_decode($searchRes, true) : []; if (empty($searchData['results'])) { - error_log("Fanart.tv: Film non trouvé sur TMDB pour '$title'"); - // Verrouillage : TMDB ne le trouve pas, on force l'image par défaut - return ['poster' => 'assets/img/default_physical_media.jpg', 'title' => $cleanTitle, 'format' => $format]; + return ['poster' => $defaultPoster, 'title' => $cleanTitle, 'format' => $format]; } $tmdbId = $searchData['results'][0]['id']; - $poster = null; // Initialisation stricte + $poster = null; - // 2. Interrogation exclusive de Fanart.tv avec l'ID obtenu + // Étape B : Interrogation stricte de Fanart.tv $fanartUrl = "https://webservice.fanart.tv/v3/movies/{$tmdbId}?api_key={$apiKey}"; $fanartRes = httpGet($fanartUrl, 5); $fanartData = $fanartRes ? json_decode($fanartRes, true) : []; @@ -171,14 +163,14 @@ function fetchFanartTv($title, $year = '', $format = 'bluray', $pdo = null) { if (!isset($fanartData['error']) && !empty($fanartData['movieposter'])) { $posters = $fanartData['movieposter']; - // PRIORITÉ 1 : Français + // Priorité 1 : Langue Française $frenchPosters = array_filter($posters, function($p) { return isset($p['lang']) && $p['lang'] === 'fr'; }); if (!empty($frenchPosters)) { usort($frenchPosters, function($a, $b) { return ($b['likes'] ?? 0) - ($a['likes'] ?? 0); }); $poster = $frenchPosters[0]['url']; } - // PRIORITÉ 2 : Anglais (fallback) + // Priorité 2 : Langue Anglaise if (empty($poster)) { $englishPosters = array_filter($posters, function($p) { return isset($p['lang']) && $p['lang'] === 'en'; }); if (!empty($englishPosters)) { @@ -187,18 +179,15 @@ function fetchFanartTv($title, $year = '', $format = 'bluray', $pdo = null) { } } - // PRIORITÉ 3 : N'importe quelle langue + // Priorité 3 : N'importe quelle jaquette dispo if (empty($poster)) { usort($posters, function($a, $b) { return ($b['likes'] ?? 0) - ($a['likes'] ?? 0); }); $poster = $posters[0]['url']; } } - // 3. Verrouillage final if (empty($poster)) { - error_log("Fanart.tv: Aucune jaquette trouvée pour TMDB ID {$tmdbId}"); - // AUCUN retour vers TMDB, on force l'image locale - $poster = 'assets/img/default_physical_media.jpg'; + $poster = $defaultPoster; } return [ @@ -497,98 +486,33 @@ case 'get_config_keys': break; case 'import_batch': - checkAuth($pdo); - set_time_limit(0); - $items = $data['items'] ?? []; - $type = $data['type'] ?? 'videotheque'; - $tmdbApiKey = getTmdbApiKey($pdo); - $imported = 0; - $debugLog = []; - - $pdo->beginTransaction(); - try { - $sqlVideotheque = "INSERT INTO videotheque (id, title, year, director, poster, format, length, publisher, ean_isbn13, number_of_discs, aspect_ratio, description, actors) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ON DUPLICATE KEY UPDATE - title=VALUES(title), year=VALUES(year), - director=IF(VALUES(director)!='',VALUES(director),director), - poster=IF(VALUES(poster)!='',VALUES(poster),poster), - format=IF(VALUES(format)!='',VALUES(format),format), - length=IF(VALUES(length)!='',VALUES(length),length), - publisher=IF(VALUES(publisher)!='',VALUES(publisher),publisher), - ean_isbn13=IF(VALUES(ean_isbn13)!='',VALUES(ean_isbn13),ean_isbn13), - 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), - description=IF(VALUES(description)!='',VALUES(description),description), - actors=IF(VALUES(actors)!='',VALUES(actors),actors)"; - $stmtVideotheque = $pdo->prepare($sqlVideotheque); - - $sqlCritiques = "INSERT INTO critiques (id, title, year, director, poster, rating, review, streaming) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON DUPLICATE KEY UPDATE - title=VALUES(title), year=VALUES(year), - rating=VALUES(rating), - review=IF(VALUES(review)!='',VALUES(review),review), - director=IF(VALUES(director)!='',VALUES(director),director), - poster=IF(VALUES(poster)!='',VALUES(poster),poster), - streaming=IF(VALUES(streaming)!='',VALUES(streaming),streaming)"; - $stmtCritiques = $pdo->prepare($sqlCritiques); - - foreach ($items as $rowData) { - $title = $rowData['title'] ?? $rowData['Name'] ?? $rowData['Title'] ?? 'Sans titre'; - $publishDate = $rowData['publish_date'] ?? $rowData['Year'] ?? $rowData['year'] ?? $rowData['Date'] ?? ''; - $year = extractYear($publishDate); - $id = makeStableId($type, $title, $year); - - if ($type === 'videotheque') { - $csvActors = $rowData['ensemble'] ?? $rowData['creators'] ?? ''; - $actors = ''; - if (!empty($csvActors)) { - $actorsArray = array_map('trim', explode(',', $csvActors)); - $actors = implode(', ', array_slice($actorsArray, 0, 4)); - } - - $ean = $rowData['ean_isbn13'] ?? $rowData['EAN'] ?? ''; - if (!empty($ean)) { - $eanFloat = floatval($ean); - if ($eanFloat > 0) $ean = (string) round($eanFloat); - $ean = preg_replace('/[^0-9]/', '', $ean); - } - - $lengthRaw = $rowData['length'] ?? ''; - $length = ''; - if ($lengthRaw !== '' && $lengthRaw !== null) { - $lengthVal = floatval($lengthRaw); - if ($lengthVal > 0) $length = (string) round($lengthVal); - } - - $discsRaw = $rowData['number_of_discs'] ?? ''; - $discs = (is_numeric($discsRaw) && floatval($discsRaw) > 0) ? (int) round(floatval($discsRaw)) : 1; - - $description = $rowData['description'] ?? $rowData['Description'] ?? ''; - $publisher = $rowData['publisher'] ?? ''; - $aspect = $rowData['aspect_ratio'] ?? ''; - $format = $rowData['format'] ?? detectFormat($title, $description); - $poster = $rowData['poster'] ?? ''; - $director = ''; - - // Récupération jaquette via DVDCover API - $cleanTitleForDC = cleanTitle($title); - if (!empty($cleanTitleForDC)) { - $fanartData = fetchFanartTv($cleanTitleForDC, $year, $format, $pdo); - if (!empty($fanartData)) { - if (!empty($fanartData['poster'])) { - $poster = $fanartData['poster']; - } - if (!empty($fanartData['title']) && ($title === 'Sans titre' || empty($title))) { - $title = $fanartData['title']; - } - } - } - - $stmtVideotheque->execute([$id, $title, $year, $director, $poster, $format, $length, $publisher, $ean, $discs, $aspect, $description, $actors]); - - } else { + checkAuth($pdo); + $data = json_decode(file_get_contents("php://input"), true); + $type = $data['type'] ?? 'critique'; + $items = $data['items'] ?? []; + + $pdo->beginTransaction(); + $imported = 0; + + if ($type === 'videotheque') { + $stmtVideo = $pdo->prepare("INSERT INTO videotheque (id, title, year, format, poster, ean_isbn13, description) VALUES (?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE ean_isbn13 = ?, poster = ?, description = ?"); + + foreach ($items as $item) { + $title = $item['title'] ?? ''; + if (empty($title)) continue; + + $year = $item['year'] ?? ''; + $ean = $item['ean'] ?? ''; + $desc = $item['description'] ?? ''; + + $id = makeStableId('videotheque', $title, $year); + $fanartData = fetchFanartTv($title, $year, 'Blu-ray', $pdo); + $poster = $fanartData['poster']; + + $stmtVideo->execute([$id, $title, $year, 'Blu-ray', $poster, $ean, $desc, $ean, $poster, $desc]); + $imported++; + } + } else { $ratingRaw = $rowData['Rating'] ?? $rowData['rating'] ?? ''; $rating = ($ratingRaw !== '' && $ratingRaw !== null) ? (float)$ratingRaw : null; $review = $rowData['Review'] ?? $rowData['review'] ?? ''; @@ -609,19 +533,9 @@ case 'get_config_keys': $stmtCritiques->execute([$id, $title, $year, $director, $poster, $rating, $review, $streaming]); } $imported++; - } - $pdo->commit(); - echo json_encode(["success" => true, "imported" => $imported, "debug" => $debugLog]); - - } catch (\Throwable $e) { - if ($pdo->inTransaction()) { - $pdo->rollBack(); - } - http_response_code(500); - echo json_encode(["success" => false, "error" => "Erreur serveur : " . $e->getMessage(), "debug" => $debugLog]); - } - break; + echo json_encode(["success" => true, "imported" => $imported]); + break; case 'debug_fanart': $title = $_GET['title'] ?? '';