fix filters, added search support (#775)

master
Naga 2 years ago committed by Koitharu
parent cc35aa6bc3
commit 2292c392e9

@ -1,58 +1,152 @@
package org.koitharu.kotatsu.parsers.site.mangareader.en package org.koitharu.kotatsu.parsers.site.mangareader.en
import org.koitharu.kotatsu.parsers.ErrorMessages import okhttp3.FormBody
import okhttp3.Request
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import org.koitharu.kotatsu.parsers.util.domain import org.koitharu.kotatsu.parsers.util.*
import org.koitharu.kotatsu.parsers.util.oneOrThrowIfMany import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault
import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
import org.koitharu.kotatsu.parsers.util.json.mapJSON
import java.util.* import java.util.*
@MangaSourceParser("RIZZCOMIC", "RizzComic", "en") @MangaSourceParser("RIZZCOMIC", "RizzComic", "en")
internal class RizzComic(context: MangaLoaderContext) : internal class RizzComic(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.RIZZCOMIC, "rizzfables.com", pageSize = 50, searchPageSize = 20) { MangaReaderParser(context, MangaSource.RIZZCOMIC, "rizzfables.com", pageSize = 50, searchPageSize = 20){
override val datePattern = "dd MMM yyyy" override val datePattern = "dd MMM yyyy"
override val listUrl = "/series" override val listUrl = "/series"
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.POPULARITY, SortOrder.ALPHABETICAL_DESC)
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL) override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED)
override val availableStates: Set<MangaState> = emptySet() override val isMultipleTagsSupported = true
override val isMultipleTagsSupported = false
override val isSearchSupported = true override val isSearchSupported = true
override val isTagsExclusionSupported = false override val isTagsExclusionSupported = false
// TODO Query created in json private val filterUrl = "/Index/filter_series"
private val searchUrl = "/Index/live_search"
private val seriesCode = "r2311170"
private val slugRegex = Regex("""[^a-z0-9]+""")
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> { override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
if (page > 1) { if (page > 1) {
return emptyList() return emptyList()
} }
val url = buildString { var url = "https://$domain$filterUrl"
append("https://")
append(domain)
when (filter) {
is MangaListFilter.Search -> { val payload = when (filter) {
throw IllegalArgumentException(ErrorMessages.SEARCH_NOT_SUPPORTED) is MangaListFilter.Search -> {
url = "https://$domain$searchUrl"
if (filter.query != "") {
FormBody.Builder()
.add("search_value", filter.query.trim())
.build()
} else {
null
} }
}
is MangaListFilter.Advanced ->{
val state = if (filter.states.isEmpty()) "all"
else filter.states.oneOrThrowIfMany()!!.toPayloadValue()
is MangaListFilter.Advanced -> { val genres = filter.tags.map { it.key }
if (filter.tags.isNotEmpty()) { val formBuilder = FormBody.Builder()
append("/genre/") .add("StatusValue", state)
filter.tags.oneOrThrowIfMany()?.let { .add("TypeValue", "all")
append(it.key) .add("OrderValue", filter.sortOrder.toPayloadValue())
}
} else {
append(listUrl)
}
}
null -> { genres.forEach { genre ->
append(listUrl) formBuilder.add("genres_checked[]", genre)
} }
formBuilder.build()
}
else -> {
FormBody.Builder()
.add("StatusValue", "all")
.add("TypeValue", "all")
.add("OrderValue", "all")
.build()
}
}
val request = Request.Builder()
.url(url)
.apply {
if (payload != null) {
post(payload)
} else {
get()
}
}
.build()
val response = context.httpClient.newCall(request).execute().parseJsonArray()
return response.mapJSON { j ->
val title = j.getString("title")
val urlManga = "https://$domain$listUrl/$seriesCode-" + title.trim().lowercase()
.replace(slugRegex, "-")
.replace("-s-", "s-")
.replace("-ll-", "ll-")
val manga = Manga(
id = j.getLong("id"),
title = title,
altTitle = j.getString("description"),
url = urlManga.toRelativeUrl(domain),
publicUrl = urlManga,
rating = j.getFloatOrDefault("rating", RATING_UNKNOWN) / 10f,
isNsfw = false,
coverUrl = "https://$domain/assets/images/"+ j.getString("image_url"),
tags = setOf(),
state = when (j.getString("status")) {
"ongoing" -> MangaState.ONGOING
"completed" -> MangaState.FINISHED
"hiatus" -> MangaState.PAUSED
else -> null
},
author = j.getStringOrNull("author"),
source = source,
description = j.getString("long_description"),
)
manga
}
}
private fun SortOrder.toPayloadValue(): String = when (this) {
SortOrder.ALPHABETICAL -> "title"
SortOrder.POPULARITY -> "popular"
SortOrder.UPDATED -> "update"
SortOrder.NEWEST -> "latest"
SortOrder.ALPHABETICAL_DESC -> "titlereverse"
else -> "all"
}
private fun MangaState.toPayloadValue(): String = when (this) {
MangaState.ONGOING -> "ongoing"
MangaState.FINISHED -> "completed"
MangaState.PAUSED -> "hiatus"
else -> "all"
}
override suspend fun getAvailableTags(): Set<MangaTag> {
val url = "https://$domain/series"
val doc = webClient.httpGet(url).parseHtml()
val genreElements = doc.select("input.genre-item")
return genreElements.mapNotNullTo(mutableSetOf()) { element ->
val id = element.attr("value")
val name = element.nextElementSibling()?.text()
if (id.isNotEmpty() && name != null) {
MangaTag(
key = id,
title = name.toTitleCase(sourceLocale),
source = source,
)
} else {
null
} }
} }
return parseMangaList(webClient.httpGet(url).parseHtml())
} }
} }

Loading…
Cancel
Save