@ -5,7 +5,7 @@ ext {
|
|||||||
extName = 'AnimeFLV'
|
extName = 'AnimeFLV'
|
||||||
pkgNameSuffix = 'es.animeflv'
|
pkgNameSuffix = 'es.animeflv'
|
||||||
extClass = '.AnimeFlv'
|
extClass = '.AnimeFlv'
|
||||||
extVersionCode = 22
|
extVersionCode = 23
|
||||||
libVersion = '12'
|
libVersion = '12'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ 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
|
||||||
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.StreamTapeExtractor
|
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.StreamTapeExtractor
|
||||||
|
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.YourUploadExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
@ -18,7 +19,12 @@ 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.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
|
||||||
@ -33,7 +39,7 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override val name = "AnimeFLV"
|
override val name = "AnimeFLV"
|
||||||
|
|
||||||
override val baseUrl = "https://ww3.animeflv.cc"
|
override val baseUrl = "https://www3.animeflv.net"
|
||||||
|
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
|
|
||||||
@ -49,7 +55,7 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override fun popularAnimeSelector(): String = "div.Container ul.ListAnimes li article"
|
override fun popularAnimeSelector(): String = "div.Container ul.ListAnimes li article"
|
||||||
|
|
||||||
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/browse?order=5&page=$page")
|
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/browse?order=rating&page=$page")
|
||||||
|
|
||||||
override fun popularAnimeFromElement(element: Element): SAnime {
|
override fun popularAnimeFromElement(element: Element): SAnime {
|
||||||
val anime = SAnime.create()
|
val anime = SAnime.create()
|
||||||
@ -68,27 +74,36 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
return anime
|
return anime
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularAnimeNextPageSelector(): String = "ul.pagination li.selected ~ li"
|
override fun popularAnimeNextPageSelector(): String = "ul.pagination li a[rel=\"next\"]"
|
||||||
|
|
||||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
override fun episodeListParse(response: Response): List<SEpisode> {
|
||||||
return super.episodeListParse(response).reversed()
|
val document = response.asJsoup()
|
||||||
}
|
val episodeList = mutableListOf<SEpisode>()
|
||||||
|
document.select("script").forEach { script ->
|
||||||
override fun episodeListSelector() = "ul.ListCaps li a"
|
if (script.data().contains("var anime_info =")) {
|
||||||
|
val animeInfo = script.data().substringAfter("var anime_info = [").substringBefore("];")
|
||||||
override fun episodeFromElement(element: Element): SEpisode {
|
val arrInfo = animeInfo.split(",")
|
||||||
val episode = SEpisode.create()
|
val animeUri = arrInfo[2]!!.replace("\"", "")
|
||||||
val epNum = getNumberFromEpsString(element.select("p").text())
|
val episodes = script.data().substringAfter("var episodes = [").substringBefore("];").trim()
|
||||||
episode.setUrlWithoutDomain(element.attr("href"))
|
val arrEpisodes = episodes.split("],[")
|
||||||
episode.episode_number = when {
|
arrEpisodes!!.forEach { arrEp ->
|
||||||
(epNum.isNotEmpty()) -> epNum.toFloat()
|
val noEpisode = arrEp!!.replace("[", "")!!.replace("]", "")!!.split(",")!![0]
|
||||||
else -> 1F
|
val ep = SEpisode.create()
|
||||||
|
val url = "$baseUrl/ver/$animeUri-$noEpisode"
|
||||||
|
ep.setUrlWithoutDomain(url)
|
||||||
|
ep.name = "Episodio $noEpisode"
|
||||||
|
ep.episode_number = noEpisode.toFloat()
|
||||||
|
episodeList.add(ep)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
episode.name = element.select("p").text()
|
return episodeList
|
||||||
|
|
||||||
return episode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun episodeListSelector() = "uwu"
|
||||||
|
|
||||||
|
override fun episodeFromElement(element: Element) = throw Exception("not used")
|
||||||
|
|
||||||
private fun getNumberFromEpsString(epsStr: String): String {
|
private fun getNumberFromEpsString(epsStr: String): String {
|
||||||
return epsStr.filter { it.isDigit() }
|
return epsStr.filter { it.isDigit() }
|
||||||
}
|
}
|
||||||
@ -96,39 +111,61 @@ 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("ul.CapiTnv li:not([title='Our Server'])").forEach { script ->
|
document.select("script").forEach { script ->
|
||||||
val quality = script.attr("title")
|
if (script.data().contains("var videos = {")) {
|
||||||
val url = script.attr("data-video")
|
val responseString = script.data().substringAfter("var videos =").substringBefore(";").trim()
|
||||||
if (quality == "Streamsb") {
|
val jObject = json.decodeFromString<JsonObject>(responseString)
|
||||||
val headers = headers.newBuilder()
|
jObject["SUB"]!!.jsonArray!!.forEach { servers ->
|
||||||
.set("Referer", url)
|
val json = servers!!.jsonObject
|
||||||
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
|
val quality = json!!["title"]!!.jsonPrimitive!!.content
|
||||||
.set("Accept-Language", "en-US,en;q=0.5")
|
var url = json!!["code"]!!.jsonPrimitive!!.content
|
||||||
.set("watchsb", "streamsb")
|
|
||||||
.build()
|
if (quality == "SB") {
|
||||||
val videos = StreamSBExtractor(client).videosFromUrl(url, headers)
|
val headers = headers.newBuilder()
|
||||||
videoList.addAll(videos)
|
.set("referer", url)
|
||||||
}
|
.set(
|
||||||
if (quality == "Fembed") {
|
"User-Agent",
|
||||||
val videos = FembedExtractor().videosFromUrl(url)
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
|
||||||
videoList.addAll(videos)
|
)
|
||||||
}
|
.set("Accept-Language", "es-MX,es-419;q=0.9,es;q=0.8,en;q=0.7")
|
||||||
if (quality == "Streamtape") {
|
.set("watchsb", "streamsb")
|
||||||
val video = StreamTapeExtractor(client).videoFromUrl(url, quality)
|
.set("authority", "embedsb.com")
|
||||||
if (video != null) {
|
.build()
|
||||||
videoList.add(video)
|
val videos = StreamSBExtractor(client).videosFromUrl(url, headers)
|
||||||
|
videoList.addAll(videos)
|
||||||
|
}
|
||||||
|
if (quality == "Fembed") {
|
||||||
|
val videos = FembedExtractor().videosFromUrl(url)
|
||||||
|
videoList.addAll(videos)
|
||||||
|
}
|
||||||
|
if (quality == "Stape") {
|
||||||
|
val url1 = json!!["url"]!!.jsonPrimitive!!.content
|
||||||
|
val video = StreamTapeExtractor(client).videoFromUrl(url1, quality)
|
||||||
|
if (video != null) {
|
||||||
|
videoList.add(video)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quality == "Doodstream") {
|
||||||
|
val video = try {
|
||||||
|
DoodExtractor(client).videoFromUrl(url, "DoodStream")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (video != null) {
|
||||||
|
videoList.add(video)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quality == "Okru") {
|
||||||
|
val videos = OkruExtractor(client).videosFromUrl(url)
|
||||||
|
videoList.addAll(videos)
|
||||||
|
}
|
||||||
|
if (quality == "YourUpload") {
|
||||||
|
val headers = headers.newBuilder().add("referer", "https://www.yourupload.com/").build()
|
||||||
|
val videos = YourUploadExtractor(client).videoFromUrl(url, headers = headers)
|
||||||
|
if (!videos.isEmpty()) videoList.addAll(videos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (quality == "Doodstream") {
|
|
||||||
val video = try { DoodExtractor(client).videoFromUrl(url, "DoodStream") } catch (e: Exception) { null }
|
|
||||||
if (video != null) {
|
|
||||||
videoList.add(video)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (quality == "Okru") {
|
|
||||||
val videos = OkruExtractor(client).videosFromUrl(url)
|
|
||||||
videoList.addAll(videos)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return videoList
|
return videoList
|
||||||
}
|
}
|
||||||
@ -162,9 +199,9 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val genreFilter = filterList.find { it is GenreFilter } as GenreFilter
|
val genreFilter = filterList.find { it is GenreFilter } as GenreFilter
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
query.isNotBlank() -> GET("$baseUrl/browse?q=$query&order=4&page=$page")
|
query.isNotBlank() -> GET("$baseUrl/browse?q=$query&order=rating&page=$page")
|
||||||
genreFilter.state != 0 -> GET("$baseUrl/browse?genres=${genreFilter.toUriPart()}&order=4&page=$page")
|
genreFilter.state != 0 -> GET("$baseUrl/browse?genre[]=${genreFilter.toUriPart()}&order=rating&page=$page")
|
||||||
else -> GET("$baseUrl/browse?page=$page&order=4")
|
else -> GET("$baseUrl/browse?page=$page&order=rating")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.es.animeflv.extractors
|
package eu.kanade.tachiyomi.animeextension.es.animeflv.extractors
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
@ -25,12 +26,13 @@ class StreamSBExtractor(private val client: OkHttpClient) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun videosFromUrl(url: String, headers: Headers): List<Video> {
|
fun videosFromUrl(url: String, headers: Headers): List<Video> {
|
||||||
val sbUrl = url.substringBefore("/e")
|
val sbUrl = url.substringBefore("/e/")
|
||||||
val id = url.substringAfter("e/").substringBefore(".html")
|
val id = url.substringAfter("/e/").substringBefore(".html")
|
||||||
val bytes = id.toByteArray()
|
val bytes = id.toByteArray()
|
||||||
val bytesToHex = bytesToHex(bytes)
|
val bytesToHex = bytesToHex(bytes)
|
||||||
val master =
|
val master =
|
||||||
"$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
|
"$sbUrl/sources43/416f794d637048744d4565577c7c${bytesToHex}7c7c776e6c7a365964385a484b767c7c73747265616d7362/656d5a62394f713230524a667c7c373635353537333734623561373634613330353134633631376337633339353037343631363934393335363434333730373633363763376337613737353836323434353534363431343633323533376137633763373337343732363536313664373336327c7c59304b7778506d424c4c32767c7c73747265616d7362"
|
||||||
|
Log.i("bruh sb", master)
|
||||||
val json = Json.decodeFromString<JsonObject>(
|
val json = Json.decodeFromString<JsonObject>(
|
||||||
client.newCall(GET(master, headers))
|
client.newCall(GET(master, headers))
|
||||||
.execute().body!!.string()
|
.execute().body!!.string()
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package eu.kanade.tachiyomi.animeextension.es.animeflv.extractors
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import okhttp3.Headers
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class YourUploadExtractor(private val client: OkHttpClient) {
|
||||||
|
fun videoFromUrl(url: String, headers: Headers): List<Video> {
|
||||||
|
val videoList = mutableListOf<Video>()
|
||||||
|
try {
|
||||||
|
val document = client.newCall(GET(url)).execute()
|
||||||
|
if (document.isSuccessful) {
|
||||||
|
val content = document.asJsoup()
|
||||||
|
val baseData =
|
||||||
|
content!!.selectFirst("script:containsData(jwplayerOptions)")!!.data()
|
||||||
|
if (!baseData.isNullOrEmpty()) {
|
||||||
|
val basicUrl = baseData.substringAfter("file: '").substringBefore("',")
|
||||||
|
videoList.add(Video(basicUrl, "YourUpload", basicUrl, null, headers))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
}
|
||||||
|
return videoList
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user