koel/app/Services/LastfmService.php

135 lines
4.1 KiB
PHP
Raw Normal View History

<?php
namespace App\Services;
2022-07-16 22:42:29 +00:00
use App\Models\Album;
use App\Models\Artist;
2022-08-08 16:00:59 +00:00
use App\Models\Song;
use App\Models\User;
2022-08-08 16:00:59 +00:00
use App\Services\ApiClients\LastfmClient;
use App\Values\AlbumInformation;
use App\Values\ArtistInformation;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\Utils;
use Illuminate\Support\Collection;
2022-08-08 16:00:59 +00:00
class LastfmService implements MusicEncyclopedia
{
2022-08-08 16:00:59 +00:00
public function __construct(private LastfmClient $client)
{
}
2016-06-05 04:37:03 +00:00
/**
* Determine if our application is using Last.fm.
*/
2022-08-08 16:00:59 +00:00
public static function used(): bool
2016-06-05 04:37:03 +00:00
{
2022-08-08 16:00:59 +00:00
return (bool) config('koel.lastfm.key');
2016-06-05 04:37:03 +00:00
}
2015-12-20 12:17:35 +00:00
/**
* Determine if Last.fm integration is enabled.
*/
2022-08-08 16:00:59 +00:00
public static function enabled(): bool
2015-12-20 12:17:35 +00:00
{
2022-08-08 16:00:59 +00:00
return config('koel.lastfm.key') && config('koel.lastfm.secret');
2015-12-20 12:17:35 +00:00
}
2022-07-16 22:42:29 +00:00
public function getArtistInformation(Artist $artist): ?ArtistInformation
{
2022-08-08 16:00:59 +00:00
return attempt_if(static::enabled(), function () use ($artist): ?ArtistInformation {
$name = urlencode($artist->name);
$response = $this->client->get("?method=artist.getInfo&autocorrect=1&artist=$name&format=json");
return isset($response?->artist) ? ArtistInformation::fromLastFmData($response->artist) : null;
2022-08-08 16:00:59 +00:00
});
}
2022-07-16 22:42:29 +00:00
public function getAlbumInformation(Album $album): ?AlbumInformation
{
2022-08-08 16:00:59 +00:00
return attempt_if(static::enabled(), function () use ($album): ?AlbumInformation {
$albumName = urlencode($album->name);
$artistName = urlencode($album->artist->name);
2022-08-08 16:00:59 +00:00
$response = $this->client
->get("?method=album.getInfo&autocorrect=1&album=$albumName&artist=$artistName&format=json");
return isset($response?->album) ? AlbumInformation::fromLastFmData($response->album) : null;
2022-08-08 16:00:59 +00:00
});
}
2022-08-08 16:00:59 +00:00
public function scrobble(Song $song, User $user, int $timestamp): void
2015-12-20 12:17:35 +00:00
{
$params = [
2022-08-08 16:00:59 +00:00
'artist' => $song->artist->name,
'track' => $song->title,
'timestamp' => $timestamp,
'sk' => $user->preferences->lastFmSessionKey,
'method' => 'track.scrobble',
];
2015-12-20 12:17:35 +00:00
2022-08-08 16:00:59 +00:00
if ($song->album->name !== Album::UNKNOWN_NAME) {
$params['album'] = $song->album->name;
2015-12-20 12:17:35 +00:00
}
2022-08-08 16:00:59 +00:00
attempt(fn () => $this->client->post('/', $params, false));
2015-12-20 12:17:35 +00:00
}
2022-08-08 16:00:59 +00:00
public function toggleLoveTrack(Song $song, User $user, bool $love): void
{
2022-08-08 16:00:59 +00:00
attempt(fn () => $this->client->post('/', [
'track' => $song->title,
'artist' => $song->artist->name,
'sk' => $user->preferences->lastFmSessionKey,
2022-08-08 16:00:59 +00:00
'method' => $love ? 'track.love' : 'track.unlove',
], false));
}
2015-12-21 13:49:00 +00:00
/**
2022-08-08 16:00:59 +00:00
* @param Collection|array<array-key, Song> $songs
2015-12-21 13:49:00 +00:00
*/
2022-08-08 16:00:59 +00:00
public function batchToggleLoveTracks(Collection $songs, User $user, bool $love): void
2015-12-21 13:49:00 +00:00
{
2022-08-08 16:00:59 +00:00
$promises = $songs->map(
function (Song $song) use ($user, $love): Promise {
return $this->client->postAsync('/', [
'track' => $song->title,
'artist' => $song->artist->name,
'sk' => $user->preferences->lastFmSessionKey,
2022-08-08 16:00:59 +00:00
'method' => $love ? 'track.love' : 'track.unlove',
], false);
}
);
2015-12-21 13:49:00 +00:00
2022-08-08 16:00:59 +00:00
attempt(static fn () => Utils::unwrap($promises));
2015-12-21 13:49:00 +00:00
}
2022-08-08 16:00:59 +00:00
public function updateNowPlaying(Song $song, User $user): void
{
$params = [
2022-08-08 16:00:59 +00:00
'artist' => $song->artist->name,
'track' => $song->title,
'duration' => $song->length,
'sk' => $user->preferences->lastFmSessionKey,
'method' => 'track.updateNowPlaying',
];
2015-12-23 06:26:16 +00:00
2022-08-08 16:00:59 +00:00
if ($song->album->name !== Album::UNKNOWN_NAME) {
$params['album'] = $song->album->name;
2015-12-20 12:17:35 +00:00
}
2022-08-08 16:00:59 +00:00
attempt(fn () => $this->client->post('/', $params, false));
}
2022-08-08 16:00:59 +00:00
public function getSessionKey(string $token): ?string
{
2022-08-08 16:00:59 +00:00
return $this->client->getSessionKey($token);
}
public function setUserSessionKey(User $user, ?string $sessionKey): void
{
$user->preferences->lastFmSessionKey = $sessionKey;
$user->save();
}
}