Fixes and added filters [AnimeFenix] (#849)
This commit is contained in:
committed by
GitHub
parent
9d1069deb5
commit
a6d3c4b430
@ -5,7 +5,7 @@ ext {
|
|||||||
extName = 'Animefenix'
|
extName = 'Animefenix'
|
||||||
pkgNameSuffix = 'es.animefenix'
|
pkgNameSuffix = 'es.animefenix'
|
||||||
extClass = '.Animefenix'
|
extClass = '.Animefenix'
|
||||||
extVersionCode = 8
|
extVersionCode = 9
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import android.content.SharedPreferences
|
|||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.FembedExtractor
|
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.FembedExtractor
|
||||||
|
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.Mp4uploadExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.OkruExtractor
|
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.OkruExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.StreamSBExtractor
|
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.StreamSBExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.StreamTapeExtractor
|
import eu.kanade.tachiyomi.animeextension.es.animefenix.extractors.StreamTapeExtractor
|
||||||
@ -58,7 +59,7 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
return anime
|
return anime
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularAnimeNextPageSelector(): String = "a.pagination-link"
|
override fun popularAnimeNextPageSelector(): String = "ul.pagination-list li a.pagination-link:contains(Siguiente)"
|
||||||
|
|
||||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
override fun episodeListParse(response: Response): List<SEpisode> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
@ -86,8 +87,20 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
servers.forEach { server ->
|
servers.forEach { server ->
|
||||||
val decodedUrl = URLDecoder.decode(server, "UTF-8")
|
val decodedUrl = URLDecoder.decode(server, "UTF-8")
|
||||||
val realUrl = client.newCall(GET(decodedUrl)).execute().asJsoup().selectFirst("script").data()
|
val realUrl = try {
|
||||||
.substringAfter("src=\"").substringBefore("\"")
|
client.newCall(GET(decodedUrl)).execute().asJsoup().selectFirst("script")
|
||||||
|
.data().substringAfter("src=\"").substringBefore("\"")
|
||||||
|
} catch (e: Exception) { "" }
|
||||||
|
/*
|
||||||
|
in case this is too slow:
|
||||||
|
Animefenix redirect links are associated with an id, ex: id:9=Amazon ; id:2=Fembed ; etc. ( $baseUrl/redirect.php?player=$id )
|
||||||
|
can be obtained in an easy way by adding this line :
|
||||||
|
Log.i("bruh", "${server.substringAfter("?player=").substringBefore("&")} = $realUrl}")
|
||||||
|
and play any episode,
|
||||||
|
the "code" part in the url represents represents what comes after the main domain like /embed/ or /v/ or /e/
|
||||||
|
ex of full url: $baseUrl/redirect.php?player=2&code=4mdmxtzmpe8768k&
|
||||||
|
in this case the playerId represent fembed and the full url is : https://www.fembed.com/v/4mdmxtzmpe8768k
|
||||||
|
*/
|
||||||
|
|
||||||
when {
|
when {
|
||||||
realUrl.contains("ok.ru") -> {
|
realUrl.contains("ok.ru") -> {
|
||||||
@ -108,10 +121,8 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
realUrl.contains("/stream/fl.php") -> {
|
realUrl.contains("/stream/fl.php") -> {
|
||||||
val video = realUrl.substringAfter("/stream/fl.php?v=")
|
val video = realUrl.substringAfter("/stream/fl.php?v=")
|
||||||
client.newCall(GET(video)).execute().code.let {
|
if (client.newCall(GET(video)).execute().code == 200) {
|
||||||
if (it == 200) {
|
videoList.add(Video(video, "FireLoad", video))
|
||||||
videoList.add(Video(video, "FireLoad", video))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realUrl.contains("streamtape") -> {
|
realUrl.contains("streamtape") -> {
|
||||||
@ -133,6 +144,11 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
.build()
|
.build()
|
||||||
StreamSBExtractor(client).videosFromUrl(realUrl, headers).map { videoList.add(it) }
|
StreamSBExtractor(client).videosFromUrl(realUrl, headers).map { videoList.add(it) }
|
||||||
}
|
}
|
||||||
|
realUrl.contains("mp4upload") -> {
|
||||||
|
val headers = headers.newBuilder().set("referer", "https://mp4upload.com/").build()
|
||||||
|
val video = Mp4uploadExtractor().getVideoFromUrl(realUrl, headers)
|
||||||
|
videoList.add(video)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return videoList
|
return videoList
|
||||||
@ -166,12 +182,35 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
||||||
val filterList = if (filters.isEmpty()) getFilterList() else filters
|
val yearFilter = filters.find { it is YearFilter } as YearFilter
|
||||||
val genreFilter = filterList.find { it is GenreFilter } as GenreFilter
|
val stateFilter = filters.find { it is StateFilter } as StateFilter
|
||||||
|
val typeFilter = filters.find { it is TypeFilter } as TypeFilter
|
||||||
|
|
||||||
|
val genreFilter = (filters.find { it is TagFilter } as TagFilter).state.filter { it.state }
|
||||||
|
|
||||||
|
var filterUrl = "$baseUrl/animes?"
|
||||||
|
if (query.isNotBlank()) {
|
||||||
|
filterUrl += "&q=$query"
|
||||||
|
} // search by name
|
||||||
|
if (genreFilter.isNotEmpty()) {
|
||||||
|
genreFilter.forEach {
|
||||||
|
filterUrl += "&genero[]=${it.name}"
|
||||||
|
}
|
||||||
|
} // search by genre
|
||||||
|
if (yearFilter.state.isNotBlank()) {
|
||||||
|
filterUrl += "&year[]=${yearFilter.state}"
|
||||||
|
} // search by year
|
||||||
|
if (stateFilter.state != 0) {
|
||||||
|
filterUrl += "&estado[]=${stateFilter.toUriPart()}"
|
||||||
|
} // search by state
|
||||||
|
if (typeFilter.state != 0) {
|
||||||
|
filterUrl += "&type[]=${typeFilter.toUriPart()}"
|
||||||
|
} // search by type
|
||||||
|
filterUrl += "&page=$page" // add page
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
query.isNotBlank() -> GET("$baseUrl/animes?q=$query&page=$page", headers)
|
genreFilter.isEmpty() || yearFilter.state.isNotBlank() ||
|
||||||
genreFilter.state != 0 -> GET("$baseUrl/animes?genero[]=${genreFilter.toUriPart()}&order=default&page=$page")
|
stateFilter.state != 0 || typeFilter.state != 0 || query.isNotBlank() -> GET(filterUrl, headers)
|
||||||
else -> GET("$baseUrl/animes?order=likes&page=$page ")
|
else -> GET("$baseUrl/animes?order=likes&page=$page ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,67 +250,99 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val videoURl = document.selectFirst("script:containsData(sources: [)").data()
|
val videoURl = document.selectFirst("script:containsData(sources: [)").data()
|
||||||
.substringAfter("[{\"file\":\"")
|
.substringAfter("[{\"file\":\"")
|
||||||
.substringBefore("\",").replace("\\", "")
|
.substringBefore("\",").replace("\\", "")
|
||||||
return if (client.newCall(GET(videoURl)).execute().code == 200) videoURl else ""
|
|
||||||
|
return try {
|
||||||
|
if (client.newCall(GET(url)).execute().code == 200) {
|
||||||
|
videoURl
|
||||||
|
} else ""
|
||||||
|
} catch (e: Exception) {
|
||||||
|
""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList(): AnimeFilterList = AnimeFilterList(
|
override fun getFilterList(): AnimeFilterList = AnimeFilterList(
|
||||||
AnimeFilter.Header("La busqueda por texto ignora el filtro"),
|
TagFilter("Generos", triStateBoxesFrom(genreList)),
|
||||||
GenreFilter()
|
StateFilter(),
|
||||||
|
TypeFilter(),
|
||||||
|
YearFilter(),
|
||||||
)
|
)
|
||||||
|
|
||||||
private class GenreFilter : UriPartFilter(
|
private val genreList = arrayOf(
|
||||||
"Generos",
|
Pair("Acción", "acción"),
|
||||||
|
Pair("Aventura", "aventura"),
|
||||||
|
Pair("Angeles", "angeles"),
|
||||||
|
Pair("Artes Marciales", "artes-marciales"),
|
||||||
|
Pair("Ciencia Ficcion", "ciencia-ficcion"),
|
||||||
|
Pair("Comedia", "comedia"),
|
||||||
|
Pair("Cyberpunk", "cyberpunk"),
|
||||||
|
Pair("Demonios", "demonios"),
|
||||||
|
Pair("Deportes", "deportes"),
|
||||||
|
Pair("Dragones", "dragones"),
|
||||||
|
Pair("Drama", "drama"),
|
||||||
|
Pair("Ecchi", "ecchi"),
|
||||||
|
Pair("Escolares", "escolares"),
|
||||||
|
Pair("Fantasía", "fantasía"),
|
||||||
|
Pair("Gore", "gore"),
|
||||||
|
Pair("Harem", "harem"),
|
||||||
|
Pair("Historico", "historico"),
|
||||||
|
Pair("Horror", "horror"),
|
||||||
|
Pair("Infantil", "infantil"),
|
||||||
|
Pair("Isekai", "isekai"),
|
||||||
|
Pair("Josei", "josei"),
|
||||||
|
Pair("Juegos", "juegos"),
|
||||||
|
Pair("Magia", "magia"),
|
||||||
|
Pair("Mecha", "mecha"),
|
||||||
|
Pair("Militar", "militar"),
|
||||||
|
Pair("Misterio", "misterio"),
|
||||||
|
Pair("Música", "música"),
|
||||||
|
Pair("Ninjas", "ninjas"),
|
||||||
|
Pair("Parodias", "parodias"),
|
||||||
|
Pair("Policia", "policia"),
|
||||||
|
Pair("Psicológico", "psicológico"),
|
||||||
|
Pair("Recuerdos de la vida", "recuerdos-de-la-vida"),
|
||||||
|
Pair("Romance", "romance"),
|
||||||
|
Pair("Samurai", "samurai"),
|
||||||
|
Pair("Sci-Fi", "sci-fi"),
|
||||||
|
Pair("Seinen", "seinen"),
|
||||||
|
Pair("Shoujo", "shoujo"),
|
||||||
|
Pair("Shonen", "shonen"),
|
||||||
|
Pair("Slice of life", "slice-of-life"),
|
||||||
|
Pair("Sobrenatural", "sobrenatural"),
|
||||||
|
Pair("Space", "space"),
|
||||||
|
Pair("Spokon", "spokon"),
|
||||||
|
Pair("SteamPunk", "steampunk"),
|
||||||
|
Pair("SuperPoder", "superpoder"),
|
||||||
|
Pair("Vampiros", "vampiros"),
|
||||||
|
Pair("Yaoi", "yaoi"),
|
||||||
|
Pair("Yuri", "yuri")
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun triStateBoxesFrom(tagArray: Array<Pair<String, String>>): List<TagTriState> = tagArray.map { TagTriState(it.second) }
|
||||||
|
class TagTriState(tag: String) : AnimeFilter.CheckBox(tag, false)
|
||||||
|
class TagFilter(name: String, triStateBoxes: List<TagTriState>) : AnimeFilter.Group<TagTriState>(name, triStateBoxes)
|
||||||
|
|
||||||
|
private class YearFilter : AnimeFilter.Text("Año", "2022")
|
||||||
|
private class StateFilter : UriPartFilter(
|
||||||
|
"Estado",
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Pair("<selecionar>", ""),
|
Pair("<Seleccionar>", ""),
|
||||||
Pair("Acción", "acción"),
|
Pair("Emision", "1"),
|
||||||
Pair("Aventura", "aventura"),
|
Pair("Finalizado", "2"),
|
||||||
Pair("Angeles", "angeles"),
|
Pair("Proximamente", "3"),
|
||||||
Pair("Artes Marciales", "artes-marciales"),
|
Pair("En Cuarentena", "4")
|
||||||
Pair("Ciencia Ficcion", "ciencia-ficcion"),
|
|
||||||
Pair("Comedia", "comedia"),
|
|
||||||
Pair("Cyberpunk", "cyberpunk"),
|
|
||||||
Pair("Demonios", "demonios"),
|
|
||||||
Pair("Deportes", "deportes"),
|
|
||||||
Pair("Dragones", "dragones"),
|
|
||||||
Pair("Drama", "drama"),
|
|
||||||
Pair("Ecchi", "ecchi"),
|
|
||||||
Pair("Escolares", "escolares"),
|
|
||||||
Pair("Fantasía", "fantasía"),
|
|
||||||
Pair("Gore", "gore"),
|
|
||||||
Pair("Harem", "harem"),
|
|
||||||
Pair("Historico", "historico"),
|
|
||||||
Pair("Horror", "horror"),
|
|
||||||
Pair("Infantil", "infantil"),
|
|
||||||
Pair("Isekai", "isekai"),
|
|
||||||
Pair("Josei", "josei"),
|
|
||||||
Pair("Juegos", "juegos"),
|
|
||||||
Pair("Magia", "magia"),
|
|
||||||
Pair("Mecha", "mecha"),
|
|
||||||
Pair("Militar", "militar"),
|
|
||||||
Pair("Misterio", "misterio"),
|
|
||||||
Pair("Música", "música"),
|
|
||||||
Pair("Ninjas", "ninjas"),
|
|
||||||
Pair("Parodias", "parodias"),
|
|
||||||
Pair("Policia", "policia"),
|
|
||||||
Pair("Psicológico", "psicológico"),
|
|
||||||
Pair("Recuerdos de la vida", "recuerdos-de-la-vida"),
|
|
||||||
Pair("Romance", "romance"),
|
|
||||||
Pair("Samurai", "samurai"),
|
|
||||||
Pair("Sci-Fi", "sci-fi"),
|
|
||||||
Pair("Seinen", "seinen"),
|
|
||||||
Pair("Shoujo", "shoujo"),
|
|
||||||
Pair("Shonen", "shonen"),
|
|
||||||
Pair("Slice of life", "slice-of-life"),
|
|
||||||
Pair("Sobrenatural", "sobrenatural"),
|
|
||||||
Pair("Space", "space"),
|
|
||||||
Pair("Spokon", "spokon"),
|
|
||||||
Pair("SteamPunk", "steampunk"),
|
|
||||||
Pair("SuperPoder", "superpoder"),
|
|
||||||
Pair("Vampiros", "vampiros"),
|
|
||||||
Pair("Yaoi", "yaoi"),
|
|
||||||
Pair("Yuri", "yuri")
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
private class TypeFilter : UriPartFilter(
|
||||||
|
"Tipo",
|
||||||
|
arrayOf(
|
||||||
|
Pair("<Seleccionar>", ""),
|
||||||
|
Pair("TV", "tv"),
|
||||||
|
Pair("Pelicula", "movie"),
|
||||||
|
Pair("Especial", "special"),
|
||||||
|
Pair("OVA", "ova")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) :
|
private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) :
|
||||||
AnimeFilter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
|
AnimeFilter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
|
||||||
fun toUriPart() = vals[state].second
|
fun toUriPart() = vals[state].second
|
||||||
@ -286,14 +357,14 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
"Okru:1080p", "Okru:720p", "Okru:480p", "Okru:360p", "Okru:240p", "Okru:144p", // Okru
|
"Okru:1080p", "Okru:720p", "Okru:480p", "Okru:360p", "Okru:240p", "Okru:144p", // Okru
|
||||||
"Fembed:1080p", "Fembed:720p", "Fembed:480p", "Fembed:360p", "Fembed:240p", "Fembed:144p", // Fembed
|
"Fembed:1080p", "Fembed:720p", "Fembed:480p", "Fembed:360p", "Fembed:240p", "Fembed:144p", // Fembed
|
||||||
"StreamSB:1080p", "StreamSB:720p", "StreamSB:480p", "StreamSB:360p", "StreamSB:240p", "StreamSB:144p", // StreamSB
|
"StreamSB:1080p", "StreamSB:720p", "StreamSB:480p", "StreamSB:360p", "StreamSB:240p", "StreamSB:144p", // StreamSB
|
||||||
"Amazon", "AmazonES", "StreamTape"
|
"Amazon", "AmazonES", "StreamTape","Fireload","Mp4upload"
|
||||||
) // video servers without resolution
|
)
|
||||||
entryValues = arrayOf(
|
entryValues = arrayOf(
|
||||||
"Okru:1080p", "Okru:720p", "Okru:480p", "Okru:360p", "Okru:240p", "Okru:144p", // Okru
|
"Okru:1080p", "Okru:720p", "Okru:480p", "Okru:360p", "Okru:240p", "Okru:144p", // Okru
|
||||||
"Fembed:1080p", "Fembed:720p", "Fembed:480p", "Fembed:360p", "Fembed:240p", "Fembed:144p", // Fembed
|
"Fembed:1080p", "Fembed:720p", "Fembed:480p", "Fembed:360p", "Fembed:240p", "Fembed:144p", // Fembed
|
||||||
"StreamSB:1080p", "StreamSB:720p", "StreamSB:480p", "StreamSB:360p", "StreamSB:240p", "StreamSB:144p", // StreamSB
|
"StreamSB:1080p", "StreamSB:720p", "StreamSB:480p", "StreamSB:360p", "StreamSB:240p", "StreamSB:144p", // StreamSB
|
||||||
"Amazon", "AmazonES", "StreamTape"
|
"Amazon", "AmazonES", "StreamTape","Fireload","Mp4upload"
|
||||||
) // video servers without resolution
|
)
|
||||||
setDefaultValue("Amazon")
|
setDefaultValue("Amazon")
|
||||||
summary = "%s"
|
summary = "%s"
|
||||||
|
|
||||||
@ -304,6 +375,7 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
preferences.edit().putString(key, entry).commit()
|
preferences.edit().putString(key, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(videoQualityPref)
|
screen.addPreference(videoQualityPref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package eu.kanade.tachiyomi.animeextension.es.animefenix.extractors
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
|
import okhttp3.Headers
|
||||||
|
import org.jsoup.Connection
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
|
class Mp4uploadExtractor {
|
||||||
|
fun getVideoFromUrl(url: String, headers: Headers): Video {
|
||||||
|
val id = url.substringAfterLast("embed-").substringBeforeLast(".html")
|
||||||
|
return try {
|
||||||
|
val videoUrl = Jsoup.connect(url).data(
|
||||||
|
mutableMapOf(
|
||||||
|
"op" to "download2",
|
||||||
|
"id" to id,
|
||||||
|
"rand" to "",
|
||||||
|
"referer" to url,
|
||||||
|
"method_free" to "+",
|
||||||
|
"method_premiun" to "",
|
||||||
|
)
|
||||||
|
).method(Connection.Method.POST).ignoreContentType(true)
|
||||||
|
.ignoreHttpErrors(true).execute().url().toString()
|
||||||
|
Video(videoUrl, "Mp4Upload", videoUrl, headers)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Video("", "", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user