1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
<?php
require_once __DIR__ . '/../partials/proxy_helpers.php';
if (!headers_sent()) {
header('Content-Type: application/json');
header('Cache-Control: no-cache, must-revalidate');
}
ob_start();
$cacheDir = sys_get_temp_dir() . '/sillylaird_lastfm';
if (!is_dir($cacheDir)) @mkdir($cacheDir, 0700, true);
$cacheFile = $cacheDir . '/recent.json';
$freshTtl = 10; // serve cache without hitting upstream
$staleTtl = PHP_INT_MAX; // on upstream failure, always fall back to cache
$serveCache = function (string $file) {
$body = @file_get_contents($file);
if ($body === false) return false;
ob_end_clean();
echo $body;
return true;
};
if (is_file($cacheFile) && (time() - filemtime($cacheFile)) < $freshTtl) {
if ($serveCache($cacheFile)) exit;
}
if (!proxy_rate_limit('lastfm_api', 60, 60)) {
if (is_file($cacheFile) && (time() - filemtime($cacheFile)) < $staleTtl) {
if ($serveCache($cacheFile)) exit;
}
ob_end_clean();
http_response_code(429);
echo json_encode(['error' => 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(),
]);
}
|