Adjust missing elements from old repo to real live website
This commit is contained in:
1 parent
2fbbf4b0fc
commit
63b61e8c5a
10 files changed
+554
-192
No files matched your search
+74
-39
@@ -2,23 +2,22 @@
|
||||
/**
|
||||
* api/artwork.php
|
||||
* ---------------
|
||||
* Optional album-art lookup via the Genius API. The browser calls this only
|
||||
* when the stream provider itself did not supply artwork and ARTWORK_SOURCE
|
||||
* allows Genius. Returns JSON:
|
||||
* Optional album-art lookup. The browser calls this only when the stream
|
||||
* provider itself did not supply artwork and ARTWORK_SOURCE allows a lookup.
|
||||
* Tries Genius first, then Last.fm (whichever have keys configured). Returns:
|
||||
*
|
||||
* { "art": "https://…" | "", "album": "…", "url": "https://genius.com/…" }
|
||||
* { "art": "https://…" | "", "album": "…", "url": "…" }
|
||||
*
|
||||
* With no Genius token configured it simply returns empty fields, and the
|
||||
* front-end falls back to the configured placeholder image.
|
||||
* With nothing configured it returns empty fields and the front-end falls back
|
||||
* to the placeholder image.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/_bootstrap.php';
|
||||
|
||||
$empty = ['art' => '', 'album' => '', 'url' => ''];
|
||||
|
||||
$token = cfg('genius.token');
|
||||
$source = cfg('artwork.source');
|
||||
if ($token === '' || $source === 'none' || $source === 'provider') {
|
||||
if ($source === 'none' || $source === 'provider') {
|
||||
json_out($empty);
|
||||
}
|
||||
|
||||
@@ -42,41 +41,77 @@ if (is_file($overridesFile)) {
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Genius lookup --------------------------------------------------------- */
|
||||
$headers = ['Authorization: Bearer ' . $token];
|
||||
$timeout = 5;
|
||||
/* -- Genius --------------------------------------------------------------- */
|
||||
function genius_artwork($artist, $title) {
|
||||
$token = cfg('genius.token');
|
||||
if ($token === '') return null;
|
||||
$headers = ['Authorization: Bearer ' . $token];
|
||||
|
||||
$query = rawurlencode(trim($artist . ' - ' . $title, ' -'));
|
||||
$search = http_get('https://api.genius.com/search?q=' . $query, $timeout, $headers);
|
||||
if ($search === null) json_out($empty);
|
||||
$query = rawurlencode(trim($artist . ' - ' . $title, ' -'));
|
||||
$search = http_get('https://api.genius.com/search?q=' . $query, 5, $headers);
|
||||
if ($search === null) return null;
|
||||
|
||||
$json = json_decode($search, true);
|
||||
$hit = dot_get($json, 'response.hits.0.result', null);
|
||||
if (!$hit) json_out($empty);
|
||||
$hit = dot_get(json_decode($search, true), 'response.hits.0.result', null);
|
||||
if (!$hit) return null;
|
||||
|
||||
$out = [
|
||||
'art' => (string) ($hit['header_image_url'] ?? $hit['song_art_image_url'] ?? ''),
|
||||
'album' => '',
|
||||
'url' => (string) ($hit['url'] ?? ''),
|
||||
];
|
||||
|
||||
// Pull the album name (and better art) from the full song record.
|
||||
if (!empty($hit['id'])) {
|
||||
$songRaw = http_get('https://api.genius.com/songs/' . rawurlencode((string) $hit['id']), $timeout, $headers);
|
||||
if ($songRaw !== null) {
|
||||
$song = json_decode($songRaw, true);
|
||||
$s = dot_get($song, 'response.song', null);
|
||||
if ($s) {
|
||||
$out['album'] = (string) dot_get($s, 'album.name', '');
|
||||
$betterArt = (string) ($s['song_art_image_url'] ?? $s['header_image_url'] ?? '');
|
||||
if ($betterArt !== '') $out['art'] = $betterArt;
|
||||
$out = [
|
||||
'art' => (string) ($hit['song_art_image_url'] ?? $hit['header_image_url'] ?? ''),
|
||||
'album' => '',
|
||||
'url' => (string) ($hit['url'] ?? ''),
|
||||
];
|
||||
if (!empty($hit['id'])) {
|
||||
$songRaw = http_get('https://api.genius.com/songs/' . rawurlencode((string) $hit['id']), 5, $headers);
|
||||
if ($songRaw !== null) {
|
||||
$s = dot_get(json_decode($songRaw, true), 'response.song', null);
|
||||
if ($s) {
|
||||
$out['album'] = (string) dot_get($s, 'album.name', '');
|
||||
$better = (string) ($s['song_art_image_url'] ?? $s['header_image_url'] ?? '');
|
||||
if ($better !== '') $out['art'] = $better;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Genius' generic default cover counts as "no art".
|
||||
if (strpos($out['art'], 'default_cover_image') !== false) $out['art'] = '';
|
||||
return ($out['art'] === '' && $out['album'] === '') ? null : $out;
|
||||
}
|
||||
|
||||
/* -- Last.fm -------------------------------------------------------------- */
|
||||
function lastfm_artwork($artist, $title) {
|
||||
$key = cfg('artwork.lastfm_key');
|
||||
if ($key === '' || $artist === '') return null;
|
||||
|
||||
$url = 'https://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json&autocorrect=1'
|
||||
. '&api_key=' . rawurlencode($key)
|
||||
. '&artist=' . rawurlencode($artist)
|
||||
. '&track=' . rawurlencode($title);
|
||||
$raw = http_get($url, 5);
|
||||
if ($raw === null) return null;
|
||||
|
||||
$data = json_decode($raw, true);
|
||||
$images = dot_get($data, 'track.album.image', []);
|
||||
$art = '';
|
||||
if (is_array($images)) {
|
||||
foreach ($images as $img) { // last non-empty = largest
|
||||
if (!empty($img['#text'])) $art = $img['#text'];
|
||||
}
|
||||
}
|
||||
if ($art === '') return null;
|
||||
return ['art' => $art, 'album' => (string) dot_get($data, 'track.album.title', ''), 'url' => ''];
|
||||
}
|
||||
|
||||
/* -- Try providers in the configured order -------------------------------- */
|
||||
$order = $source === 'lastfm' ? ['lastfm']
|
||||
: ($source === 'genius' ? ['genius'] : ['genius', 'lastfm']);
|
||||
|
||||
$album = '';
|
||||
foreach ($order as $provider) {
|
||||
$res = ($provider === 'genius') ? genius_artwork($artist, $title) : lastfm_artwork($artist, $title);
|
||||
if ($res === null) continue;
|
||||
if ($album === '' && $res['album'] !== '') $album = $res['album'];
|
||||
if ($res['art'] !== '') {
|
||||
$res['album'] = $res['album'] ?: $album;
|
||||
json_out($res);
|
||||
}
|
||||
}
|
||||
|
||||
// Treat Genius' generic default cover as "no art" so the placeholder shows.
|
||||
if (strpos($out['art'], 'default_cover_image') !== false) {
|
||||
$out['art'] = '';
|
||||
}
|
||||
|
||||
json_out($out);
|
||||
json_out(['art' => '', 'album' => $album, 'url' => '']);
|
||||
+20
-1
@@ -78,7 +78,26 @@ $search = http_get('https://api.genius.com/search?q=' . $query, $timeout, $heade
|
||||
if ($search === null) json_out($empty);
|
||||
|
||||
$json = json_decode($search, true);
|
||||
$pageUrl = (string) dot_get($json, 'response.hits.0.result.url', '');
|
||||
$hits = dot_get($json, 'response.hits', []);
|
||||
if (!is_array($hits) || count($hits) === 0) json_out($empty);
|
||||
|
||||
$pageUrl = (string) dot_get($hits, '0.result.url', '');
|
||||
|
||||
// Optionally prefer the first English-language match (a few extra API calls).
|
||||
if (cfg('lyrics.prefer_english')) {
|
||||
$checked = 0;
|
||||
foreach ($hits as $h) {
|
||||
if ($checked++ >= 5) break;
|
||||
$id = dot_get($h, 'result.id', null);
|
||||
if (!$id) continue;
|
||||
$songRaw = http_get('https://api.genius.com/songs/' . rawurlencode((string) $id), $timeout, $headers);
|
||||
if ($songRaw === null) continue;
|
||||
if (dot_get(json_decode($songRaw, true), 'response.song.language', '') === 'en') {
|
||||
$pageUrl = (string) dot_get($h, 'result.url', $pageUrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($pageUrl === '') json_out($empty);
|
||||
|
||||
/* -- Scrape the lyric containers ------------------------------------------- */
|
||||
|
||||
@@ -37,6 +37,23 @@ $out = [
|
||||
'listeners_peak' => null,
|
||||
];
|
||||
|
||||
/** Remove configured junk (e.g. " (Remastered)", ".mp3") from a string. */
|
||||
function clean_str($s) {
|
||||
$patterns = cfg('nowplaying.cleanup');
|
||||
if (empty($patterns)) return trim($s);
|
||||
$isRegex = cfg('nowplaying.cleanup_is_regex');
|
||||
foreach ($patterns as $p) {
|
||||
if ($p === '') continue;
|
||||
if ($isRegex) {
|
||||
$out = @preg_replace('/' . str_replace('/', '\\/', $p) . '/i', '', $s);
|
||||
if ($out !== null) $s = $out; // ignore invalid patterns
|
||||
} else {
|
||||
$s = str_ireplace($p, '', $s);
|
||||
}
|
||||
}
|
||||
return trim($s);
|
||||
}
|
||||
|
||||
/** Split "Artist <delim> Title" into [artist, title]. */
|
||||
function split_title($combined, $delim) {
|
||||
$combined = trim((string) $combined);
|
||||
@@ -147,4 +164,8 @@ switch ($provider) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Strip configured junk from the metadata before returning it.
|
||||
$out['artist'] = clean_str($out['artist']);
|
||||
$out['title'] = clean_str($out['title']);
|
||||
|
||||
json_out($out);
|
||||
Reference in new issue
Block a user