Add dumb: a privacy focused genius frontend alternative

This commit is contained in:
iamdoubz committed 2026-07-30 14:24:48 -05:00
1 parent 4b7f1c9c8d
commit 12bc10449e
5 files changed
+155 -46

No files matched your search

+15 -43
View File
@@ -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);