Add missing genres to RS. (#13611)
This commit is contained in:
parent
a062cfaeca
commit
8d7759ca76
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'Reaper Scans'
|
extName = 'Reaper Scans'
|
||||||
pkgNameSuffix = 'pt.reaperscans'
|
pkgNameSuffix = 'pt.reaperscans'
|
||||||
extClass = '.ReaperScans'
|
extClass = '.ReaperScans'
|
||||||
extVersionCode = 31
|
extVersionCode = 32
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -11,10 +11,8 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonArray
|
|
||||||
import kotlinx.serialization.json.buildJsonObject
|
|
||||||
import kotlinx.serialization.json.put
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
@ -49,15 +47,14 @@ class ReaperScans : HttpSource() {
|
||||||
.add("Referer", "$baseUrl/")
|
.add("Referer", "$baseUrl/")
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
val payloadObj = buildJsonObject {
|
val payloadObj = ReaperSearchDto(
|
||||||
put("order", "desc")
|
order = "desc",
|
||||||
put("order_by", "total_views")
|
orderBy = "total_views",
|
||||||
put("series_status", "Ongoing")
|
status = "Ongoing",
|
||||||
put("series_type", "Comic")
|
type = "Comic"
|
||||||
put("tag_ids", JsonArray(emptyList()))
|
)
|
||||||
}
|
|
||||||
|
|
||||||
val payload = payloadObj.toString().toRequestBody(JSON_MEDIA_TYPE)
|
val payload = json.encodeToString(payloadObj).toRequestBody(JSON_MEDIA_TYPE)
|
||||||
|
|
||||||
val apiHeaders = headersBuilder()
|
val apiHeaders = headersBuilder()
|
||||||
.add("Accept", ACCEPT_JSON)
|
.add("Accept", ACCEPT_JSON)
|
||||||
|
@ -75,15 +72,14 @@ class ReaperScans : HttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
val payloadObj = buildJsonObject {
|
val payloadObj = ReaperSearchDto(
|
||||||
put("order", "desc")
|
order = "desc",
|
||||||
put("order_by", "latest")
|
orderBy = "latest",
|
||||||
put("series_status", "Ongoing")
|
status = "Ongoing",
|
||||||
put("series_type", "Comic")
|
type = "Comic"
|
||||||
put("tag_ids", JsonArray(emptyList()))
|
)
|
||||||
}
|
|
||||||
|
|
||||||
val payload = payloadObj.toString().toRequestBody(JSON_MEDIA_TYPE)
|
val payload = json.encodeToString(payloadObj).toRequestBody(JSON_MEDIA_TYPE)
|
||||||
|
|
||||||
val apiHeaders = headersBuilder()
|
val apiHeaders = headersBuilder()
|
||||||
.add("Accept", ACCEPT_JSON)
|
.add("Accept", ACCEPT_JSON)
|
||||||
|
@ -96,22 +92,20 @@ class ReaperScans : HttpSource() {
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
|
override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val sortByFilter = filters.filterIsInstance<SortByFilter>().firstOrNull()
|
val sortByFilter = filters.firstInstanceOrNull<SortByFilter>()
|
||||||
val sortAscending = sortByFilter?.state?.ascending ?: false
|
|
||||||
val sortProperty = sortByFilter?.selected ?: "total_views"
|
|
||||||
|
|
||||||
val status = filters.filterIsInstance<StatusFilter>()
|
val payloadObj = ReaperSearchDto(
|
||||||
.firstOrNull()?.selected?.value ?: "Ongoing"
|
order = if (sortByFilter?.state?.ascending == true) "asc" else "desc",
|
||||||
|
orderBy = sortByFilter?.selected ?: "total_views",
|
||||||
|
status = filters.firstInstanceOrNull<StatusFilter>()?.selected?.value ?: "Ongoing",
|
||||||
|
type = "Comic",
|
||||||
|
tagIds = filters.firstInstanceOrNull<GenreFilter>()?.state
|
||||||
|
?.filter(Genre::state)
|
||||||
|
?.map(Genre::id)
|
||||||
|
.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
val payloadObj = buildJsonObject {
|
val payload = json.encodeToString(payloadObj).toRequestBody(JSON_MEDIA_TYPE)
|
||||||
put("order", if (sortAscending) "asc" else "desc")
|
|
||||||
put("order_by", sortProperty)
|
|
||||||
put("series_status", status)
|
|
||||||
put("series_type", "Comic")
|
|
||||||
put("tag_ids", JsonArray(emptyList()))
|
|
||||||
}
|
|
||||||
|
|
||||||
val payload = payloadObj.toString().toRequestBody(JSON_MEDIA_TYPE)
|
|
||||||
|
|
||||||
val apiHeaders = headersBuilder()
|
val apiHeaders = headersBuilder()
|
||||||
.add("Accept", ACCEPT_JSON)
|
.add("Accept", ACCEPT_JSON)
|
||||||
|
@ -213,15 +207,46 @@ class ReaperScans : HttpSource() {
|
||||||
SortProperty("Data de criação", "latest")
|
SortProperty("Data de criação", "latest")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun getGenreList(): List<Genre> = listOf(
|
||||||
|
Genre("Artes Marciais", 2),
|
||||||
|
Genre("Aventura", 10),
|
||||||
|
Genre("Ação", 9),
|
||||||
|
Genre("Comédia", 14),
|
||||||
|
Genre("Drama", 15),
|
||||||
|
Genre("Escolar", 7),
|
||||||
|
Genre("Fantasia", 11),
|
||||||
|
Genre("Ficção científica", 16),
|
||||||
|
Genre("Guerra", 17),
|
||||||
|
Genre("Isekai", 18),
|
||||||
|
Genre("Jogo", 12),
|
||||||
|
Genre("Mangá", 24),
|
||||||
|
Genre("Manhua", 23),
|
||||||
|
Genre("Manhwa", 22),
|
||||||
|
Genre("Mecha", 19),
|
||||||
|
Genre("Mistério", 20),
|
||||||
|
Genre("Nacional", 8),
|
||||||
|
Genre("Realidade Virtual", 21),
|
||||||
|
Genre("Retorno", 3),
|
||||||
|
Genre("Romance", 5),
|
||||||
|
Genre("Segunda vida", 4),
|
||||||
|
Genre("Seinen", 1),
|
||||||
|
Genre("Shounen", 13),
|
||||||
|
Genre("Terror", 6)
|
||||||
|
)
|
||||||
|
|
||||||
override fun getFilterList(): FilterList = FilterList(
|
override fun getFilterList(): FilterList = FilterList(
|
||||||
StatusFilter(getStatusList()),
|
StatusFilter(getStatusList()),
|
||||||
SortByFilter(getSortProperties()),
|
SortByFilter(getSortProperties()),
|
||||||
|
GenreFilter(getGenreList())
|
||||||
)
|
)
|
||||||
|
|
||||||
private inline fun <reified T> Response.parseAs(): T = use {
|
private inline fun <reified T> Response.parseAs(): T = use {
|
||||||
json.decodeFromString(it.body?.string().orEmpty())
|
json.decodeFromString(it.body?.string().orEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <reified R> List<*>.firstInstanceOrNull(): R? =
|
||||||
|
filterIsInstance<R>().firstOrNull()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
|
private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
|
||||||
private const val ACCEPT_JSON = "application/json, text/plain, */*"
|
private const val ACCEPT_JSON = "application/json, text/plain, */*"
|
||||||
|
|
|
@ -18,25 +18,35 @@ data class ReaperSeriesDto(
|
||||||
val status: String? = null,
|
val status: String? = null,
|
||||||
val thumbnail: String,
|
val thumbnail: String,
|
||||||
val title: String,
|
val title: String,
|
||||||
|
val tags: List<ReaperTagDto>? = emptyList(),
|
||||||
val chapters: List<ReaperChapterDto>? = emptyList()
|
val chapters: List<ReaperChapterDto>? = emptyList()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun toSManga(): SManga = SManga.create().apply {
|
fun toSManga(): SManga = SManga.create().apply {
|
||||||
title = this@ReaperSeriesDto.title
|
title = this@ReaperSeriesDto.title
|
||||||
author = this@ReaperSeriesDto.author
|
author = this@ReaperSeriesDto.author?.trim()
|
||||||
artist = this@ReaperSeriesDto.studio
|
artist = this@ReaperSeriesDto.studio?.trim()
|
||||||
description = this@ReaperSeriesDto.description?.let { Jsoup.parseBodyFragment(it).text() }
|
description = this@ReaperSeriesDto.description
|
||||||
|
?.let { Jsoup.parseBodyFragment(it).select("p") }
|
||||||
|
?.joinToString("\n\n") { it.text() }
|
||||||
|
genre = tags.orEmpty()
|
||||||
|
.sortedBy(ReaperTagDto::name)
|
||||||
|
.joinToString { it.name }
|
||||||
thumbnail_url = "${ReaperScans.API_URL}/cover/$thumbnail"
|
thumbnail_url = "${ReaperScans.API_URL}/cover/$thumbnail"
|
||||||
status = when (this@ReaperSeriesDto.status) {
|
status = when (this@ReaperSeriesDto.status) {
|
||||||
"Ongoing" -> SManga.ONGOING
|
"Ongoing" -> SManga.ONGOING
|
||||||
"Hiatus" -> SManga.ON_HIATUS
|
"Hiatus" -> SManga.ON_HIATUS
|
||||||
"Dropped" -> SManga.CANCELLED
|
"Dropped" -> SManga.CANCELLED
|
||||||
|
"Completed", "Finished" -> SManga.COMPLETED
|
||||||
else -> SManga.UNKNOWN
|
else -> SManga.UNKNOWN
|
||||||
}
|
}
|
||||||
url = "/series/$slug"
|
url = "/series/$slug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ReaperTagDto(val name: String)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ReaperChapterDto(
|
data class ReaperChapterDto(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
@ -47,7 +57,7 @@ data class ReaperChapterDto(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun toSChapter(seriesSlug: String): SChapter = SChapter.create().apply {
|
fun toSChapter(seriesSlug: String): SChapter = SChapter.create().apply {
|
||||||
name = this@ReaperChapterDto.name
|
name = this@ReaperChapterDto.name.trim()
|
||||||
date_upload = runCatching { DATE_FORMAT.parse(createdAt.substringBefore("."))?.time }
|
date_upload = runCatching { DATE_FORMAT.parse(createdAt.substringBefore("."))?.time }
|
||||||
.getOrNull() ?: 0L
|
.getOrNull() ?: 0L
|
||||||
url = "/series/$seriesSlug/$slug#$id"
|
url = "/series/$seriesSlug/$slug#$id"
|
||||||
|
@ -69,3 +79,12 @@ data class ReaperReaderDto(
|
||||||
data class ReaperReaderContentDto(
|
data class ReaperReaderContentDto(
|
||||||
val images: List<String>? = emptyList()
|
val images: List<String>? = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ReaperSearchDto(
|
||||||
|
val order: String,
|
||||||
|
@SerialName("order_by") val orderBy: String,
|
||||||
|
@SerialName("series_status") val status: String,
|
||||||
|
@SerialName("series_type") val type: String,
|
||||||
|
@SerialName("tags_ids") val tagIds: List<Int> = emptyList()
|
||||||
|
)
|
||||||
|
|
|
@ -2,6 +2,10 @@ package eu.kanade.tachiyomi.extension.pt.reaperscans
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
|
|
||||||
|
class Genre(title: String, val id: Int) : Filter.CheckBox(title)
|
||||||
|
|
||||||
|
class GenreFilter(genres: List<Genre>) : Filter.Group<Genre>("Gêneros", genres)
|
||||||
|
|
||||||
open class EnhancedSelect<T>(name: String, values: Array<T>) : Filter.Select<T>(name, values) {
|
open class EnhancedSelect<T>(name: String, values: Array<T>) : Filter.Select<T>(name, values) {
|
||||||
val selected: T
|
val selected: T
|
||||||
get() = values[state]
|
get() = values[state]
|
||||||
|
|
Loading…
Reference in New Issue