its 7am i havent slept i have no idea
All checks were successful
CI (Gitea) / php-tests (push) Successful in 10m5s
CI (Gitea) / docker-image (push) Successful in 2m22s

This commit is contained in:
2025-11-28 06:40:10 +00:00
parent 336dcc4d3a
commit f77f3a9e40
34 changed files with 1142 additions and 183 deletions

View File

@@ -119,6 +119,7 @@ class SpotifyClient
$limit = 50;
$offset = 0;
do {
// Spotify returns tracks in pages of 50, so iterate until there are no further pages.
$page = $this->requestAlbumTracksPage($albumId, $accessToken, $limit, $offset);
if ($page === null) {
break;
@@ -156,6 +157,31 @@ class SpotifyClient
}
}
/**
* Fetch multiple artists to gather genre information.
*
* @param list<string> $artistIds
* @return array<mixed>|null
*/
public function getArtists(array $artistIds): ?array
{
if ($artistIds === []) { return []; }
$accessToken = $this->getAccessToken();
if ($accessToken === null) { return null; }
$url = 'https://api.spotify.com/v1/artists';
$options = [
'headers' => [ 'Authorization' => 'Bearer ' . $accessToken ],
'query' => [ 'ids' => implode(',', $artistIds) ],
];
try {
return $this->sendRequest('GET', $url, $options, 1800);
} catch (\Throwable) {
return null;
}
}
/**
* Centralized request helper with lightweight caching.
*
@@ -164,31 +190,26 @@ class SpotifyClient
*/
private function sendRequest(string $method, string $url, array $options, int $cacheTtlSeconds = 0): array
{
$cacheKey = null;
if ($cacheTtlSeconds > 0 && strtoupper($method) === 'GET') {
$request = function () use ($method, $url, $options): array {
$response = $this->httpClient->request($method, $url, $options);
return $response->toArray(false);
};
$shouldCache = $cacheTtlSeconds > 0 && strtoupper($method) === 'GET';
if ($shouldCache) {
$cacheKey = 'spotify_resp_' . sha1($url . '|' . json_encode($options['query'] ?? []));
$cached = $this->cache->get($cacheKey, function($item) use ($cacheTtlSeconds) {
// placeholder; we'll set item value explicitly below on miss
$item->expiresAfter(1);
return null;
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($cacheTtlSeconds, $request) {
$item->expiresAfter($cacheTtlSeconds);
return $request();
});
if (is_array($cached) && !empty($cached)) {
return $cached;
}
}
$response = $this->httpClient->request($method, $url, $options);
$data = $response->toArray(false);
if ($cacheKey && $cacheTtlSeconds > 0 && is_array($data)) {
$this->cache->get($cacheKey, function($item) use ($data, $cacheTtlSeconds) {
$item->expiresAfter($cacheTtlSeconds);
return $data;
});
}
return $data;
return $request();
}
/**
* Requests one paginated track list page for an album using the provided OAuth token.
*
* @return array<mixed>|null
*/
private function requestAlbumTracksPage(string $albumId, string $accessToken, int $limit, int $offset): ?array