From 234ffeeca607b493f6693892283dce9d999c2891 Mon Sep 17 00:00:00 2001 From: imper1aldev <23511335+imper1aldev@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:14:22 -0600 Subject: [PATCH] VerAnimes improvements --- src/es/veranimes/build.gradle | 2 +- .../animeextension/es/veranimes/VerAnimes.kt | 69 +-------- .../es/veranimes/VerAnimesFilters.kt | 146 ++++++++++++++++++ 3 files changed, 155 insertions(+), 62 deletions(-) create mode 100644 src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimesFilters.kt diff --git a/src/es/veranimes/build.gradle b/src/es/veranimes/build.gradle index 1b55eb6a..ef979c73 100644 --- a/src/es/veranimes/build.gradle +++ b/src/es/veranimes/build.gradle @@ -1,7 +1,7 @@ ext { extName = 'VerAnimes' extClass = '.VerAnimes' - extVersionCode = 2 + extVersionCode = 3 } apply from: "$rootDir/common.gradle" diff --git a/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimes.kt b/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimes.kt index 93a849ba..ed164c6f 100644 --- a/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimes.kt +++ b/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimes.kt @@ -6,7 +6,6 @@ import androidx.preference.ListPreference import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.animeextension.es.veranimes.extractors.VidGuardExtractor import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource -import eu.kanade.tachiyomi.animesource.model.AnimeFilter import eu.kanade.tachiyomi.animesource.model.AnimeFilterList import eu.kanade.tachiyomi.animesource.model.AnimesPage import eu.kanade.tachiyomi.animesource.model.SAnime @@ -64,10 +63,14 @@ class VerAnimes : ConfigurableAnimeSource, AnimeHttpSource() { val document = response.asJsoup() val animeDetails = SAnime.create().apply { title = document.selectFirst(".ti h1")?.text()?.trim() ?: "" - status = SAnime.UNKNOWN description = document.selectFirst(".r .tx p")?.text() genre = document.select(".gn li a").joinToString { it.text() } thumbnail_url = document.selectFirst(".info figure img")?.attr("abs:data-src") + status = when { + document.select(".em").any() -> SAnime.ONGOING + document.select(".fi").any() -> SAnime.COMPLETED + else -> SAnime.UNKNOWN + } document.select(".info .u:not(.sp) > li").map { it.text() }.map { textContent -> when { "Estudio" in textContent -> author = textContent.substringAfter("Estudio(s):").trim() @@ -99,12 +102,11 @@ class VerAnimes : ConfigurableAnimeSource, AnimeHttpSource() { override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/animes?estado=en-emision&orden=desc&pag=$page", headers) override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { - val filterList = if (filters.isEmpty()) getFilterList() else filters - val genreFilter = filterList.find { it is GenreFilter } as GenreFilter + val params = VerAnimesFilters.getSearchParameters(filters) return when { query.isNotBlank() -> GET("$baseUrl/animes?buscar=$query&pag=$page", headers) - genreFilter.state != 0 -> GET("$baseUrl/animes?genero=${genreFilter.toUriPart()}&orden=desc&pag=$page", headers) + params.filter.isNotBlank() -> GET("$baseUrl/animes${params.getQuery()}&pag=$page", headers) else -> popularAnimeRequest(page) } } @@ -188,62 +190,7 @@ class VerAnimes : ConfigurableAnimeSource, AnimeHttpSource() { ).reversed() } - override fun getFilterList(): AnimeFilterList = AnimeFilterList( - AnimeFilter.Header("La busqueda por texto ignora el filtro"), - GenreFilter(), - ) - - private class GenreFilter : UriPartFilter( - "Género", - arrayOf( - Pair("", ""), - Pair("Acción", "accion"), - Pair("Artes Marciales", "artes-marciales"), - Pair("Aventuras", "aventuras"), - Pair("Carreras", "carreras"), - Pair("Ciencia Ficción", "ciencia-ficcion"), - Pair("Comedia", "comedia"), - Pair("Demencia", "demencia"), - Pair("Demonios", "demonios"), - Pair("Deportes", "deportes"), - Pair("Drama", "drama"), - Pair("Ecchi", "ecchi"), - Pair("Escolares", "escolares"), - Pair("Espacial", "espacial"), - Pair("Fantasía", "fantasia"), - Pair("Harem", "harem"), - Pair("Historico", "historico"), - Pair("Infantil", "infantil"), - Pair("Josei", "josei"), - Pair("Juegos", "juegos"), - Pair("Magia", "magia"), - Pair("Mecha", "mecha"), - Pair("Militar", "militar"), - Pair("Misterio", "misterio"), - Pair("Música", "musica"), - Pair("Parodia", "parodia"), - Pair("Policía", "policia"), - Pair("Psicológico", "psicologico"), - Pair("Recuentos de la vida", "recuentos-de-la-vida"), - Pair("Romance", "romance"), - Pair("Samurai", "samurai"), - Pair("Seinen", "seinen"), - Pair("Shoujo", "shoujo"), - Pair("Shounen", "shounen"), - Pair("Sobrenatural", "sobrenatural"), - Pair("Superpoderes", "superpoderes"), - Pair("Suspenso", "suspenso"), - Pair("Terror", "terror"), - Pair("Vampiros", "vampiros"), - Pair("Yaoi", "yaoi"), - Pair("Yuri", "yuri"), - ), - ) - - private open class UriPartFilter(displayName: String, val vals: Array>) : - AnimeFilter.Select(displayName, vals.map { it.first }.toTypedArray()) { - fun toUriPart() = vals[state].second - } + override fun getFilterList(): AnimeFilterList = VerAnimesFilters.FILTER_LIST override fun setupPreferenceScreen(screen: PreferenceScreen) { ListPreference(screen.context).apply { diff --git a/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimesFilters.kt b/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimesFilters.kt new file mode 100644 index 00000000..0000961f --- /dev/null +++ b/src/es/veranimes/src/eu/kanade/tachiyomi/animeextension/es/veranimes/VerAnimesFilters.kt @@ -0,0 +1,146 @@ +package eu.kanade.tachiyomi.animeextension.es.veranimes + +import eu.kanade.tachiyomi.animesource.model.AnimeFilter +import eu.kanade.tachiyomi.animesource.model.AnimeFilterList + +object VerAnimesFilters { + open class QueryPartFilter(displayName: String, val vals: Array>) : AnimeFilter.Select( + 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) : AnimeFilter.Group(name, values) + + private class CheckBoxVal(name: String, state: Boolean = false) : AnimeFilter.CheckBox(name, state) + + private inline fun AnimeFilterList.parseCheckbox( + options: Array>, + name: String, + ): String { + return (this.getFirst() as CheckBoxFilterList).state + .mapNotNull { checkbox -> + if (checkbox.state) { + options.find { it.first == checkbox.name }!!.second + } else { + null + } + }.joinToString(",").let { + if (it.isBlank()) { + "" + } else { + "&$name=$it" + } + } + } + + private inline fun AnimeFilterList.asQueryPart(name: String): String { + return (this.getFirst() as QueryPartFilter).toQueryPart(name) + } + + private inline fun AnimeFilterList.getFirst(): R { + return this.filterIsInstance().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(VerAnimesFiltersData.GENRES, "genero") + + filters.parseCheckbox(VerAnimesFiltersData.YEARS, "anio") + + filters.parseCheckbox(VerAnimesFiltersData.TYPES, "tipo") + + filters.asQueryPart("estado") + + filters.asQueryPart("orden"), + ) + } + + val FILTER_LIST get() = AnimeFilterList( + AnimeFilter.Header("La busqueda por texto ignora el filtro"), + GenresFilter(), + YearsFilter(), + TypesFilter(), + StateFilter(), + SortFilter(), + ) + + class GenresFilter : CheckBoxFilterList("Género", VerAnimesFiltersData.GENRES.map { CheckBoxVal(it.first, false) }) + + class YearsFilter : CheckBoxFilterList("Año", VerAnimesFiltersData.YEARS.map { CheckBoxVal(it.first, false) }) + + class TypesFilter : CheckBoxFilterList("Tipo", VerAnimesFiltersData.TYPES.map { CheckBoxVal(it.first, false) }) + + class StateFilter : QueryPartFilter("Estado", VerAnimesFiltersData.STATE) + + class SortFilter : QueryPartFilter("Orden", VerAnimesFiltersData.SORT) + + private object VerAnimesFiltersData { + + val YEARS = (1967..2024).map { Pair("$it", "$it") }.reversed().toTypedArray() + + val TYPES = arrayOf( + Pair("Tv", "tv"), + Pair("Película", "pelicula"), + Pair("Especial", "especial"), + Pair("Ova", "ova"), + ) + + val STATE = arrayOf( + Pair("Todos", ""), + Pair("En Emisión", "en-emision"), + Pair("Finalizado", "finalizado"), + Pair("Próximamente", "proximamente"), + ) + + val SORT = arrayOf( + Pair("Descendente", "desc"), + Pair("Ascendente", "asc"), + ) + + val GENRES = arrayOf( + Pair("Acción", "accion"), + Pair("Artes Marciales", "artes-marciales"), + Pair("Aventuras", "aventuras"), + Pair("Carreras", "carreras"), + Pair("Ciencia Ficción", "ciencia-ficcion"), + Pair("Comedia", "comedia"), + Pair("Demencia", "demencia"), + Pair("Demonios", "demonios"), + Pair("Deportes", "deportes"), + Pair("Drama", "drama"), + Pair("Ecchi", "ecchi"), + Pair("Escolares", "escolares"), + Pair("Espacial", "espacial"), + Pair("Fantasía", "fantasia"), + Pair("Harem", "harem"), + Pair("Historico", "historico"), + Pair("Infantil", "infantil"), + Pair("Josei", "josei"), + Pair("Juegos", "juegos"), + Pair("Magia", "magia"), + Pair("Mecha", "mecha"), + Pair("Militar", "militar"), + Pair("Misterio", "misterio"), + Pair("Música", "musica"), + Pair("Parodia", "parodia"), + Pair("Policía", "policia"), + Pair("Psicológico", "psicologico"), + Pair("Recuentos de la vida", "recuentos-de-la-vida"), + Pair("Romance", "romance"), + Pair("Samurai", "samurai"), + Pair("Seinen", "seinen"), + Pair("Shoujo", "shoujo"), + Pair("Shounen", "shounen"), + Pair("Sobrenatural", "sobrenatural"), + Pair("Superpoderes", "superpoderes"), + Pair("Suspenso", "suspenso"), + Pair("Terror", "terror"), + Pair("Vampiros", "vampiros"), + Pair("Yaoi", "yaoi"), + Pair("Yuri", "yuri"), + ) + } +}