Animeflv updates: video link extraction and pagination (#460)

Co-authored-by: Eliud Miguel Antonio <eliud.miguel@cenace.gob.mx>
This commit is contained in:
miguelantonioe
2022-04-05 04:39:18 -05:00
committed by GitHub
parent 4270633187
commit 02a580610a
3 changed files with 80 additions and 66 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeFLV' extName = 'AnimeFLV'
pkgNameSuffix = 'es.animeflv' pkgNameSuffix = 'es.animeflv'
extClass = '.AnimeFlv' extClass = '.AnimeFlv'
extVersionCode = 17 extVersionCode = 18
libVersion = '12' libVersion = '12'
} }

View File

@ -2,9 +2,9 @@ package eu.kanade.tachiyomi.animeextension.es.animeflv
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Log
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.DoodExtractor
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.FembedExtractor import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.FembedExtractor
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.OkruExtractor import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.OkruExtractor
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.StreamSBExtractor import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.StreamSBExtractor
@ -17,13 +17,7 @@ import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -73,7 +67,7 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
return anime return anime
} }
override fun popularAnimeNextPageSelector(): String = "ul.pagination li a[rel=next]:not(li.disabled)" override fun popularAnimeNextPageSelector(): String = "ul.pagination li.selected ~ li"
override fun episodeListParse(response: Response): List<SEpisode> { override fun episodeListParse(response: Response): List<SEpisode> {
return super.episodeListParse(response).reversed() return super.episodeListParse(response).reversed()
@ -84,7 +78,7 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun episodeFromElement(element: Element): SEpisode { override fun episodeFromElement(element: Element): SEpisode {
val episode = SEpisode.create() val episode = SEpisode.create()
val epNum = getNumberFromEpsString(element.select("p").text()) val epNum = getNumberFromEpsString(element.select("p").text())
episode.setUrlWithoutDomain(element.attr("abs:href")) episode.setUrlWithoutDomain(element.attr("href"))
episode.episode_number = when { episode.episode_number = when {
(epNum.isNotEmpty()) -> epNum.toFloat() (epNum.isNotEmpty()) -> epNum.toFloat()
else -> 1F else -> 1F
@ -102,63 +96,39 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup() val document = response.asJsoup()
val videoList = mutableListOf<Video>() val videoList = mutableListOf<Video>()
document.select("script").forEach { script -> document.select("ul.CapiTnv li:not([title='Our Server'])").forEach { script ->
if (script.data().contains("var videos = {")) { val quality = script.attr("title")
val data = script.data().substringAfter("var videos = ").substringBefore(";") val url = script.attr("data-video")
val jsonObject = json.decodeFromString<JsonObject>(data) if (quality == "Streamsb") {
val sub = jsonObject["SUB"]!! val headers = headers.newBuilder()
val lat = jsonObject["LAT"] .set("Referer", url)
Log.i("bruh", " a $lat") .set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
if (sub !is JsonNull) { .set("Accept-Language", "en-US,en;q=0.5")
for (server in sub.jsonArray) { .set("watchsb", "streamsb")
val url = server.jsonObject["code"]!!.jsonPrimitive.content.replace("\\/", "/") .build()
val quality = server.jsonObject["title"]!!.jsonPrimitive.content val videos = StreamSBExtractor(client).videosFromUrl(url, headers)
if (quality == "SB") { videoList.addAll(videos)
val headers = headers.newBuilder() }
.set("Referer", url) if (quality == "Fembed") {
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0") val videos = FembedExtractor().videosFromUrl(url)
.set("Accept-Language", "en-US,en;q=0.5") videoList.addAll(videos)
.set("watchsb", "streamsb") }
.build() if (quality == "Streamtape") {
val videos = StreamSBExtractor(client).videosFromUrl(url, headers) val video = StreamTapeExtractor(client).videoFromUrl(url, quality)
videoList.addAll(videos) if (video != null) {
} videoList.add(video)
if (quality == "Fembed") {
val videos = FembedExtractor().videosFromUrl(url)
videoList.addAll(videos)
}
if (quality == "Stape") {
val video = StreamTapeExtractor(client).videoFromUrl(url, quality)
if (video != null) {
videoList.add(video)
}
}
if (quality == "Okru") {
val videos = OkruExtractor(client).videosFromUrl(url)
videoList.addAll(videos)
}
}
} }
if (lat !is JsonNull) { }
if (quality == "Doodstream") {
if (lat != null) { val video = try { DoodExtractor(client).videoFromUrl(url, "DoodStream") } catch (e: Exception) { null }
for (server in lat.jsonArray) { if (video != null) {
val url = server.jsonObject["code"]!!.jsonPrimitive.content.replace("\\/", "/") videoList.add(video)
val quality = server.jsonObject["title"]!!.jsonPrimitive.content
if (quality == "Fembed") {
val videos = FembedExtractor().videosFromUrl(url, "DUB: ")
videoList.addAll(videos)
}
if (quality == "Okru") {
val videos = OkruExtractor(client).videosFromUrl(url, "DUB: ")
videoList.addAll(videos)
}
}
}
} }
} }
if (quality == "Okru") {
val videos = OkruExtractor(client).videosFromUrl(url)
videoList.addAll(videos)
}
} }
return videoList return videoList
} }
@ -199,14 +169,18 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun animeDetailsParse(document: Document): SAnime { override fun animeDetailsParse(document: Document): SAnime {
val anime = SAnime.create() val anime = SAnime.create()
anime.thumbnail_url = baseUrl + "/" + document.selectFirst("div.AnimeCover div.Image figure img").attr("src") anime.thumbnail_url = externalOrInternalImg(document.selectFirst("div.AnimeCover div.Image figure img").attr("src"))
anime.title = document.selectFirst("div.Ficha.fchlt div.Container h1.Title").text() anime.title = document.selectFirst("div.Ficha.fchlt div.Container .Title").text()
anime.description = document.selectFirst("div.Description").text().removeSurrounding("\"") anime.description = document.selectFirst("div.Description").text().removeSurrounding("\"")
anime.genre = document.select("nav.Nvgnrs a").joinToString { it.text() } anime.genre = document.select("nav.Nvgnrs a").joinToString { it.text() }
anime.status = parseStatus(document.select("span.fa-tv").text()) anime.status = parseStatus(document.select("span.fa-tv").text())
return anime return anime
} }
private fun externalOrInternalImg(url: String): String {
return if (url.contains("https")) url else "$baseUrl/$url"
}
private fun parseStatus(statusString: String): Int { private fun parseStatus(statusString: String): Int {
return when { return when {
statusString.contains("En emision") -> SAnime.ONGOING statusString.contains("En emision") -> SAnime.ONGOING

View File

@ -0,0 +1,40 @@
package eu.kanade.tachiyomi.animeextension.es.animeflv.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import okhttp3.Headers
import okhttp3.OkHttpClient
class DoodExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String): Video? {
val response = client.newCall(GET(url)).execute()
val doodTld = url.substringAfter("https://dood.").substringBefore("/")
val content = response.body!!.string()
if (!content.contains("'/pass_md5/")) return null
val md5 = content.substringAfter("'/pass_md5/").substringBefore("',")
val token = md5.substringAfterLast("/")
val randomString = getRandomString()
val expiry = System.currentTimeMillis()
val videoUrlStart = client.newCall(
GET(
"https://dood.$doodTld/pass_md5/$md5",
Headers.headersOf("referer", url)
)
).execute().body!!.string()
val videoUrl = "$videoUrlStart$randomString?token=$token&expiry=$expiry"
return Video(url, quality, videoUrl, null, doodHeaders(doodTld))
}
private fun getRandomString(length: Int = 10): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
private fun doodHeaders(tld: String) = Headers.Builder().apply {
add("User-Agent", "Aniyomi")
add("Referer", "https://dood.$tld/")
}.build()
}