true, 'message' => 'rate limited']); exit; } $apiKey = lastfm_api_key(); $user = 'SillyLaird'; $limit = 5; $url = "https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=$user&api_key=$apiKey&format=json&limit=$limit"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); try { if ($response === false) { throw new Exception("cURL Error: " . $error); } if ($httpCode !== 200) { throw new Exception("Last.fm API returned HTTP $httpCode"); } $data = json_decode($response, true); if (isset($data['error'])) { throw new Exception("Last.fm Error: " . $data['message']); } if (!isset($data['recenttracks']['track'])) { throw new Exception("No tracks found."); } $tracks = $data['recenttracks']['track']; if (isset($tracks['name'])) { $tracks = [$tracks]; } $results = []; foreach ($tracks as $track) { $results[] = [ 'name' => $track['name'], 'artist' => $track['artist']['#text'], 'url' => $track['url'], 'image' => isset($track['image'][2]['#text']) ? $track['image'][2]['#text'] : '', 'nowplaying' => isset($track['@attr']['nowplaying']) && $track['@attr']['nowplaying'] === 'true', ]; } $json = json_encode($results); $tmp = $cacheFile . '.tmp'; if (@file_put_contents($tmp, $json, LOCK_EX) !== false) { @rename($tmp, $cacheFile); } ob_end_clean(); echo $json; } catch (Exception $e) { if (is_file($cacheFile) && (time() - filemtime($cacheFile)) < $staleTtl) { if ($serveCache($cacheFile)) exit; } ob_end_clean(); http_response_code(500); echo json_encode([ 'error' => true, 'message' => $e->getMessage(), ]); }