fix filters, added search support (#775)
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…
Reference in New Issue