Fix ReaperScans(BR) and YugenMangas(ES) (#17407)

* Reaper new api

* I forgot to copy the DTO

* Minor change

* Minor change

* Minor change

* Also yugen

* Update multisrc/overrides/heancms/reaperscans/src/ReaperScans.kt

Co-authored-by: Alessandro Jean <14254807+alessandrojean@users.noreply.github.com>

* Update multisrc/overrides/heancms/yugenmangas/src/YugenMangas.kt

Co-authored-by: Alessandro Jean <14254807+alessandrojean@users.noreply.github.com>

* Update multisrc/overrides/heancms/reaperscans/src/ReaperScans.kt

Co-authored-by: Alessandro Jean <14254807+alessandrojean@users.noreply.github.com>

* Update multisrc/overrides/heancms/yugenmangas/src/YugenMangas.kt

Co-authored-by: Alessandro Jean <14254807+alessandrojean@users.noreply.github.com>

---------

Co-authored-by: Alessandro Jean <14254807+alessandrojean@users.noreply.github.com>
This commit is contained in:
Rolando Lecca 2023-08-06 11:32:57 -05:00 committed by GitHub
parent 3060d919f2
commit abcea92017
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 191 additions and 5 deletions

View File

@ -1,10 +1,21 @@
package eu.kanade.tachiyomi.extension.pt.reaperscans package eu.kanade.tachiyomi.extension.pt.reaperscans
import eu.kanade.tachiyomi.multisrc.heancms.Genre import eu.kanade.tachiyomi.multisrc.heancms.Genre
import eu.kanade.tachiyomi.multisrc.heancms.GenreFilter
import eu.kanade.tachiyomi.multisrc.heancms.HeanCms import eu.kanade.tachiyomi.multisrc.heancms.HeanCms
import eu.kanade.tachiyomi.multisrc.heancms.HeanCmsSeriesDto
import eu.kanade.tachiyomi.multisrc.heancms.SortByFilter
import eu.kanade.tachiyomi.multisrc.heancms.StatusFilter
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.TimeZone import java.util.TimeZone
@ -27,6 +38,81 @@ class ReaperScans : HeanCms(
timeZone = TimeZone.getTimeZone("GMT+01:00") timeZone = TimeZone.getTimeZone("GMT+01:00")
} }
override fun popularMangaRequest(page: Int): Request {
val url = "$apiUrl/query".toHttpUrl().newBuilder()
.addQueryParameter("query_string", "")
.addQueryParameter("series_status", "All")
.addQueryParameter("order", "desc")
.addQueryParameter("orderBy", "total_views")
.addQueryParameter("series_type", "Comic")
.addQueryParameter("page", page.toString())
.addQueryParameter("perPage", "12")
.addQueryParameter("tags_ids", "[]")
return GET(url.build(), headers)
}
override fun latestUpdatesRequest(page: Int): Request {
val url = "$apiUrl/query".toHttpUrl().newBuilder()
.addQueryParameter("query_string", "")
.addQueryParameter("series_status", "All")
.addQueryParameter("order", "desc")
.addQueryParameter("orderBy", "latest")
.addQueryParameter("series_type", "Comic")
.addQueryParameter("page", page.toString())
.addQueryParameter("perPage", "12")
.addQueryParameter("tags_ids", "[]")
return GET(url.build(), headers)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val sortByFilter = filters.firstInstanceOrNull<SortByFilter>()
val statusFilter = filters.firstInstanceOrNull<StatusFilter>()
val tagIds = filters.firstInstanceOrNull<GenreFilter>()?.state.orEmpty()
.filter(Genre::state)
.map(Genre::id)
.joinToString(",", prefix = "[", postfix = "]")
val url = "$apiUrl/query".toHttpUrl().newBuilder()
.addQueryParameter("query_string", query)
.addQueryParameter("series_status", statusFilter?.selected?.value ?: "All")
.addQueryParameter("order", if (sortByFilter?.state?.ascending == true) "asc" else "desc")
.addQueryParameter("orderBy", sortByFilter?.selected ?: "total_views")
.addQueryParameter("series_type", "Comic")
.addQueryParameter("page", page.toString())
.addQueryParameter("perPage", "12")
.addQueryParameter("tags_ids", tagIds)
return GET(url.build(), headers)
}
override fun chapterListParse(response: Response): List<SChapter> {
val result = response.parseAs<HeanCmsSeriesDto>()
val currentTimestamp = System.currentTimeMillis()
return result.seasons.orEmpty()
.flatMap { it.chapters.orEmpty() }
.filterNot { it.price == 1 }
.map { it.toSChapter(result.slug, dateFormat) }
.filter { it.date_upload <= currentTimestamp }
}
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup()
val images = document.selectFirst("div.min-h-screen > div.container > p.items-center")
return images?.select("img").orEmpty().mapIndexed { i, img ->
val imageUrl = if (img.hasClass("lazy")) img.absUrl("data-src") else img.absUrl("src")
Page(i, "", imageUrl)
}
}
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),

View File

@ -1,9 +1,20 @@
package eu.kanade.tachiyomi.extension.es.yugenmangas package eu.kanade.tachiyomi.extension.es.yugenmangas
import eu.kanade.tachiyomi.multisrc.heancms.Genre import eu.kanade.tachiyomi.multisrc.heancms.Genre
import eu.kanade.tachiyomi.multisrc.heancms.GenreFilter
import eu.kanade.tachiyomi.multisrc.heancms.HeanCms import eu.kanade.tachiyomi.multisrc.heancms.HeanCms
import eu.kanade.tachiyomi.multisrc.heancms.HeanCmsSeriesDto
import eu.kanade.tachiyomi.multisrc.heancms.SortByFilter
import eu.kanade.tachiyomi.multisrc.heancms.StatusFilter
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import okhttp3.Response
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.TimeZone import java.util.TimeZone
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -31,6 +42,81 @@ class YugenMangas :
timeZone = TimeZone.getTimeZone("UTC") timeZone = TimeZone.getTimeZone("UTC")
} }
override fun popularMangaRequest(page: Int): Request {
val url = "$apiUrl/query".toHttpUrl().newBuilder()
.addQueryParameter("query_string", "")
.addQueryParameter("series_status", "All")
.addQueryParameter("order", "desc")
.addQueryParameter("orderBy", "total_views")
.addQueryParameter("series_type", "Comic")
.addQueryParameter("page", page.toString())
.addQueryParameter("perPage", "12")
.addQueryParameter("tags_ids", "[]")
return GET(url.build(), headers)
}
override fun latestUpdatesRequest(page: Int): Request {
val url = "$apiUrl/query".toHttpUrl().newBuilder()
.addQueryParameter("query_string", "")
.addQueryParameter("series_status", "All")
.addQueryParameter("order", "desc")
.addQueryParameter("orderBy", "latest")
.addQueryParameter("series_type", "Comic")
.addQueryParameter("page", page.toString())
.addQueryParameter("perPage", "12")
.addQueryParameter("tags_ids", "[]")
return GET(url.build(), headers)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val sortByFilter = filters.firstInstanceOrNull<SortByFilter>()
val statusFilter = filters.firstInstanceOrNull<StatusFilter>()
val tagIds = filters.firstInstanceOrNull<GenreFilter>()?.state.orEmpty()
.filter(Genre::state)
.map(Genre::id)
.joinToString(",", prefix = "[", postfix = "]")
val url = "$apiUrl/query".toHttpUrl().newBuilder()
.addQueryParameter("query_string", query)
.addQueryParameter("series_status", statusFilter?.selected?.value ?: "All")
.addQueryParameter("order", if (sortByFilter?.state?.ascending == true) "asc" else "desc")
.addQueryParameter("orderBy", sortByFilter?.selected ?: "total_views")
.addQueryParameter("series_type", "Comic")
.addQueryParameter("page", page.toString())
.addQueryParameter("perPage", "12")
.addQueryParameter("tags_ids", tagIds)
return GET(url.build(), headers)
}
override fun chapterListParse(response: Response): List<SChapter> {
val result = response.parseAs<HeanCmsSeriesDto>()
val currentTimestamp = System.currentTimeMillis()
return result.seasons.orEmpty()
.flatMap { it.chapters.orEmpty() }
.filterNot { it.price == 1 }
.map { it.toSChapter(result.slug, dateFormat) }
.filter { it.date_upload <= currentTimestamp }
}
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup()
val images = document.selectFirst("div.min-h-screen > div.container > p.items-center")
return images?.select("img").orEmpty().mapIndexed { i, img ->
val imageUrl = if (img.hasClass("lazy")) img.absUrl("data-src") else img.absUrl("src")
Page(i, "", imageUrl)
}
}
override fun getGenreList(): List<Genre> = listOf( override fun getGenreList(): List<Genre> = listOf(
Genre("+18", 1), Genre("+18", 1),
Genre("Acción", 36), Genre("Acción", 36),

View File

@ -267,6 +267,7 @@ abstract class HeanCms(
} }
protected open fun getStatusList(): List<Status> = listOf( protected open fun getStatusList(): List<Status> = listOf(
Status(intl.statusAll, "All"),
Status(intl.statusOngoing, "Ongoing"), Status(intl.statusOngoing, "Ongoing"),
Status(intl.statusOnHiatus, "Hiatus"), Status(intl.statusOnHiatus, "Hiatus"),
Status(intl.statusDropped, "Dropped"), Status(intl.statusDropped, "Dropped"),
@ -294,13 +295,13 @@ abstract class HeanCms(
return FilterList(filters) return FilterList(filters)
} }
private inline fun <reified T> Response.parseAs(): T = use { protected inline fun <reified T> Response.parseAs(): T = use {
it.body.string().parseAs() it.body.string().parseAs()
} }
private inline fun <reified T> String.parseAs(): T = json.decodeFromString(this) protected inline fun <reified T> String.parseAs(): T = json.decodeFromString(this)
private inline fun <reified R> List<*>.firstInstanceOrNull(): R? = protected inline fun <reified R> List<*>.firstInstanceOrNull(): R? =
filterIsInstance<R>().firstOrNull() filterIsInstance<R>().firstOrNull()
companion object { companion object {

View File

@ -55,6 +55,7 @@ data class HeanCmsSeriesDto(
val title: String, val title: String,
val tags: List<HeanCmsTagDto>? = emptyList(), val tags: List<HeanCmsTagDto>? = emptyList(),
val chapters: List<HeanCmsChapterDto>? = emptyList(), val chapters: List<HeanCmsChapterDto>? = emptyList(),
val seasons: List<HeanCmsSeasonsDto>? = emptyList(),
) { ) {
fun toSManga( fun toSManga(
@ -79,6 +80,12 @@ data class HeanCmsSeriesDto(
} }
} }
@Serializable
data class HeanCmsSeasonsDto(
val index: Int,
val chapters: List<HeanCmsChapterDto>? = emptyList(),
)
@Serializable @Serializable
data class HeanCmsTagDto(val name: String) data class HeanCmsTagDto(val name: String)

View File

@ -14,8 +14,8 @@ class HeanCmsGenerator : ThemeSourceGenerator {
override val sources = listOf( override val sources = listOf(
SingleLang("Glorious Scan", "https://gloriousscan.com", "pt-BR", overrideVersionCode = 17), SingleLang("Glorious Scan", "https://gloriousscan.com", "pt-BR", overrideVersionCode = 17),
SingleLang("Omega Scans", "https://omegascans.org", "en", isNsfw = true, overrideVersionCode = 17), SingleLang("Omega Scans", "https://omegascans.org", "en", isNsfw = true, overrideVersionCode = 17),
SingleLang("Reaper Scans", "https://reaperscans.net", "pt-BR", overrideVersionCode = 35), SingleLang("Reaper Scans", "https://reaperscans.net", "pt-BR", overrideVersionCode = 36),
SingleLang("YugenMangas", "https://yugenmangas.net", "es", isNsfw = true, overrideVersionCode = 5), SingleLang("YugenMangas", "https://yugenmangas.net", "es", isNsfw = true, overrideVersionCode = 6),
) )
companion object { companion object {

View File

@ -16,6 +16,12 @@ class HeanCmsIntl(lang: String) {
else -> "Status" else -> "Status"
} }
val statusAll: String = when (availableLang) {
BRAZILIAN_PORTUGUESE -> "Todos"
SPANISH -> "Todos"
else -> "All"
}
val statusOngoing: String = when (availableLang) { val statusOngoing: String = when (availableLang) {
BRAZILIAN_PORTUGUESE -> "Em andamento" BRAZILIAN_PORTUGUESE -> "Em andamento"
SPANISH -> "En curso" SPANISH -> "En curso"