Add dumb: a privacy focused genius frontend alternative
This commit is contained in:
1 parent
4b7f1c9c8d
commit
12bc10449e
5 files changed
+155
-46
No files matched your search
+15
-43
@@ -3,8 +3,9 @@
|
||||
* api/lyrics.php
|
||||
* --------------
|
||||
* Lyrics lookup. Tries LRCLIB first (free, no key, has synced lyrics), then
|
||||
* falls back to scraping the public Genius song page if LRCLIB has nothing
|
||||
* and a Genius token is configured. Returns JSON:
|
||||
* falls back to dumb (if USE_DUMB is on) or scraping the public Genius song
|
||||
* page (if a Genius token is configured) when LRCLIB has nothing. Returns
|
||||
* JSON:
|
||||
*
|
||||
* {
|
||||
* "found": true|false,
|
||||
@@ -81,53 +82,24 @@ if ($lrc !== null) {
|
||||
json_out(['found' => true, 'lyrics' => $lrc['lyrics'], 'synced' => $lrc['synced'], 'url' => '']);
|
||||
}
|
||||
|
||||
/* -- dumb (Genius-API-free fallback) ----------------------------------------- */
|
||||
if (cfg('dumb.enabled')) {
|
||||
$path = dumb_search($artist, $title, $timeout);
|
||||
if ($path === '') json_out($empty);
|
||||
$song = dumb_song($path, $timeout);
|
||||
$url = cfg('dumb.url') . $path;
|
||||
if ($song === null || $song['lyrics'] === '') {
|
||||
json_out(['found' => false, 'lyrics' => '', 'synced' => [], 'url' => $url]);
|
||||
}
|
||||
json_out(['found' => true, 'lyrics' => $song['lyrics'], 'synced' => [], 'url' => $url]);
|
||||
}
|
||||
|
||||
/* -- Genius (fallback) ------------------------------------------------------- */
|
||||
if (cfg('genius.token') === '') json_out($empty);
|
||||
|
||||
$token = cfg('genius.token');
|
||||
$headers = ['Authorization: Bearer ' . $token];
|
||||
|
||||
/**
|
||||
* Return the inner HTML of a balanced <div> whose opening tag starts at $lt.
|
||||
* Correctly handles nested <div> elements.
|
||||
*/
|
||||
function inner_balanced_div($html, $lt) {
|
||||
$open = strpos($html, '>', $lt);
|
||||
if ($open === false) return '';
|
||||
$i = $open + 1;
|
||||
$start = $i;
|
||||
$len = strlen($html);
|
||||
$depth = 1;
|
||||
while ($i < $len && $depth > 0) {
|
||||
$next = strpos($html, '<', $i);
|
||||
if ($next === false) break;
|
||||
if (strncasecmp(substr($html, $next, 5), '</div', 5) === 0) {
|
||||
$depth--;
|
||||
if ($depth === 0) return substr($html, $start, $next - $start);
|
||||
$i = $next + 5;
|
||||
} elseif (strncasecmp(substr($html, $next, 4), '<div', 4) === 0) {
|
||||
$depth++;
|
||||
$i = $next + 4;
|
||||
} else {
|
||||
$i = $next + 1;
|
||||
}
|
||||
}
|
||||
return substr($html, $start, max(0, $i - $start));
|
||||
}
|
||||
|
||||
/** Turn one container's HTML into plain text with newlines. */
|
||||
function container_to_text($fragment) {
|
||||
// Line breaks -> newlines before stripping tags.
|
||||
$fragment = preg_replace('#<br\s*/?>#i', "\n", $fragment);
|
||||
// Drop any stray script/style.
|
||||
$fragment = preg_replace('#<(script|style)\b[^>]*>.*?</\1>#is', '', $fragment);
|
||||
// Block-level tags imply a line break.
|
||||
$fragment = preg_replace('#</(p|div)>#i', "\n", $fragment);
|
||||
$text = strip_tags($fragment);
|
||||
$text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
return $text;
|
||||
}
|
||||
|
||||
/* -- Find the song on Genius ----------------------------------------------- */
|
||||
$query = rawurlencode(trim($artist . ' - ' . $title, ' -'));
|
||||
$search = http_get('https://api.genius.com/search?q=' . $query, $timeout, $headers);
|
||||
|
||||
Reference in new issue
Block a user