mirror of
https://github.com/IllusionMan1212/lyrics-grabbr.git
synced 2026-10-24 02:12:27 +00:00
fixes
- added instructions on how to use the "Spotify for lyrics" feature in the README - added ABI splits in preparation for the f-droid relase - removed the skrape.it dependency - fixed bug where the "This song is an instrumental" screen always shows after the first time of fetching lyrics from spotify - properly position title and rotate navigation button icon on topbar for RTL languages - show errors on the lyrics screen - version 1.0.0
This commit is contained in:
@@ -2,14 +2,10 @@ package com.illusionman1212.lyricsgrabbr.data
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import com.illusionman1212.lyricsgrabbr.R
|
||||
import com.illusionman1212.lyricsgrabbr.data.network.GET
|
||||
import com.illusionman1212.lyricsgrabbr.data.network.NetworkHelper
|
||||
import com.illusionman1212.lyricsgrabbr.utils.await
|
||||
import it.skrape.core.htmlDocument
|
||||
import it.skrape.selects.ElementNotFoundException
|
||||
import it.skrape.selects.html5.div
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.jsoup.Jsoup
|
||||
@@ -56,8 +52,10 @@ class LyricsRepository(private val context: Context) {
|
||||
GET(url.toString())
|
||||
).await()
|
||||
|
||||
val body = res.body?.string()
|
||||
|
||||
if (res.isSuccessful) {
|
||||
return Pair(json.decodeFromString(SuccessResponse.serializer(), res.body!!.string())
|
||||
return Pair(json.decodeFromString(SuccessResponse.serializer(), body!!)
|
||||
.lyrics
|
||||
.lines.joinToString(separator = "\n") { it.words }, true)
|
||||
} else {
|
||||
@@ -70,61 +68,41 @@ class LyricsRepository(private val context: Context) {
|
||||
}
|
||||
|
||||
fun fetchLyricsFromGenius(url: Uri): String {
|
||||
// TODO: write a custom fetcher for skrape.it to use our OkHttp client
|
||||
// and get rid of jsoup. Or better yet, maybe skrape.it will be fixed in the future
|
||||
// and we can just use its built in BrowserFetcher
|
||||
val doc = Jsoup.connect(url.toString()).userAgent(USER_AGENT).get()
|
||||
val divs = doc.select("div[data-lyrics-container]")
|
||||
|
||||
try {
|
||||
val lyrics = htmlDocument(doc.toString()) {
|
||||
// set relaxed for instrumental songs
|
||||
relaxed = true
|
||||
val lyrics = StringUtil.borrowBuilder()
|
||||
|
||||
findFirst {
|
||||
div {
|
||||
withAttributeKey = "data-lyrics-container"
|
||||
findAll {
|
||||
this
|
||||
}.joinToString(separator = "\n") {
|
||||
val accum = StringUtil.borrowBuilder()
|
||||
it.element.text()
|
||||
|
||||
it.element.traverse(object : NodeVisitor {
|
||||
override fun head(node: Node, depth: Int) {
|
||||
if (node is TextNode) {
|
||||
accum.append(node.text().trim())
|
||||
// append space here to get proper spacing when there's a <i> tag or other inline text tags
|
||||
accum.append(" ")
|
||||
} else if (node is Element) {
|
||||
if (accum.isNotEmpty() && node.normalName() == "br") {
|
||||
accum.append("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tail(node: Node, depth: Int) {
|
||||
// since we append a space after every text node, we only append a newline if
|
||||
// the last char isn't a space
|
||||
val lastCharIsWhitespace = accum.isNotEmpty() && accum[accum.length - 1] == ' '
|
||||
if (node is Element) {
|
||||
if (node.isBlock && node.nextSibling() is TextNode && !lastCharIsWhitespace) {
|
||||
accum.append("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
accum
|
||||
divs.forEach {
|
||||
it.traverse(object : NodeVisitor {
|
||||
override fun head(node: Node, depth: Int) {
|
||||
if (node is TextNode) {
|
||||
lyrics.append(node.text().trim())
|
||||
// append space here to get proper spacing when there's a <i> tag or other inline text tags
|
||||
lyrics.append(" ")
|
||||
} else if (node is Element) {
|
||||
if (lyrics.isNotEmpty() && node.normalName() == "br") {
|
||||
lyrics.append("\n")
|
||||
}
|
||||
}
|
||||
}.replace("\n\n\n", "\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
return lyrics
|
||||
} catch (e: ElementNotFoundException) {
|
||||
// TODO: relaxed is broken in skrape.it, so we have to catch this exception
|
||||
return ""
|
||||
override fun tail(node: Node, depth: Int) {
|
||||
// since we append a space after every text node, we only append a newline if
|
||||
// the last char isn't a space
|
||||
val lastCharIsWhitespace = lyrics.isNotEmpty() && lyrics[lyrics.length - 1] == ' '
|
||||
if (node is Element) {
|
||||
if (node.isBlock && node.nextSibling() is TextNode && !lastCharIsWhitespace) {
|
||||
lyrics.append("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
lyrics.append("\n")
|
||||
}
|
||||
|
||||
return lyrics.toString().replace("\n\n\n", "\n\n")
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user