fix(pt/animesgratis): Add VrfInterceptor and parallelize video extractor (#1837)

This commit is contained in:
Claudemirovsky
2023-07-05 07:56:47 +00:00
committed by GitHub
parent 8f15d8559e
commit b018668820
4 changed files with 62 additions and 6 deletions

View File

@ -9,6 +9,10 @@ import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup 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.FormBody
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -18,6 +22,10 @@ class AnimesGratis : DooPlay(
"Animes Grátis", "Animes Grátis",
"https://animesgratis.org", "https://animesgratis.org",
) { ) {
override val client by lazy {
super.client.newBuilder().addInterceptor(VrfInterceptor()).build()
}
// ============================== Popular =============================== // ============================== Popular ===============================
override fun popularAnimeSelector() = "div.imdbRating > article > a" override fun popularAnimeSelector() = "div.imdbRating > article > a"
override fun popularAnimeRequest(page: Int) = GET("$baseUrl/animes/") override fun popularAnimeRequest(page: Int) = GET("$baseUrl/animes/")
@ -30,7 +38,7 @@ class AnimesGratis : DooPlay(
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup() val document = response.asJsoup()
val players = document.select("ul#playeroptionsul li") val players = document.select("ul#playeroptionsul li")
return players.flatMap(::getPlayerVideos) return players.parallelMap(::getPlayerVideos).flatten()
} }
override val prefQualityValues = arrayOf("360p", "480p", "720p", "1080p") override val prefQualityValues = arrayOf("360p", "480p", "720p", "1080p")
@ -71,6 +79,12 @@ class AnimesGratis : DooPlay(
} }
// ============================== Filters =============================== // ============================== Filters ===============================
override fun genresListRequest() = GET("$baseUrl/generos") override fun genresListRequest() = GET("$baseUrl/generos/")
override fun genresListSelector() = "ul.generos li > a" 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()
}
} }

View File

@ -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()
}
}
}

View File

@ -7,20 +7,22 @@ import okhttp3.OkHttpClient
class BloggerExtractor(private val client: OkHttpClient) { class BloggerExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String, headers: Headers): List<Video> { 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() } .use { it.body.string() }
.takeIf { !it.contains("errorContainer") }
.let { it ?: return emptyList() }
.substringAfter("\"streams\":[") .substringAfter("\"streams\":[")
.substringBefore("]") .substringBefore("]")
.split("},") .split("},")
.map { .map {
val url = it.substringAfter("{\"play_url\":\"").substringBefore('"') val videoUrl = it.substringAfter("{\"play_url\":\"").substringBefore('"')
val format = it.substringAfter("\"format_id\":").substringBefore("}") val format = it.substringAfter("\"format_id\":").substringBefore("}")
val quality = when (format) { val quality = when (format) {
"18" -> "360p" "18" -> "360p"
"22" -> "720p" "22" -> "720p"
else -> "Unknown" else -> "Unknown"
} }
Video(url, quality, url, headers = headers) Video(videoUrl, quality, videoUrl, headers = headers)
} }
} }
} }

View File

@ -15,7 +15,7 @@ class DooPlayGenerator : ThemeSourceGenerator {
SingleLang("AnimeOnline.Ninja", "https://www1.animeonline.ninja", "es", className = "AnimeOnlineNinja", isNsfw = false, overrideVersionCode = 27), 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("AnimePlayer", "https://animeplayer.com.br", "pt-BR", isNsfw = true),
SingleLang("AnimesFox BR", "https://animesfox.net", "pt-BR", isNsfw = false, overrideVersionCode = 2), 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("Animes House", "https://animeshouse.net", "pt-BR", isNsfw = false, overrideVersionCode = 5),
SingleLang("Cinemathek", "https://cinemathek.net", "de", isNsfw = true, overrideVersionCode = 12), SingleLang("Cinemathek", "https://cinemathek.net", "de", isNsfw = true, overrideVersionCode = 12),
SingleLang("CineVision", "https://cinevisionv3.online", "pt-BR", isNsfw = true, overrideVersionCode = 5), SingleLang("CineVision", "https://cinevisionv3.online", "pt-BR", isNsfw = true, overrideVersionCode = 5),