Add missing genres to RS. (#13611)

This commit is contained in:
Alessandro Jean 2022-09-27 19:00:29 -03:00 committed by GitHub
parent a062cfaeca
commit 8d7759ca76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 38 deletions

View File

@ -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"

View File

@ -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, */*"

View File

@ -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()
)

View File

@ -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]