refactor: split config.php into modules and lazy-load categories
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Intégration Funkwhale : récupération de morceaux aléatoires via l'API.
|
||||
*
|
||||
* Extrait de includes/config.php (ARC-1) — chargé par ce dernier.
|
||||
* Dépend de lib/http.php (client cURL) et lib/format.php (formatDuration).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Récupère des morceaux aléatoires depuis Funkwhale via l'API
|
||||
*
|
||||
* @param string $funkwhaleUrl URL de l'instance Funkwhale
|
||||
* @param int $count Nombre de morceaux à récupérer
|
||||
* @return array Liste des morceaux formatés
|
||||
*/
|
||||
function getFunkwhaleTracks($funkwhaleUrl = null, $count = null) {
|
||||
if (!defined('FUNKWHALE_ENABLED') || !FUNKWHALE_ENABLED) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$funkwhaleUrl = $funkwhaleUrl ?? FUNKWHALE_URL;
|
||||
$count = $count ?? FUNKWHALE_TRACKS_COUNT;
|
||||
|
||||
// Validation de l'URL Funkwhale pour prévenir SSRF
|
||||
if (!isValidRemoteUrl($funkwhaleUrl)) {
|
||||
error_log('SECURITY: Invalid Funkwhale URL detected: ' . $funkwhaleUrl);
|
||||
return [];
|
||||
}
|
||||
|
||||
// Clé de cache - on récupère un grand nombre de morceaux pour le cache
|
||||
$cacheKey = 'funkwhale_' . md5($funkwhaleUrl);
|
||||
$cacheFetchSize = 50; // Nombre de morceaux à mettre en cache
|
||||
|
||||
// Vérifier le cache
|
||||
$allTracks = null;
|
||||
if (defined('CACHE_ENABLED') && CACHE_ENABLED) {
|
||||
$allTracks = getFromCache($cacheKey);
|
||||
}
|
||||
|
||||
// Si pas de cache, récupérer depuis l'API
|
||||
if ($allTracks === null) {
|
||||
try {
|
||||
// Construire l'URL de l'API en ordre aléatoire ; le filtrage local
|
||||
// est fait ensuite côté PHP (comparaison de domaine)
|
||||
$apiUrl = rtrim($funkwhaleUrl, '/') . '/api/v1/tracks?ordering=random&page_size=' . $cacheFetchSize . '&scope=all';
|
||||
|
||||
// Récupérer les morceaux
|
||||
$response = httpGet($apiUrl, ['timeout' => 10]);
|
||||
$jsonContent = $response['body'];
|
||||
|
||||
if ($response['code'] !== 200 || !$jsonContent) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Parser le JSON
|
||||
$data = json_decode($jsonContent, true);
|
||||
if (!$data || !isset($data['results'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allTracks = [];
|
||||
|
||||
// Extraire le domaine de l'instance locale pour filtrer
|
||||
$localDomain = parse_url($funkwhaleUrl, PHP_URL_HOST);
|
||||
|
||||
// Parcourir les morceaux et filtrer pour garder uniquement les morceaux locaux
|
||||
foreach ($data['results'] as $item) {
|
||||
// Vérifier si le morceau est local en comparant le domaine
|
||||
// Les morceaux fédérés ont généralement un domaine différent dans leur URL
|
||||
$isLocal = true;
|
||||
|
||||
// Vérifier via l'URL de l'artiste ou de l'album
|
||||
if (isset($item['artist']['channel'])) {
|
||||
$artistDomain = parse_url($item['artist']['channel'], PHP_URL_HOST);
|
||||
if ($artistDomain && $artistDomain !== $localDomain) {
|
||||
$isLocal = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Ou vérifier via le champ is_local si disponible
|
||||
if (isset($item['is_local']) && !$item['is_local']) {
|
||||
$isLocal = false;
|
||||
}
|
||||
|
||||
// Ne garder que les morceaux locaux
|
||||
if ($isLocal) {
|
||||
// Récupérer l'URL d'écoute depuis l'API (peut être relative)
|
||||
$listenUrl = $item['listen_url'] ?? '';
|
||||
|
||||
// Si l'URL est relative, la transformer en URL absolue
|
||||
if (!empty($listenUrl) && strpos($listenUrl, 'http') !== 0) {
|
||||
$listenUrl = rtrim($funkwhaleUrl, '/') . $listenUrl;
|
||||
}
|
||||
|
||||
$track = [
|
||||
'title' => $item['title'] ?? '',
|
||||
'artist' => $item['artist']['name'] ?? 'Artiste inconnu',
|
||||
'album' => $item['album']['title'] ?? '',
|
||||
'cover' => $item['album']['cover']['urls']['medium_square_crop'] ?? '',
|
||||
'duration' => $item['uploads'][0]['duration'] ?? 0,
|
||||
'link' => rtrim($funkwhaleUrl, '/') . '/library/tracks/' . ($item['id'] ?? ''),
|
||||
'trackId' => $item['id'] ?? 0,
|
||||
'audioUrl' => $listenUrl,
|
||||
];
|
||||
|
||||
// Formater la durée
|
||||
if ($track['duration']) {
|
||||
$track['formattedDuration'] = formatDuration($track['duration']);
|
||||
} else {
|
||||
$track['formattedDuration'] = '';
|
||||
}
|
||||
|
||||
$allTracks[] = $track;
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre en cache tous les morceaux locaux
|
||||
if (defined('CACHE_ENABLED') && CACHE_ENABLED) {
|
||||
saveToCache($cacheKey, $allTracks);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log('Erreur lors de la récupération des morceaux Funkwhale: ' . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Si pas assez de morceaux, retourner ce qu'on a
|
||||
if (empty($allTracks)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Sélectionner aléatoirement $count morceaux parmi tous les morceaux en cache
|
||||
$trackCount = count($allTracks);
|
||||
if ($trackCount <= $count) {
|
||||
return $allTracks;
|
||||
}
|
||||
|
||||
// Mélanger et prendre les N premiers
|
||||
shuffle($allTracks);
|
||||
return array_slice($allTracks, 0, $count);
|
||||
}
|
||||
Reference in New Issue
Block a user