Dead source (#518)

This commit is contained in:
Hak 2025-01-11 19:16:04 +07:00 committed by GitHub
parent 8158afc567
commit 527dc0e0cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 0 additions and 519 deletions

View file

@ -1,24 +0,0 @@
ext {
extName = 'Animefenix'
extClass = '.Animefenix'
extVersionCode = 43
}
apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(':lib:mp4upload-extractor'))
implementation(project(':lib:streamtape-extractor'))
implementation(project(':lib:yourupload-extractor'))
implementation(project(':lib:uqload-extractor'))
implementation(project(':lib:okru-extractor'))
implementation(project(':lib:burstcloud-extractor'))
implementation(project(':lib:streamwish-extractor'))
implementation(project(':lib:filemoon-extractor'))
implementation(project(':lib:voe-extractor'))
implementation(project(':lib:streamlare-extractor'))
implementation(project(':lib:fastream-extractor'))
implementation(project(':lib:dood-extractor'))
implementation(project(':lib:upstream-extractor'))
implementation(project(':lib:streamhidevid-extractor'))
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View file

@ -1,161 +0,0 @@
package eu.kanade.tachiyomi.animeextension.es.animefenix
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import java.util.Calendar
object AnimeFenixFilters {
open class QueryPartFilter(displayName: String, val vals: Array<Pair<String, String>>) : AnimeFilter.Select<String>(
displayName,
vals.map { it.first }.toTypedArray(),
) {
fun toQueryPart(name: String) = vals[state].second.takeIf { it.isNotEmpty() }?.let { "&$name=${vals[state].second}" } ?: run { "" }
}
open class CheckBoxFilterList(name: String, values: List<CheckBox>) : AnimeFilter.Group<AnimeFilter.CheckBox>(name, values)
private class CheckBoxVal(name: String, state: Boolean = false) : AnimeFilter.CheckBox(name, state)
private inline fun <reified R> AnimeFilterList.parseCheckbox(
options: Array<Pair<String, String>>,
name: String,
): String {
return (this.getFirst<R>() as CheckBoxFilterList).state
.mapNotNull { checkbox ->
if (checkbox.state) {
options.find { it.first == checkbox.name }!!.second
} else {
null
}
}.joinToString("&$name[]=").let {
if (it.isBlank()) {
""
} else {
"&$name[]=$it"
}
}
}
private inline fun <reified R> AnimeFilterList.asQueryPart(name: String): String {
return (this.getFirst<R>() as QueryPartFilter).toQueryPart(name)
}
private inline fun <reified R> AnimeFilterList.getFirst(): R {
return this.filterIsInstance<R>().first()
}
private fun String.changePrefix() = this.takeIf { it.startsWith("&") }?.let { this.replaceFirst("&", "?") } ?: run { this }
data class FilterSearchParams(val filter: String = "") { fun getQuery() = filter.changePrefix() }
internal fun getSearchParameters(filters: AnimeFilterList): FilterSearchParams {
if (filters.isEmpty()) return FilterSearchParams()
return FilterSearchParams(
filters.parseCheckbox<GenresFilter>(AnimeFenixFiltersData.GENRES, "genero") +
filters.parseCheckbox<YearsFilter>(AnimeFenixFiltersData.YEARS, "year") +
filters.parseCheckbox<TypesFilter>(AnimeFenixFiltersData.TYPES, "type") +
filters.parseCheckbox<StateFilter>(AnimeFenixFiltersData.STATE, "estado") +
filters.asQueryPart<SortFilter>("order"),
)
}
val FILTER_LIST get() = AnimeFilterList(
AnimeFilter.Header("La busqueda por texto ignora el filtro"),
GenresFilter(),
YearsFilter(),
TypesFilter(),
StateFilter(),
SortFilter(),
)
class GenresFilter : CheckBoxFilterList("Género", AnimeFenixFiltersData.GENRES.map { CheckBoxVal(it.first, false) })
class YearsFilter : CheckBoxFilterList("Año", AnimeFenixFiltersData.YEARS.map { CheckBoxVal(it.first, false) })
class TypesFilter : CheckBoxFilterList("Tipo", AnimeFenixFiltersData.TYPES.map { CheckBoxVal(it.first, false) })
class StateFilter : CheckBoxFilterList("Estado", AnimeFenixFiltersData.STATE.map { CheckBoxVal(it.first, false) })
class SortFilter : QueryPartFilter("Orden", AnimeFenixFiltersData.SORT)
object AnimeFenixFiltersData {
val YEARS = (1990..Calendar.getInstance().get(Calendar.YEAR)).map { Pair("$it", "$it") }.reversed().toTypedArray()
val TYPES = arrayOf(
Pair("TV", "tv"),
Pair("Película", "movie"),
Pair("Especial", "special"),
Pair("OVA", "ova"),
Pair("DONGHUA", "donghua"),
)
val STATE = arrayOf(
Pair("Emisión", "1"),
Pair("Finalizado", "2"),
Pair("Próximamente", "3"),
Pair("En Cuarentena", "4"),
)
val SORT = arrayOf(
Pair("Por Defecto", "default"),
Pair("Recientemente Actualizados", "updated"),
Pair("Recientemente Agregados", "added"),
Pair("Nombre A-Z", "title"),
Pair("Calificación", "likes"),
Pair("Más Vistos", "visits"),
)
val GENRES = arrayOf(
Pair("Acción", "accion"),
Pair("Ángeles", "angeles"),
Pair("Artes Marciales", "artes-marciales"),
Pair("Aventura", "aventura"),
Pair("Ciencia Ficción", "Ciencia Ficción"),
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", "fantasia"),
Pair("Gore", "gore"),
Pair("Harem", "harem"),
Pair("Histórico", "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", "Musica"),
Pair("Ninjas", "ninjas"),
Pair("Parodia", "parodia"),
Pair("Policía", "policia"),
Pair("Psicológico", "psicologico"),
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("Shoujo Ai", "shoujo-ai"),
Pair("Shounen", "shounen"),
Pair("Slice of life", "slice-of-life"),
Pair("Sobrenatural", "sobrenatural"),
Pair("Space", "space"),
Pair("Spokon", "spokon"),
Pair("Steampunk", "steampunk"),
Pair("Superpoder", "superpoder"),
Pair("Thriller", "thriller"),
Pair("Vampiro", "vampiro"),
Pair("Yaoi", "yaoi"),
Pair("Yuri", "yuri"),
Pair("Zombies", "zombies"),
)
}
}

View file

@ -1,307 +0,0 @@
package eu.kanade.tachiyomi.animeextension.es.animefenix
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import eu.kanade.tachiyomi.lib.burstcloudextractor.BurstCloudExtractor
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
import eu.kanade.tachiyomi.lib.fastreamextractor.FastreamExtractor
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
import eu.kanade.tachiyomi.lib.streamhidevidextractor.StreamHideVidExtractor
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
import eu.kanade.tachiyomi.lib.upstreamextractor.UpstreamExtractor
import eu.kanade.tachiyomi.lib.uqloadextractor.UqloadExtractor
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import okhttp3.Response
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.net.URLDecoder
class Animefenix : ConfigurableAnimeSource, AnimeHttpSource() {
override val name = "AnimeFenix"
override val baseUrl = "https://www.animefenix.tv"
override val lang = "es"
override val supportsLatest = true
private val preferences: SharedPreferences by lazy { Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) }
private object CSSQuery {
object AnimeList {
const val GRID = "main div.container div.grid"
const val ELEMENT = "a"
const val ELEMENT_URL = "a"
const val ELEMENT_TITLE = "div div h3"
const val ELEMENT_THUMBNAIL_URL = "img"
const val ELEMENT_STATUS = "div div span.bg-zinc-700"
const val NEXT = "a:has(span.sr-only:contains(Next))"
}
object EpisodeList {
const val EPISODE = "div.container div.bg-zinc-800 ul li"
const val NUMBER = "a span span"
const val URL = "a"
}
}
companion object {
private const val PREF_QUALITY_KEY = "preferred_quality"
private const val PREF_QUALITY_DEFAULT = "1080"
private val QUALITY_LIST = arrayOf("1080", "720", "480", "360")
private const val PREF_SERVER_KEY = "preferred_server"
private const val PREF_SERVER_DEFAULT = "Amazon"
private val SERVER_LIST = arrayOf(
"YourUpload", "Voe", "Mp4Upload", "Doodstream",
"Upload", "BurstCloud", "Upstream", "StreamTape",
"Fastream", "Filemoon", "StreamWish", "Okru",
"Amazon", "AmazonES", "Fireload", "FileLions",
)
}
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/animes?order=likes&page=$page")
override fun popularAnimeParse(response: Response): AnimesPage {
val document = response.asJsoup()
val grid = document.select(CSSQuery.AnimeList.GRID)[1]
val elements = grid.select(CSSQuery.AnimeList.ELEMENT)
val nextPage = document.select(CSSQuery.AnimeList.NEXT).any()
val animeList = elements.map { element ->
SAnime.create().apply {
setUrlWithoutDomain(element.select(CSSQuery.AnimeList.ELEMENT_URL).attr("abs:href"))
title = element.select(CSSQuery.AnimeList.ELEMENT_TITLE).text()
thumbnail_url = element.select(CSSQuery.AnimeList.ELEMENT_THUMBNAIL_URL).attr("abs:src")
status = parseStatus(element.select(CSSQuery.AnimeList.ELEMENT_STATUS).text())
}
}
return AnimesPage(animeList, nextPage)
}
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/animes?order=added&page=$page")
override fun latestUpdatesParse(response: Response) = popularAnimeParse(response)
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val params = AnimeFenixFilters.getSearchParameters(filters)
return when {
query.isNotBlank() -> GET("$baseUrl/animes?q=$query&page=$page", headers)
params.filter.isNotBlank() -> GET("$baseUrl/animes${params.getQuery()}&page=$page", headers)
else -> GET("$baseUrl/animes?order=likes&page=$page")
}
}
override fun searchAnimeParse(response: Response) = popularAnimeParse(response)
override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup()
return document.select(CSSQuery.EpisodeList.EPISODE).map { it ->
val epNum = it.select(CSSQuery.EpisodeList.NUMBER).text().replace("Episodio", "")
SEpisode.create().apply {
episode_number = epNum.toFloat()
name = "Episodio $epNum"
setUrlWithoutDomain(it.select(CSSQuery.EpisodeList.URL).attr("abs:href"))
}
}
}
override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup()
val videoList = mutableListOf<Video>()
val servers = document.selectFirst("script:containsData(var tabsArray)")!!.data()
.split("\n")
.filter { it.contains("tabsArray[") }
.map { it.split(" = ").last().trim().trim(';').trim('"') }
.filter { it.contains("https") }
servers.forEach { server ->
val decodedUrl = URLDecoder.decode(server, "UTF-8")
val realUrl = try {
client.newCall(GET(decodedUrl)).execute().asJsoup().selectFirst("script")!!
.data().substringAfter("src=\"").substringBefore("\"")
} catch (e: Exception) { "" }
try {
serverVideoResolver(realUrl).let { videoList.addAll(it) }
} catch (_: Exception) { }
}
return videoList.filter { it.url.contains("https") || it.url.contains("http") }
}
private fun serverVideoResolver(url: String): List<Video> {
val videoList = mutableListOf<Video>()
val embedUrl = url.lowercase()
try {
if (embedUrl.contains("voe")) {
VoeExtractor(client).videosFromUrl(url).also(videoList::addAll)
}
if ((embedUrl.contains("amazon") || embedUrl.contains("amz")) && !embedUrl.contains("disable")) {
val video = amazonExtractor(baseUrl + url.substringAfter(".."))
if (video.isNotBlank()) {
if (url.contains("&ext=es")) {
videoList.add(Video(video, "AmazonES", video))
} else {
videoList.add(Video(video, "Amazon", video))
}
}
}
if (embedUrl.contains("ok.ru") || embedUrl.contains("okru")) {
OkruExtractor(client).videosFromUrl(url).also(videoList::addAll)
}
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
val vidHeaders = headers.newBuilder()
.add("Origin", "https://${url.toHttpUrl().host}")
.add("Referer", "https://${url.toHttpUrl().host}/")
.build()
FilemoonExtractor(client).videosFromUrl(url, prefix = "Filemoon:", headers = vidHeaders).also(videoList::addAll)
}
if (embedUrl.contains("uqload")) {
UqloadExtractor(client).videosFromUrl(url).also(videoList::addAll)
}
if (embedUrl.contains("mp4upload")) {
Mp4uploadExtractor(client).videosFromUrl(url, headers).let { videoList.addAll(it) }
}
if (embedUrl.contains("wishembed") || embedUrl.contains("embedwish") || embedUrl.contains("streamwish") || embedUrl.contains("strwish") || embedUrl.contains("wish")) {
val docHeaders = headers.newBuilder()
.add("Origin", "https://streamwish.to")
.add("Referer", "https://streamwish.to/")
.build()
StreamWishExtractor(client, docHeaders).videosFromUrl(url, videoNameGen = { "StreamWish:$it" }).also(videoList::addAll)
}
if (embedUrl.contains("doodstream") || embedUrl.contains("dood.")) {
DoodExtractor(client).videoFromUrl(url, "DoodStream", false)?.let { videoList.add(it) }
}
if (embedUrl.contains("streamlare")) {
StreamlareExtractor(client).videosFromUrl(url).let { videoList.addAll(it) }
}
if (embedUrl.contains("yourupload") || embedUrl.contains("upload")) {
YourUploadExtractor(client).videoFromUrl(url, headers = headers).let { videoList.addAll(it) }
}
if (embedUrl.contains("burstcloud") || embedUrl.contains("burst")) {
BurstCloudExtractor(client).videoFromUrl(url, headers = headers).let { videoList.addAll(it) }
}
if (embedUrl.contains("fastream")) {
FastreamExtractor(client, headers).videosFromUrl(url).also(videoList::addAll)
}
if (embedUrl.contains("upstream")) {
UpstreamExtractor(client).videosFromUrl(url).let { videoList.addAll(it) }
}
if (embedUrl.contains("streamtape") || embedUrl.contains("stp") || embedUrl.contains("stape")) {
StreamTapeExtractor(client).videoFromUrl(url)?.let { videoList.add(it) }
}
if (embedUrl.contains("ahvsh") || embedUrl.contains("streamhide")) {
StreamHideVidExtractor(client).videosFromUrl(url).let { videoList.addAll(it) }
}
if (embedUrl.contains("/stream/fl.php")) {
val video = url.substringAfter("/stream/fl.php?v=")
if (client.newCall(GET(video)).execute().code == 200) {
videoList.add(Video(video, "FireLoad", video))
}
}
if (embedUrl.contains("filelions") || embedUrl.contains("lion")) {
StreamWishExtractor(client, headers).videosFromUrl(url, videoNameGen = { "FileLions:$it" }).also(videoList::addAll)
}
} catch (_: Exception) { }
return videoList
}
override fun List<Video>.sort(): List<Video> {
val quality = preferences.getString(PREF_QUALITY_KEY, PREF_QUALITY_DEFAULT)!!
val server = preferences.getString(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)!!
return this.sortedWith(
compareBy(
{ it.quality.contains(server, true) },
{ it.quality.contains(quality) },
{ Regex("""(\d+)p""").find(it.quality)?.groupValues?.get(1)?.toIntOrNull() ?: 0 },
),
).reversed()
}
override fun animeDetailsParse(response: Response) = SAnime.create().apply {
val document = response.asJsoup()
with(document.selectFirst("main > div.relative > div.container > div.flex")!!) {
title = selectFirst("h1.font-bold")!!.ownText()
genre = select("div:has(h2:containsOwn(Géneros)) > div.flex > a").joinToString { it.text() }
status = parseStatus(selectFirst("li:has(> span:containsOwn(Estado))")!!.ownText())
description = select("div:has(h2:containsOwn(Sinopsis)) > p").text()
}
}
private fun parseStatus(statusString: String): Int {
return when {
statusString.contains("Emisión") -> SAnime.ONGOING
statusString.contains("Finalizado") -> SAnime.COMPLETED
else -> SAnime.UNKNOWN
}
}
private fun amazonExtractor(url: String): String {
val document = client.newCall(GET(url)).execute().asJsoup()
val videoURl = document.selectFirst("script:containsData(sources: [)")!!.data()
.substringAfter("[{\"file\":\"")
.substringBefore("\",").replace("\\", "")
return try {
if (client.newCall(GET(videoURl)).execute().code == 200) videoURl else ""
} catch (e: Exception) {
""
}
}
override fun getFilterList(): AnimeFilterList = AnimeFenixFilters.FILTER_LIST
override fun setupPreferenceScreen(screen: PreferenceScreen) {
ListPreference(screen.context).apply {
key = PREF_QUALITY_KEY
title = "Preferred quality"
entries = QUALITY_LIST
entryValues = QUALITY_LIST
setDefaultValue(PREF_QUALITY_DEFAULT)
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit()
}
}.also(screen::addPreference)
ListPreference(screen.context).apply {
key = PREF_SERVER_KEY
title = "Preferred server"
entries = SERVER_LIST
entryValues = SERVER_LIST
setDefaultValue(PREF_SERVER_DEFAULT)
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit()
}
}.also(screen::addPreference)
}
}

View file

@ -1,27 +0,0 @@
package eu.kanade.tachiyomi.animeextension.es.animefenix.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class SolidFilesExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
val videoList = mutableListOf<Video>()
return try {
val document = client.newCall(GET(url)).execute().asJsoup()
document.select("script").forEach { script ->
if (script.data().contains("\"downloadUrl\":")) {
val data = script.data().substringAfter("\"downloadUrl\":").substringBefore(",")
val url = data.replace("\"", "")
val videoUrl = url
val quality = prefix + "SolidFiles"
videoList.add(Video(videoUrl, quality, videoUrl))
}
}
videoList
} catch (e: Exception) {
videoList
}
}
}