<?php
namespace App\Services;
use App\Models\Album;
use App\Models\Artist;
use App\Pipelines\Encyclopedia\GetAlbumTracksUsingMbid;
use App\Pipelines\Encyclopedia\GetAlbumWikidataIdUsingReleaseGroupMbid;
use App\Pipelines\Encyclopedia\GetArtistWikidataIdUsingMbid;
use App\Pipelines\Encyclopedia\GetMbidForArtist;
use App\Pipelines\Encyclopedia\GetReleaseAndReleaseGroupMbidsForAlbum;
use App\Pipelines\Encyclopedia\GetWikipediaPageSummaryUsingPageTitle;
use App\Pipelines\Encyclopedia\GetWikipediaPageTitleUsingWikidataId;
use App\Services\Contracts\Encyclopedia;
use App\Values\Album\AlbumInformation;
use App\Values\Artist\ArtistInformation;
use Illuminate\Support\Facades\Pipeline;
class MusicBrainzService implements Encyclopedia
{
public static function enabled(): bool
{
return config('koel.services.musicbrainz.enabled');
}
public function getArtistInformation(Artist $artist): ?ArtistInformation
{
if ($artist->is_unknown || $artist->is_various) {
return null;
}
return rescue_if(static::enabled(), static function () use ($artist) {
$wikipediaSummary = Pipeline::send($artist->name)
->through([
GetMbidForArtist::class,
GetArtistWikidataIdUsingMbid::class,
GetWikipediaPageTitleUsingWikidataId::class,
GetWikipediaPageSummaryUsingPageTitle::class,
])
->thenReturn();
return $wikipediaSummary
? ArtistInformation::fromWikipediaSummary($wikipediaSummary)
: null;
});
}
public function getAlbumInformation(Album $album): ?AlbumInformation
{
if ($album->is_unknown || $album->artist->is_unknown) {
return null;
}
return rescue_if(static::enabled(), static function () use ($album): ?AlbumInformation {
// MusicBrainz has the concept of a "release" and a "release group".
// A release is a specific version of an album, which contains the actual tracks.
// A release group is a collection of releases (e.g. different formats or editions or markets
// of the same album), which contains metadata like the Wikidata relationship.
/**
* @var string|null $albumMbid
* @var string|null $releaseGroupMbid
*/
[$albumMbid, $releaseGroupMbid] = Pipeline::send([
'album' => $album->name,
'artist' => $album->artist->name,
])
->through([GetReleaseAndReleaseGroupMbidsForAlbum::class])
->thenReturn();
if (!$albumMbid || !$releaseGroupMbid) {
return null;
}
$tracks = Pipeline::send($albumMbid)
->through([GetAlbumTracksUsingMbid::class])
->thenReturn() ?: [];
$wikipediaSummary = Pipeline::send($releaseGroupMbid)
->through([
GetAlbumWikidataIdUsingReleaseGroupMbid::class,
GetWikipediaPageTitleUsingWikidataId::class,
GetWikipediaPageSummaryUsingPageTitle::class,
])
->thenReturn();
return $wikipediaSummary
? AlbumInformation::fromWikipediaSummary($wikipediaSummary)->withMusicBrainzTracks($tracks)
: AlbumInformation::make(url: "https://musicbrainz.org/release/$albumMbid")
->withMusicBrainzTracks($tracks);
});
}
}