now.flash.moe/public/get.php

160 lines
6.6 KiB
PHP

<?php
define('FNP_API_KEY', __DIR__ . '/../.apikey');
define('FNP_API_URL', 'https://ws.audioscrobbler.com');
define('FNP_ORIGINS', __DIR__ . '/../.cors');
define('FNP_FMT_JSON', 'json');
define('FNP_FMT_XML', 'xml');
define('FNP_FMTS', [
FNP_FMT_JSON => 'application/json',
FNP_FMT_XML => 'application/xml',
]);
if(!empty($_SERVER['HTTP_ORIGIN']) && is_file(FNP_ORIGINS)) {
$origin = parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST);
$allowedOrigins = file(FNP_ORIGINS, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if(in_array($origin, $allowedOrigins)) {
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Vary: Origin');
}
}
if(!isset($format))
$format = (string)(filter_input(INPUT_GET, 'f') ?? 'json');
$pretty = !empty($_GET['p']);
if($format !== 'json' && $format !== 'xml') {
http_response_code(400);
return;
}
$charset = preg_match('#MSIE#i', $_SERVER['HTTP_USER_AGENT'] ?? '') ? '' : 'utf-8';
header('Content-Type: ' . FNP_FMTS[$format] . (empty($charset) ? '' : ('; charset=' . $charset)));
function errorResponse(string $text, int $code = -1): void {
global $format, $charset;
http_response_code(500);
switch($format) {
case FNP_FMT_JSON:
echo json_encode(['error' => $text, 'code' => $code]);
break;
// Has strange formatting, but XML mode exists for backwards compatibility with an unreleased variation of get.php.
case FNP_FMT_XML:
$document = new DOMDocument('1.0', $charset);
$tracks = $document->appendChild($document->createElement('Tracks'));
$track = $tracks->appendChild($document->createElement('Track'));
$track->setAttribute('error', $text);
$track->setAttribute('code', $code);
echo $document->saveXML();
break;
}
exit;
}
if(!is_file(FNP_API_KEY))
errorResponse('API key file missing! Create a file called ".apikey" in the root directory and place your last.fm api key in there.');
$apiKey = trim(file_get_contents(FNP_API_KEY));
$userName = (string)filter_input(INPUT_GET, 'u', FILTER_SANITIZE_STRING);
$curl = curl_init(FNP_API_URL . '/2.0/?method=user.getrecenttracks&format=json&limit=1&api_key=' . $apiKey . '&user=' . rawurlencode($userName));
curl_setopt_array($curl, [
CURLOPT_AUTOREFERER => false,
CURLOPT_COOKIESESSION => false,
CURLOPT_VERBOSE => false,
CURLOPT_FAILONERROR => false,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TCP_NODELAY => true,
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TCP_FASTOPEN => true,
CURLOPT_VERBOSE => false,
CURLOPT_CONNECTTIMEOUT => 2,
CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
CURLOPT_TIMEOUT => 2,
CURLOPT_USERAGENT => 'NowListening v2 (' . $_SERVER['HTTP_HOST'] . ')',
]);
$response = json_decode(curl_exec($curl));
curl_close($curl);
if($response === null)
errorResponse('API request failed.');
if(isset($response->message))
errorResponse($response->message, $response->error ?? -1);
switch($format) {
case FNP_FMT_JSON:
$tracks = [];
if(!empty($response->recenttracks?->track))
foreach($response->recenttracks->track as $recentTrack) {
$tracks[] = $track = new stdClass;
$track->name = $recentTrack->name;
if(!empty($recentTrack->{"@attr"}?->nowplaying))
$track->nowplaying = true;
$track->mbid = $recentTrack->mbid;
$track->url = $recentTrack->url;
$track->date = $recentTrack->date?->uts ?? '';
$track->streamable = $recentTrack->streamable;
$track->artist = new stdClass;
$track->artist->name = $recentTrack->artist?->{"#text"} ?? '';
$track->artist->mbid = $recentTrack->artist?->mbid ?? '';
$track->artist->url = explode('/_/', $track->url, 2)[0];
$track->album = new stdClass;
$track->album->name = $recentTrack->album?->{"#text"};
$track->album->mbid = $recentTrack->album?->mbid ?? '';
$track->images = new stdClass;
foreach($recentTrack->image as $trackImage)
$track->images->{$trackImage->size} = $trackImage->{"#text"};
}
echo json_encode($tracks, $pretty ? JSON_PRETTY_PRINT : 0);
break;
case FNP_FMT_XML:
$document = new DOMDocument('1.0', $charset);
$document->formatOutput = $pretty;
$tracks = $document->appendChild($document->createElement('Tracks'));
if(!empty($response->recenttracks?->track))
foreach($response->recenttracks->track as $recentTrack) {
$elem = $tracks->appendChild($document->createElement('Track'));
$elem->appendChild($document->createElement('Name', htmlspecialchars($recentTrack->name)));
$elem->appendChild($document->createElement('Mbid', $recentTrack->mbid));
$elem->appendChild($document->createElement('Url', htmlspecialchars($recentTrack->url)));
$elem->appendChild($document->createElement('Date', empty($recentTrack->date?->uts) ? '' : date('c', $recentTrack->date->uts)));
$elem->appendChild($document->createElement('Streamable', empty($recentTrack->streamable) ? '0' : '1'));
$elem->appendChild($document->createElement('IsPlaying', empty($recentTrack->{"@attr"}?->nowplaying) ? '0' : '1'));
$artist = $elem->appendChild($document->createElement('Artist'));
$artist->appendChild($document->createElement('Name', htmlspecialchars($recentTrack->artist?->{"#text"} ?? '')));
$artist->appendChild($document->createElement('Mbid', $recentTrack->artist?->mbid ?? ''));
$album = $elem->appendChild($document->createElement('Album'));
$album->appendChild($document->createElement('Name', htmlspecialchars($recentTrack->album?->{"#text"} ?? '')));
$album->appendChild($document->createElement('Mbid', $recentTrack->album?->mbid ?? ''));
$images = $elem->appendChild($document->createElement('Images'));
foreach($recentTrack->image as $trackImage) {
$name = $trackImage->size;
if($name === 'extralarge')
$name = 'ExtraLarge';
else
$name = ucfirst($name);
$images->appendChild($document->createElement($name, htmlspecialchars($trackImage->{"#text"})));
}
}
echo $document->saveXML();
break;
}