Add more filters to Tsuki. (#7061)

This commit is contained in:
Alessandro Jean 2021-05-17 14:52:36 -03:00 committed by GitHub
parent c06c47caac
commit b03d930599
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 146 additions and 66 deletions

View File

@ -5,8 +5,9 @@ ext {
extName = 'Tsuki Mangás' extName = 'Tsuki Mangás'
pkgNameSuffix = 'pt.tsukimangas' pkgNameSuffix = 'pt.tsukimangas'
extClass = '.TsukiMangas' extClass = '.TsukiMangas'
extVersionCode = 14 extVersionCode = 15
libVersion = '1.2' libVersion = '1.2'
containsNsfw = true
} }
dependencies { dependencies {

View File

@ -9,6 +9,7 @@ import com.github.salomonbrys.kotson.string
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
@ -30,6 +31,7 @@ import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Nsfw
class TsukiMangas : HttpSource() { class TsukiMangas : HttpSource() {
override val name = "Tsuki Mangás" override val name = "Tsuki Mangás"
@ -51,16 +53,17 @@ class TsukiMangas : HttpSource() {
.add("Referer", baseUrl) .add("Referer", baseUrl)
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/api/v2/home", headers) return GET("$baseUrl/api/v2/mangas?page=$page&title=&filter=0", headers)
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val result = response.asJson().obj val result = response.asJson().obj
val popularMangas = result["topviewsmonth"].array val popularMangas = result["data"].array
.map { popularMangaItemParse(it.obj) } .map { popularMangaItemParse(it.obj) }
return MangasPage(popularMangas, false) val hasNextPage = result["page"].int < result["lastPage"].int
return MangasPage(popularMangas, hasNextPage)
} }
private fun popularMangaItemParse(obj: JsonObject) = SManga.create().apply { private fun popularMangaItemParse(obj: JsonObject) = SManga.create().apply {
@ -97,20 +100,41 @@ class TsukiMangas : HttpSource() {
val url = "$baseUrl/api/v2/mangas?page=$page".toHttpUrlOrNull()!!.newBuilder() val url = "$baseUrl/api/v2/mangas?page=$page".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("title", query) url.addQueryParameter("title", query)
filters.forEach { filter -> // Genre filter must be the first.
when (filter) { filters.filterIsInstance<GenreFilter>().firstOrNull()?.state
is GenreFilter -> { ?.filter { it.state }
filter.state ?.forEach { url.addQueryParameter("genres[]", it.name) }
.filter { it.state }
.forEach { url.addQueryParameter("genres", it.name) } // Sort by filter must also be the first.
filters.filterIsInstance<SortByFilter>().firstOrNull()
?.let { filter ->
if (filter.state!!.index == 0) {
url.addQueryParameter("filter", if (filter.state!!.ascending) "1" else "0")
} else {
url.addQueryParameter("filter", if (filter.state!!.ascending) "3" else "2")
}
} }
is TypeFilter -> { filters.forEach { filter ->
when (filter) {
is DemographyFilter -> {
if (filter.state > 0) {
url.addQueryParameter("demography", filter.state.toString())
}
}
is FormatFilter -> {
if (filter.state > 0) { if (filter.state > 0) {
url.addQueryParameter("format", filter.state.toString()) url.addQueryParameter("format", filter.state.toString())
} }
} }
is StatusFilter -> {
if (filter.state > 0) {
url.addQueryParameter("status", (filter.state - 1).toString())
}
}
is AdultFilter -> { is AdultFilter -> {
if (filter.state == Filter.TriState.STATE_INCLUDE) { if (filter.state == Filter.TriState.STATE_INCLUDE) {
url.addQueryParameter("adult_content", "1") url.addQueryParameter("adult_content", "1")
@ -259,73 +283,36 @@ class TsukiMangas : HttpSource() {
private class Genre(name: String) : Filter.CheckBox(name) private class Genre(name: String) : Filter.CheckBox(name)
private class GenreFilter(genres: List<Genre>) : Filter.Group<Genre>("Gêneros", genres) private class DemographyFilter(demographies: List<String>) : Filter.Select<String>("Demografia", demographies.toTypedArray())
private class TypeFilter(types: List<String>) : Filter.Select<String>("Formato", types.toTypedArray()) private class FormatFilter(types: List<String>) : Filter.Select<String>("Formato", types.toTypedArray())
private class StatusFilter(statusList: List<String>) : Filter.Select<String>("Status", statusList.toTypedArray())
private class AdultFilter : Filter.TriState("Conteúdo adulto") private class AdultFilter : Filter.TriState("Conteúdo adulto")
private class SortByFilter : Filter.Sort("Ordenar por", arrayOf("Visualizações", "Nota"), Selection(0, false))
private class GenreFilter(genres: List<Genre>) : Filter.Group<Genre>("Gêneros", genres)
override fun getFilterList(): FilterList = FilterList( override fun getFilterList(): FilterList = FilterList(
DemographyFilter(getDemographiesList()),
FormatFilter(getSerieFormats()),
StatusFilter(getStatusList()),
AdultFilter(),
SortByFilter(),
GenreFilter(getGenreList()), GenreFilter(getGenreList()),
TypeFilter(getSerieTypes()),
AdultFilter()
) )
// [...document.querySelectorAll(".multiselect:first-of-type .multiselect__element span span")] private fun getDemographiesList(): List<String> = listOf(
// .map(i => `Genre("${i.innerHTML}")`).join(",\n") "Todas",
private fun getGenreList(): List<Genre> = listOf( "Shounen",
Genre("4-koma"), "Shoujo",
Genre("Adulto"), "Seinen",
Genre("Artes Marciais"), "Josei"
Genre("Aventura"),
Genre("Ação"),
Genre("Bender"),
Genre("Comédia"),
Genre("Drama"),
Genre("Ecchi"),
Genre("Esporte"),
Genre("Fantasia"),
Genre("Ficção"),
Genre("Gastronomia"),
Genre("Gender"),
Genre("Guerra"),
Genre("Harém"),
Genre("Histórico"),
Genre("Horror"),
Genre("Isekai"),
Genre("Josei"),
Genre("Magia"),
Genre("Manhua"),
Genre("Manhwa"),
Genre("Mecha"),
Genre("Medicina"),
Genre("Militar"),
Genre("Mistério"),
Genre("Musical"),
Genre("One-Shot"),
Genre("Psicológico"),
Genre("Romance"),
Genre("Sci-fi"),
Genre("Seinen"),
Genre("Shoujo"),
Genre("Shoujo Ai"),
Genre("Shounen"),
Genre("Shounen Ai"),
Genre("Slice of Life"),
Genre("Sobrenatural"),
Genre("Super Poderes"),
Genre("Suspense"),
Genre("Terror"),
Genre("Thriller"),
Genre("Tragédia"),
Genre("Vida Escolar"),
Genre("Webtoon"),
Genre("Yaoi"),
Genre("Yuri"),
Genre("Zumbi")
) )
private fun getSerieTypes(): List<String> = listOf( private fun getSerieFormats(): List<String> = listOf(
"Todos", "Todos",
"Mangá", "Mangá",
"Manhwa", "Manhwa",
@ -333,6 +320,98 @@ class TsukiMangas : HttpSource() {
"Novel" "Novel"
) )
private fun getStatusList(): List<String> = listOf(
"Todos",
"Ativo",
"Completo",
"Cancelado",
"Hiato"
)
// [...document.querySelectorAll(".multiselect:first-of-type .multiselect__element span span")]
// .map(i => `Genre("${i.innerHTML}")`).join(",\n")
private fun getGenreList(): List<Genre> = listOf(
Genre("4-Koma"),
Genre("Adaptação"),
Genre("Aliens"),
Genre("Animais"),
Genre("Antologia"),
Genre("Artes Marciais"),
Genre("Aventura"),
Genre("Ação"),
Genre("Colorido por fã"),
Genre("Comédia"),
Genre("Crime"),
Genre("Cross-dressing"),
Genre("Deliquentes"),
Genre("Demônios"),
Genre("Doujinshi"),
Genre("Drama"),
Genre("Ecchi"),
Genre("Esportes"),
Genre("Fantasia"),
Genre("Fantasmas"),
Genre("Filosófico"),
Genre("Gals"),
Genre("Ganhador de Prêmio"),
Genre("Garotas Monstro"),
Genre("Garotas Mágicas"),
Genre("Gastronomia"),
Genre("Gore"),
Genre("Harém"),
Genre("Harém Reverso"),
Genre("Hentai"),
Genre("Histórico"),
Genre("Horror"),
Genre("Incesto"),
Genre("Isekai"),
Genre("Jogos Tradicionais"),
Genre("Lolis"),
Genre("Long Strip"),
Genre("Mafia"),
Genre("Magia"),
Genre("Mecha"),
Genre("Medicina"),
Genre("Militar"),
Genre("Mistério"),
Genre("Monstros"),
Genre("Música"),
Genre("Ninjas"),
Genre("Obscenidade"),
Genre("Oficialmente Colorido"),
Genre("One-shot"),
Genre("Policial"),
Genre("Psicológico"),
Genre("Pós-apocalíptico"),
Genre("Realidade Virtual"),
Genre("Reencarnação"),
Genre("Romance"),
Genre("Samurais"),
Genre("Sci-Fi"),
Genre("Shotas"),
Genre("Shoujo Ai"),
Genre("Shounen Ai"),
Genre("Slice of Life"),
Genre("Sobrenatural"),
Genre("Sobrevivência"),
Genre("Super Herói"),
Genre("Thriller"),
Genre("Todo Colorido"),
Genre("Trabalho de Escritório"),
Genre("Tragédia"),
Genre("Troca de Gênero"),
Genre("Vampiros"),
Genre("Viagem no Tempo"),
Genre("Vida Escolar"),
Genre("Violência Sexual"),
Genre("Vídeo Games"),
Genre("Webcomic"),
Genre("Wuxia"),
Genre("Yaoi"),
Genre("Yuri"),
Genre("Zumbis")
)
private fun String.toDate(): Long { private fun String.toDate(): Long {
return try { return try {
DATE_FORMATTER.parse(this)?.time ?: 0L DATE_FORMATTER.parse(this)?.time ?: 0L