Fix bad JSON parsing in RS. (#13896)
This commit is contained in:
parent
85dd5326e7
commit
cb6498ae33
|
@ -19,6 +19,10 @@ class ReaperScans : HeanCms(
|
||||||
// Site changed from Madara to HeanCms.
|
// Site changed from Madara to HeanCms.
|
||||||
override val versionId = 2
|
override val versionId = 2
|
||||||
|
|
||||||
|
override val fetchAllTitles = true
|
||||||
|
|
||||||
|
override val coverPath: String = ""
|
||||||
|
|
||||||
override fun getGenreList(): List<Genre> = listOf(
|
override fun getGenreList(): List<Genre> = listOf(
|
||||||
Genre("Artes Marciais", 2),
|
Genre("Artes Marciais", 2),
|
||||||
Genre("Aventura", 10),
|
Genre("Aventura", 10),
|
||||||
|
|
|
@ -37,6 +37,10 @@ abstract class HeanCms(
|
||||||
|
|
||||||
protected val intl by lazy { HeanCmsIntl(lang) }
|
protected val intl by lazy { HeanCmsIntl(lang) }
|
||||||
|
|
||||||
|
protected open val fetchAllTitles: Boolean = false
|
||||||
|
|
||||||
|
protected open val coverPath: String = "cover/"
|
||||||
|
|
||||||
private var seriesSlugMap: Map<String, String>? = null
|
private var seriesSlugMap: Map<String, String>? = null
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
|
@ -44,7 +48,8 @@ abstract class HeanCms(
|
||||||
.add("Referer", "$baseUrl/")
|
.add("Referer", "$baseUrl/")
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
val payloadObj = HeanCmsSearchDto(
|
val payloadObj = HeanCmsSearchPayloadDto(
|
||||||
|
page = page,
|
||||||
order = "desc",
|
order = "desc",
|
||||||
orderBy = "total_views",
|
orderBy = "total_views",
|
||||||
status = "Ongoing",
|
status = "Ongoing",
|
||||||
|
@ -62,8 +67,19 @@ abstract class HeanCms(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
|
val json = response.body?.string().orEmpty()
|
||||||
|
|
||||||
|
if (json.startsWith("{")) {
|
||||||
|
val result = json.parseAs<HeanCmsSearchDto>()
|
||||||
|
val mangaList = result.data.map { it.toSManga(apiUrl, coverPath) }
|
||||||
|
|
||||||
|
fetchAllTitles()
|
||||||
|
|
||||||
|
return MangasPage(mangaList, result.meta?.hasNextPage ?: false)
|
||||||
|
}
|
||||||
|
|
||||||
val mangaList = response.parseAs<List<HeanCmsSeriesDto>>()
|
val mangaList = response.parseAs<List<HeanCmsSeriesDto>>()
|
||||||
.map { it.toSManga(apiUrl) }
|
.map { it.toSManga(apiUrl, coverPath) }
|
||||||
|
|
||||||
fetchAllTitles()
|
fetchAllTitles()
|
||||||
|
|
||||||
|
@ -71,7 +87,8 @@ abstract class HeanCms(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
val payloadObj = HeanCmsSearchDto(
|
val payloadObj = HeanCmsSearchPayloadDto(
|
||||||
|
page = page,
|
||||||
order = "desc",
|
order = "desc",
|
||||||
orderBy = "latest",
|
orderBy = "latest",
|
||||||
status = "Ongoing",
|
status = "Ongoing",
|
||||||
|
@ -93,7 +110,8 @@ abstract class HeanCms(
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val sortByFilter = filters.firstInstanceOrNull<SortByFilter>()
|
val sortByFilter = filters.firstInstanceOrNull<SortByFilter>()
|
||||||
|
|
||||||
val payloadObj = HeanCmsSearchDto(
|
val payloadObj = HeanCmsSearchPayloadDto(
|
||||||
|
page = page,
|
||||||
order = if (sortByFilter?.state?.ascending == true) "asc" else "desc",
|
order = if (sortByFilter?.state?.ascending == true) "asc" else "desc",
|
||||||
orderBy = sortByFilter?.selected ?: "total_views",
|
orderBy = sortByFilter?.selected ?: "total_views",
|
||||||
status = filters.firstInstanceOrNull<StatusFilter>()?.selected?.value ?: "Ongoing",
|
status = filters.firstInstanceOrNull<StatusFilter>()?.selected?.value ?: "Ongoing",
|
||||||
|
@ -119,10 +137,24 @@ abstract class HeanCms(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
|
val json = response.body?.string().orEmpty()
|
||||||
val query = response.request.url.queryParameter("q").orEmpty()
|
val query = response.request.url.queryParameter("q").orEmpty()
|
||||||
|
|
||||||
|
if (json.startsWith("{")) {
|
||||||
|
val result = json.parseAs<HeanCmsSearchDto>()
|
||||||
|
var mangaList = result.data.map { it.toSManga(apiUrl, coverPath) }
|
||||||
|
|
||||||
|
if (query.isNotBlank()) {
|
||||||
|
mangaList = mangaList.filter { it.title.contains(query, ignoreCase = true) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchAllTitles()
|
||||||
|
|
||||||
|
return MangasPage(mangaList, result.meta?.hasNextPage ?: false)
|
||||||
|
}
|
||||||
|
|
||||||
var mangaList = response.parseAs<List<HeanCmsSeriesDto>>()
|
var mangaList = response.parseAs<List<HeanCmsSeriesDto>>()
|
||||||
.map { it.toSManga(apiUrl) }
|
.map { it.toSManga(apiUrl, coverPath) }
|
||||||
|
|
||||||
if (query.isNotBlank()) {
|
if (query.isNotBlank()) {
|
||||||
mangaList = mangaList.filter { it.title.contains(query, ignoreCase = true) }
|
mangaList = mangaList.filter { it.title.contains(query, ignoreCase = true) }
|
||||||
|
@ -158,7 +190,7 @@ abstract class HeanCms(
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val result = runCatching { response.parseAs<HeanCmsSeriesDto>() }
|
val result = runCatching { response.parseAs<HeanCmsSeriesDto>() }
|
||||||
val seriesDetails = result.getOrNull()?.toSManga(apiUrl)
|
val seriesDetails = result.getOrNull()?.toSManga(apiUrl, coverPath)
|
||||||
?: throw Exception(intl.urlChangedError(name))
|
?: throw Exception(intl.urlChangedError(name))
|
||||||
|
|
||||||
return seriesDetails.apply {
|
return seriesDetails.apply {
|
||||||
|
@ -220,20 +252,40 @@ abstract class HeanCms(
|
||||||
protected open fun getGenreList(): List<Genre> = emptyList()
|
protected open fun getGenreList(): List<Genre> = emptyList()
|
||||||
|
|
||||||
protected open fun fetchAllTitles() {
|
protected open fun fetchAllTitles() {
|
||||||
if (!seriesSlugMap.isNullOrEmpty()) {
|
if (!seriesSlugMap.isNullOrEmpty() || !fetchAllTitles) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = runCatching {
|
val result = runCatching {
|
||||||
client.newCall(allTitlesRequest()).execute()
|
var hasNextPage = true
|
||||||
.let { parseAllTitles(it) }
|
var page = 1
|
||||||
|
val tempMap = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
while (hasNextPage) {
|
||||||
|
val response = client.newCall(allTitlesRequest(page)).execute()
|
||||||
|
val json = response.body?.string().orEmpty()
|
||||||
|
|
||||||
|
if (json.startsWith("{")) {
|
||||||
|
val result = json.parseAs<HeanCmsSearchDto>()
|
||||||
|
tempMap.putAll(parseAllTitles(result.data))
|
||||||
|
hasNextPage = result.meta?.hasNextPage ?: false
|
||||||
|
page++
|
||||||
|
} else {
|
||||||
|
val result = json.parseAs<List<HeanCmsSeriesDto>>()
|
||||||
|
tempMap.putAll(parseAllTitles(result))
|
||||||
|
hasNextPage = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tempMap.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesSlugMap = result.getOrNull()
|
seriesSlugMap = result.getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun allTitlesRequest(): Request {
|
protected open fun allTitlesRequest(page: Int): Request {
|
||||||
val payloadObj = HeanCmsSearchDto(
|
val payloadObj = HeanCmsSearchPayloadDto(
|
||||||
|
page = page,
|
||||||
order = "desc",
|
order = "desc",
|
||||||
orderBy = "total_views",
|
orderBy = "total_views",
|
||||||
status = "",
|
status = "",
|
||||||
|
@ -250,8 +302,8 @@ abstract class HeanCms(
|
||||||
return POST("$apiUrl/series/querysearch", apiHeaders, payload)
|
return POST("$apiUrl/series/querysearch", apiHeaders, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun parseAllTitles(response: Response): Map<String, String> {
|
protected open fun parseAllTitles(result: List<HeanCmsSeriesDto>): Map<String, String> {
|
||||||
return response.parseAs<List<HeanCmsSeriesDto>>()
|
return result
|
||||||
.filter { it.type == "Comic" }
|
.filter { it.type == "Comic" }
|
||||||
.associateBy(
|
.associateBy(
|
||||||
keySelector = { it.slug.replace(TIMESTAMP_REGEX, "") },
|
keySelector = { it.slug.replace(TIMESTAMP_REGEX, "") },
|
||||||
|
@ -275,6 +327,8 @@ abstract class HeanCms(
|
||||||
json.decodeFromString(it.body?.string().orEmpty())
|
json.decodeFromString(it.body?.string().orEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <reified T> String.parseAs(): T = json.decodeFromString(this)
|
||||||
|
|
||||||
private inline fun <reified R> List<*>.firstInstanceOrNull(): R? =
|
private inline fun <reified R> List<*>.firstInstanceOrNull(): R? =
|
||||||
filterIsInstance<R>().firstOrNull()
|
filterIsInstance<R>().firstOrNull()
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,22 @@ import org.jsoup.Jsoup
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class HeanCmsSearchDto(
|
||||||
|
val data: List<HeanCmsSeriesDto> = emptyList(),
|
||||||
|
val meta: HeanCmsSearchMetaDto? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class HeanCmsSearchMetaDto(
|
||||||
|
@SerialName("current_page") val currentPage: Int,
|
||||||
|
@SerialName("last_page") val lastPage: Int
|
||||||
|
) {
|
||||||
|
|
||||||
|
val hasNextPage: Boolean
|
||||||
|
get() = currentPage < lastPage
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class HeanCmsSeriesDto(
|
data class HeanCmsSeriesDto(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
@ -23,7 +39,7 @@ data class HeanCmsSeriesDto(
|
||||||
val chapters: List<HeanCmsChapterDto>? = emptyList()
|
val chapters: List<HeanCmsChapterDto>? = emptyList()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun toSManga(apiUrl: String): SManga = SManga.create().apply {
|
fun toSManga(apiUrl: String, coverPath: String): SManga = SManga.create().apply {
|
||||||
val descriptionBody = this@HeanCmsSeriesDto.description?.let(Jsoup::parseBodyFragment)
|
val descriptionBody = this@HeanCmsSeriesDto.description?.let(Jsoup::parseBodyFragment)
|
||||||
|
|
||||||
title = this@HeanCmsSeriesDto.title
|
title = this@HeanCmsSeriesDto.title
|
||||||
|
@ -35,7 +51,7 @@ data class HeanCmsSeriesDto(
|
||||||
genre = tags.orEmpty()
|
genre = tags.orEmpty()
|
||||||
.sortedBy(HeanCmsTagDto::name)
|
.sortedBy(HeanCmsTagDto::name)
|
||||||
.joinToString { it.name }
|
.joinToString { it.name }
|
||||||
thumbnail_url = "$apiUrl/cover/$thumbnail"
|
thumbnail_url = "$apiUrl/$coverPath$thumbnail"
|
||||||
status = when (this@HeanCmsSeriesDto.status) {
|
status = when (this@HeanCmsSeriesDto.status) {
|
||||||
"Ongoing" -> SManga.ONGOING
|
"Ongoing" -> SManga.ONGOING
|
||||||
"Hiatus" -> SManga.ON_HIATUS
|
"Hiatus" -> SManga.ON_HIATUS
|
||||||
|
@ -84,8 +100,9 @@ data class HeanCmsReaderContentDto(
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class HeanCmsSearchDto(
|
data class HeanCmsSearchPayloadDto(
|
||||||
val order: String,
|
val order: String,
|
||||||
|
val page: Int,
|
||||||
@SerialName("order_by") val orderBy: String,
|
@SerialName("order_by") val orderBy: String,
|
||||||
@SerialName("series_status") val status: String,
|
@SerialName("series_status") val status: String,
|
||||||
@SerialName("series_type") val type: String,
|
@SerialName("series_type") val type: String,
|
||||||
|
|
|
@ -9,7 +9,7 @@ class HeanCmsGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
override val themeClass = "HeanCms"
|
override val themeClass = "HeanCms"
|
||||||
|
|
||||||
override val baseVersionCode: Int = 1
|
override val baseVersionCode: Int = 2
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang("Reaper Scans", "https://reaperscans.net", "pt-BR", overrideVersionCode = 35),
|
SingleLang("Reaper Scans", "https://reaperscans.net", "pt-BR", overrideVersionCode = 35),
|
||||||
|
|
Loading…
Reference in New Issue