feat: add Funkwhale integration

This commit is contained in:
2025-10-17 21:10:20 +04:00
parent 0319fa20c3
commit 95de788114
6 changed files with 637 additions and 11 deletions
+13
View File
@@ -154,6 +154,19 @@ if (!defined('CASTOPOD_PODCAST_SLUGS')) {
// Nombre d'épisodes à afficher (total, tous podcasts confondus)
if (!defined('CASTOPOD_EPISODES_COUNT')) define('CASTOPOD_EPISODES_COUNT', 5);
// =========================================
// Configuration Funkwhale
// =========================================
// Activer l'affichage des morceaux Funkwhale
if (!defined('FUNKWHALE_ENABLED')) define('FUNKWHALE_ENABLED', false);
// URL de l'instance Funkwhale
if (!defined('FUNKWHALE_URL')) define('FUNKWHALE_URL', 'https://mizik.o-k-i.net');
// Nombre de morceaux à afficher
if (!defined('FUNKWHALE_TRACKS_COUNT')) define('FUNKWHALE_TRACKS_COUNT', 10);
// Tags pour filtrer les vidéos selon les catégories
if (!defined('TAG_SHORT')) define('TAG_SHORT', 'short');
+13
View File
@@ -333,6 +333,19 @@ define('WORDPRESS_ENABLED', false);
// define('CACHE_ENABLED', true);
// define('CACHE_DURATION', 3600); // 1 heure recommandé
// =========================================
// Intégration Funkwhale (Musique)
// =========================================
// Activer/désactiver l'affichage des morceaux Funkwhale
// define('FUNKWHALE_ENABLED', true);
// URL de l'instance Funkwhale
// define('FUNKWHALE_URL', 'https://mizik.o-k-i.net');
// Nombre de morceaux aléatoires à afficher
// define('FUNKWHALE_TRACKS_COUNT', 10);
// =========================================
// Système de dons
// =========================================
+127
View File
@@ -873,4 +873,131 @@ function getCastopodEpisodes($castopodUrl = null, $podcastSlugs = null, $count =
return $allEpisodes;
}
/**
* 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;
// 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 avec filtre pour morceaux locaux uniquement
// Le paramètre scope=me récupère uniquement les morceaux de l'instance locale
$apiUrl = rtrim($funkwhaleUrl, '/') . '/api/v1/tracks?ordering=random&page_size=' . $cacheFetchSize . '&scope=all';
// Récupérer les morceaux via cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$jsonContent = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 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) {
$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,
];
// 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);
}
?>