fix(pt/animesgratis): Add VrfInterceptor and parallelize video extractor (#1837)
This commit is contained in:
@ -9,6 +9,10 @@ import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Element
|
||||
@ -18,6 +22,10 @@ class AnimesGratis : DooPlay(
|
||||
"Animes Grátis",
|
||||
"https://animesgratis.org",
|
||||
) {
|
||||
override val client by lazy {
|
||||
super.client.newBuilder().addInterceptor(VrfInterceptor()).build()
|
||||
}
|
||||
|
||||
// ============================== Popular ===============================
|
||||
override fun popularAnimeSelector() = "div.imdbRating > article > a"
|
||||
override fun popularAnimeRequest(page: Int) = GET("$baseUrl/animes/")
|
||||
@ -30,7 +38,7 @@ class AnimesGratis : DooPlay(
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val document = response.asJsoup()
|
||||
val players = document.select("ul#playeroptionsul li")
|
||||
return players.flatMap(::getPlayerVideos)
|
||||
return players.parallelMap(::getPlayerVideos).flatten()
|
||||
}
|
||||
|
||||
override val prefQualityValues = arrayOf("360p", "480p", "720p", "1080p")
|
||||
@ -71,6 +79,12 @@ class AnimesGratis : DooPlay(
|
||||
}
|
||||
|
||||
// ============================== Filters ===============================
|
||||
override fun genresListRequest() = GET("$baseUrl/generos")
|
||||
override fun genresListRequest() = GET("$baseUrl/generos/")
|
||||
override fun genresListSelector() = "ul.generos li > a"
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
||||
runBlocking {
|
||||
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package eu.kanade.tachiyomi.animeextension.pt.animesgratis
|
||||
|
||||
import app.cash.quickjs.QuickJs
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
import org.jsoup.Jsoup
|
||||
|
||||
class VrfInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
val response = chain.proceed(request)
|
||||
val respBody = response.body.string()
|
||||
if (response.headers["Content-Type"]?.contains("image") == true) {
|
||||
return chain.proceed(request)
|
||||
}
|
||||
val body = if (respBody.contains("One moment, please")) {
|
||||
val parsed = Jsoup.parse(respBody)
|
||||
val js = parsed.selectFirst("script:containsData(west=)")!!.data()
|
||||
val west = js.substringAfter("west=").substringBefore(",")
|
||||
val east = js.substringAfter("east=").substringBefore(",")
|
||||
val form = parsed.selectFirst("form#wsidchk-form")!!.attr("action")
|
||||
val eval = evalJs(west, east)
|
||||
val getLink = "https://" + request.url.host + form + "?wsidchk=$eval"
|
||||
chain.proceed(GET(getLink)).body
|
||||
} else {
|
||||
respBody.toResponseBody(response.body.contentType())
|
||||
}
|
||||
return response.newBuilder().body(body).build()
|
||||
}
|
||||
|
||||
private fun evalJs(west: String, east: String): String {
|
||||
return QuickJs.create().use { qjs ->
|
||||
val jscript = """$west + $east;"""
|
||||
qjs.evaluate(jscript).toString()
|
||||
}
|
||||
}
|
||||
}
|
@ -7,20 +7,22 @@ import okhttp3.OkHttpClient
|
||||
|
||||
class BloggerExtractor(private val client: OkHttpClient) {
|
||||
fun videosFromUrl(url: String, headers: Headers): List<Video> {
|
||||
return client.newCall(GET(url)).execute()
|
||||
return client.newCall(GET(url, headers)).execute()
|
||||
.use { it.body.string() }
|
||||
.takeIf { !it.contains("errorContainer") }
|
||||
.let { it ?: return emptyList() }
|
||||
.substringAfter("\"streams\":[")
|
||||
.substringBefore("]")
|
||||
.split("},")
|
||||
.map {
|
||||
val url = it.substringAfter("{\"play_url\":\"").substringBefore('"')
|
||||
val videoUrl = it.substringAfter("{\"play_url\":\"").substringBefore('"')
|
||||
val format = it.substringAfter("\"format_id\":").substringBefore("}")
|
||||
val quality = when (format) {
|
||||
"18" -> "360p"
|
||||
"22" -> "720p"
|
||||
else -> "Unknown"
|
||||
}
|
||||
Video(url, quality, url, headers = headers)
|
||||
Video(videoUrl, quality, videoUrl, headers = headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ class DooPlayGenerator : ThemeSourceGenerator {
|
||||
SingleLang("AnimeOnline.Ninja", "https://www1.animeonline.ninja", "es", className = "AnimeOnlineNinja", isNsfw = false, overrideVersionCode = 27),
|
||||
SingleLang("AnimePlayer", "https://animeplayer.com.br", "pt-BR", isNsfw = true),
|
||||
SingleLang("AnimesFox BR", "https://animesfox.net", "pt-BR", isNsfw = false, overrideVersionCode = 2),
|
||||
SingleLang("Animes Grátis", "https://animesgratis.org", "pt-BR", className = "AnimesGratis", isNsfw = false),
|
||||
SingleLang("Animes Grátis", "https://animesgratis.org", "pt-BR", className = "AnimesGratis", isNsfw = false, overrideVersionCode = 1),
|
||||
SingleLang("Animes House", "https://animeshouse.net", "pt-BR", isNsfw = false, overrideVersionCode = 5),
|
||||
SingleLang("Cinemathek", "https://cinemathek.net", "de", isNsfw = true, overrideVersionCode = 12),
|
||||
SingleLang("CineVision", "https://cinevisionv3.online", "pt-BR", isNsfw = true, overrideVersionCode = 5),
|
||||
|
Reference in New Issue
Block a user