From 99f355d65bd30924f0b8b49a880c633aa263871c Mon Sep 17 00:00:00 2001 From: bapeey <90949336+bapeey@users.noreply.github.com> Date: Mon, 4 Mar 2024 05:33:33 -0500 Subject: [PATCH] LeerCapitulo: Add filters (#1679) * Add filters * Bump --- src/es/leercapitulo/build.gradle | 2 +- .../extension/es/leercapitulo/LeerCapitulo.kt | 71 +++++++++-- .../es/leercapitulo/LeerCapituloFilters.kt | 118 ++++++++++++++++++ 3 files changed, 182 insertions(+), 9 deletions(-) create mode 100644 src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapituloFilters.kt diff --git a/src/es/leercapitulo/build.gradle b/src/es/leercapitulo/build.gradle index cbb986808..b56b1b2f5 100644 --- a/src/es/leercapitulo/build.gradle +++ b/src/es/leercapitulo/build.gradle @@ -1,7 +1,7 @@ ext { extName = 'LeerCapitulo' extClass = '.LeerCapitulo' - extVersionCode = 7 + extVersionCode = 8 } apply from: "$rootDir/common.gradle" diff --git a/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapitulo.kt b/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapitulo.kt index 5ca21c35b..767514b18 100644 --- a/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapitulo.kt +++ b/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapitulo.kt @@ -4,6 +4,7 @@ import android.util.Base64 import eu.kanade.tachiyomi.lib.synchrony.Deobfuscator import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.interceptor.rateLimitHost +import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.Page @@ -52,13 +53,54 @@ class LeerCapitulo : ParsedHttpSource() { override fun popularMangaNextPageSelector(): String? = null override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = "$baseUrl/search-autocomplete".toHttpUrl().newBuilder() - .addQueryParameter("term", query) + val urlBuilder = baseUrl.toHttpUrl().newBuilder() - return GET(url.build(), headers) + if (query.isNotBlank()) { + urlBuilder.addPathSegment("search-autocomplete") + urlBuilder.addQueryParameter("term", query) + + return GET(urlBuilder.build(), headers) + } else { + for (filter in filters) { + when (filter) { + is GenreFilter -> { + if (filter.state != 0) { + urlBuilder.addPathSegment("genre") + urlBuilder.addPathSegment(filter.toUriPart()) + break + } + } + is AlphabeticFilter -> { + if (filter.state != 0) { + urlBuilder.addPathSegment("initial") + urlBuilder.addPathSegment(filter.toUriPart()) + break + } + } + is StatusFilter -> { + if (filter.state != 0) { + urlBuilder.addPathSegment("status") + urlBuilder.addPathSegment(filter.toUriPart()) + break + } + } + else -> {} + } + } + urlBuilder.addPathSegment("") // Empty path segment to avoid 404 + urlBuilder.addQueryParameter("page", page.toString()) + } + val url = urlBuilder.build() + if (url.pathSegments.size <= 1) throw Exception("Debe seleccionar un filtro o realizar una búsqueda por texto.") + + return GET(url, headers) } override fun searchMangaParse(response: Response): MangasPage { + if (!response.request.url.pathSegments.contains("search-autocomplete")) { + return super.searchMangaParse(response) + } + val mangas = json.decodeFromString>(response.body.string()).map { SManga.create().apply { setUrlWithoutDomain(it.link) @@ -70,11 +112,25 @@ class LeerCapitulo : ParsedHttpSource() { return MangasPage(mangas, hasNextPage = false) } - override fun searchMangaSelector(): String = throw UnsupportedOperationException() + override fun searchMangaSelector(): String = "div.cate-manga div.mainpage-manga" - override fun searchMangaFromElement(element: Element): SManga = throw UnsupportedOperationException() + override fun searchMangaFromElement(element: Element) = SManga.create().apply { + setUrlWithoutDomain(element.selectFirst("div.media-body a")!!.attr("href")) + title = element.selectFirst("div.media-body a")!!.text() + thumbnail_url = element.selectFirst("img")!!.imgAttr() + } - override fun searchMangaNextPageSelector(): String? = null + override fun searchMangaNextPageSelector(): String = "ul.pagination > li.active + li" + + override fun getFilterList(): FilterList { + return FilterList( + Filter.Header("Los filtros serán ignorados si se realiza una búsqueda por texto."), + Filter.Header("Los filtros no se pueden combinar entre ellos."), + GenreFilter(), + AlphabeticFilter(), + StatusFilter(), + ) + } override fun latestUpdatesRequest(page: Int): Request = popularMangaRequest(page) @@ -167,10 +223,9 @@ class LeerCapitulo : ParsedHttpSource() { } @Serializable - data class MangaDto( + class MangaDto( val label: String, val link: String, val thumbnail: String, - val value: String, ) } diff --git a/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapituloFilters.kt b/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapituloFilters.kt new file mode 100644 index 000000000..c40c12e63 --- /dev/null +++ b/src/es/leercapitulo/src/eu/kanade/tachiyomi/extension/es/leercapitulo/LeerCapituloFilters.kt @@ -0,0 +1,118 @@ +package eu.kanade.tachiyomi.extension.es.leercapitulo + +import eu.kanade.tachiyomi.source.model.Filter + +class GenreFilter : UriPartFilter( + "Género", + arrayOf( + Pair("", ""), + Pair("Acción", "accion"), + Pair("Animación", "animacion"), + Pair("Apocalíptico", "apocaliptico"), + Pair("Artes Marciales", "artes-marciales"), + Pair("Aventura", "aventura"), + Pair("Boys Love", "boys-love"), + Pair("Ciberpunk", "ciberpunk"), + Pair("Ciencia Ficción", "ciencia-ficcion"), + Pair("Comedia", "comedia"), + Pair("Crimen", "crimen"), + Pair("Demonios", "demonios"), + Pair("Deporte", "deporte"), + Pair("Drama", "drama"), + Pair("Ecchi", "ecchi"), + Pair("Extranjero", "extranjero"), + Pair("Familia", "familia"), + Pair("Fantasia", "fantasia"), + Pair("Género Bender", "genero-bender"), + Pair("Girls Love", "girls-love"), + Pair("Gore", "gore"), + Pair("Guerra", "guerra"), + Pair("Harem", "harem"), + Pair("Historia", "historia"), + Pair("Horror", "horror"), + Pair("Magia", "magia"), + Pair("Mecha", "mecha"), + Pair("Militar", "militar"), + Pair("Misterio", "misterio"), + Pair("Musica", "musica"), + Pair("Niños", "ninos"), + Pair("Oeste", "oeste"), + Pair("Parodia", "parodia"), + Pair("Policiaco", "policiaco"), + Pair("Psicológico", "psicologico"), + Pair("Realidad", "realidad"), + Pair("Realidad Virtual", "realidad-virtual"), + Pair("Recuentos de la vida", "recuentos-de-la-vida"), + Pair("Reencarnación", "reencarnacion"), + Pair("Romance", "romance"), + Pair("Samurái", "samurai"), + Pair("Sobrenatural", "sobrenatural"), + Pair("Superpoderes", "superpoderes"), + Pair("Supervivencia", "supervivencia"), + Pair("Telenovela", "telenovela"), + Pair("Thriller", "thriller"), + Pair("Tragedia", "tragedia"), + Pair("Traps", "traps"), + Pair("Vampiros", "vampiros"), + Pair("Vida Escolar", "vida-escolar"), + ), +) + +class AlphabeticFilter : UriPartFilter( + "Alfabético", + arrayOf( + Pair("", ""), + Pair("0", "0"), + Pair("1", "1"), + Pair("2", "2"), + Pair("3", "3"), + Pair("4", "4"), + Pair("5", "5"), + Pair("6", "6"), + Pair("7", "7"), + Pair("8", "8"), + Pair("9", "9"), + Pair("A", "A"), + Pair("B", "B"), + Pair("C", "C"), + Pair("D", "D"), + Pair("E", "E"), + Pair("F", "F"), + Pair("G", "G"), + Pair("H", "H"), + Pair("I", "I"), + Pair("J", "J"), + Pair("K", "K"), + Pair("L", "L"), + Pair("M", "M"), + Pair("N", "N"), + Pair("O", "O"), + Pair("P", "P"), + Pair("Q", "Q"), + Pair("R", "R"), + Pair("S", "S"), + Pair("T", "T"), + Pair("U", "U"), + Pair("V", "V"), + Pair("W", "W"), + Pair("X", "X"), + Pair("Y", "Y"), + Pair("Z", "Z"), + ), +) + +class StatusFilter : UriPartFilter( + "Estado", + arrayOf( + Pair("", ""), + Pair("Completed", "completed"), + Pair("Ongoing", "ongoing"), + Pair("Paused", "paused"), + Pair("Cancelled", "cancelled"), + ), +) + +open class UriPartFilter(displayName: String, val vals: Array>) : + Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { + fun toUriPart() = vals[state].second +}