parent
6af9f2d853
commit
67b795a5b8
@ -129,19 +129,22 @@ abstract class YuYu(
|
|||||||
genre = details.select(".genre-tag").joinToString { it.text() }
|
genre = details.select(".genre-tag").joinToString { it.text() }
|
||||||
description = details.selectFirst(".sinopse p")?.text()
|
description = details.selectFirst(".sinopse p")?.text()
|
||||||
details.selectFirst(".manga-meta > div")?.ownText()?.let {
|
details.selectFirst(".manga-meta > div")?.ownText()?.let {
|
||||||
status = when (it.lowercase()) {
|
status = it.toStatus()
|
||||||
"em andamento" -> SManga.ONGOING
|
|
||||||
"completo" -> SManga.COMPLETED
|
|
||||||
"cancelado" -> SManga.CANCELLED
|
|
||||||
"hiato" -> SManga.ON_HIATUS
|
|
||||||
else -> SManga.UNKNOWN
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setUrlWithoutDomain(document.location())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SManga.fetchMangaId(): String {
|
protected fun String.toStatus(): Int {
|
||||||
val document = client.newCall(mangaDetailsRequest(this)).execute().asJsoup()
|
return when (lowercase()) {
|
||||||
|
"em andamento" -> SManga.ONGOING
|
||||||
|
"completo" -> SManga.COMPLETED
|
||||||
|
"cancelado" -> SManga.CANCELLED
|
||||||
|
"hiato" -> SManga.ON_HIATUS
|
||||||
|
else -> SManga.UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun getMangaId(manga: SManga): String {
|
||||||
|
val document = client.newCall(mangaDetailsRequest(manga)).execute().asJsoup()
|
||||||
return document.select("script")
|
return document.select("script")
|
||||||
.map(Element::data)
|
.map(Element::data)
|
||||||
.firstOrNull(MANGA_ID_REGEX::containsMatchIn)
|
.firstOrNull(MANGA_ID_REGEX::containsMatchIn)
|
||||||
@ -159,11 +162,11 @@ abstract class YuYu(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
||||||
val mangaId = manga.fetchMangaId()
|
val mangaId = getMangaId(manga)
|
||||||
val chapters = mutableListOf<SChapter>()
|
val chapters = mutableListOf<SChapter>()
|
||||||
var page = 1
|
var page = 1
|
||||||
do {
|
do {
|
||||||
val dto = fetchChapterListPage(mangaId, page++).parseAs<ChaptersDto>()
|
val dto = fetchChapterListPage(mangaId, page++).parseAs<ChaptersDto<String>>()
|
||||||
val document = Jsoup.parseBodyFragment(dto.chapters, baseUrl)
|
val document = Jsoup.parseBodyFragment(dto.chapters, baseUrl)
|
||||||
chapters += document.select(chapterListSelector()).map(::chapterFromElement)
|
chapters += document.select(chapterListSelector()).map(::chapterFromElement)
|
||||||
} while (dto.hasNext())
|
} while (dto.hasNext())
|
||||||
@ -194,7 +197,7 @@ abstract class YuYu(
|
|||||||
// ============================== Utilities ===========================
|
// ============================== Utilities ===========================
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class ChaptersDto(val chapters: String, private val remaining: Int) {
|
class ChaptersDto<T>(val chapters: T, private val remaining: Int) {
|
||||||
fun hasNext() = remaining > 0
|
fun hasNext() = remaining > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ ext {
|
|||||||
extClass = '.YushukeMangas'
|
extClass = '.YushukeMangas'
|
||||||
themePkg = 'yuyu'
|
themePkg = 'yuyu'
|
||||||
baseUrl = 'https://new.yushukemangas.com'
|
baseUrl = 'https://new.yushukemangas.com'
|
||||||
overrideVersionCode = 6
|
overrideVersionCode = 7
|
||||||
isNsfw = false
|
isNsfw = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.pt.yushukemangas
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.extension.pt.yushukemangas.YushukeMangas.Companion.dateFormat
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import keiyoushi.utils.tryParse
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class ChapterDto(
|
||||||
|
val id: Int,
|
||||||
|
@SerialName("numero")
|
||||||
|
val number: Float,
|
||||||
|
@SerialName("titulo")
|
||||||
|
val name: String,
|
||||||
|
@SerialName("data_publicacao")
|
||||||
|
val date: String,
|
||||||
|
) {
|
||||||
|
fun toSChapter(chapterUrl: String) = SChapter.create().apply {
|
||||||
|
name = this@ChapterDto.name
|
||||||
|
chapter_number = number
|
||||||
|
date_upload = dateFormat.tryParse(date)
|
||||||
|
url = "$chapterUrl/capitulo/$id"
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,17 @@
|
|||||||
package eu.kanade.tachiyomi.extension.pt.yushukemangas
|
package eu.kanade.tachiyomi.extension.pt.yushukemangas
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.yuyu.YuYu
|
import eu.kanade.tachiyomi.multisrc.yuyu.YuYu
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import keiyoushi.utils.parseAs
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import rx.Observable
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class YushukeMangas : YuYu(
|
class YushukeMangas : YuYu(
|
||||||
"Yushuke Mangas",
|
"Yushuke Mangas",
|
||||||
@ -10,8 +20,68 @@ class YushukeMangas : YuYu(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
override val client = super.client.newBuilder()
|
override val client = super.client.newBuilder()
|
||||||
.rateLimit(1, 2)
|
.rateLimit(2)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override val versionId = 2
|
override val versionId = 2
|
||||||
|
|
||||||
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
if (document.location().contains(MANGA_URL_ID_REGEX).not()) {
|
||||||
|
return super.mangaDetailsParse(document)
|
||||||
|
}
|
||||||
|
|
||||||
|
return SManga.create().apply {
|
||||||
|
title = document.selectFirst("h1")!!.text()
|
||||||
|
thumbnail_url = document.selectFirst(".detalhe-capa-img")?.absUrl("src")
|
||||||
|
genre = document.select(".detalhe-tags-chips span").joinToString { it.text() }
|
||||||
|
description = document.selectFirst(".detalhe-sinopse")?.text()
|
||||||
|
document.selectFirst(".detalhe-chip.status")?.ownText()?.let {
|
||||||
|
status = it.toStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMangaId(manga: SManga): String {
|
||||||
|
return when {
|
||||||
|
manga.isOldEntry() -> super.getMangaId(manga)
|
||||||
|
else -> MANGA_URL_ID_REGEX.find(manga.url)?.groups?.get(1)?.value ?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SManga.isOldEntry(): Boolean = MANGA_URL_ID_REGEX.containsMatchIn(url).not()
|
||||||
|
|
||||||
|
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
||||||
|
if (manga.isOldEntry()) {
|
||||||
|
return super.fetchChapterList(manga)
|
||||||
|
}
|
||||||
|
|
||||||
|
val mangaId = getMangaId(manga).takeIf(String::isNotBlank)
|
||||||
|
?: throw Exception("Manga ID não encontrado")
|
||||||
|
|
||||||
|
val chapters = mutableListOf<SChapter>()
|
||||||
|
var page = 1
|
||||||
|
val url = manga.url.replace("/$mangaId", "")
|
||||||
|
do {
|
||||||
|
val chaptersDto = fetchChapterListPage(mangaId, page++).parseAs<ChaptersDto<List<ChapterDto>>>()
|
||||||
|
chapters += chaptersDto.chapters.map { it.toSChapter(url) }
|
||||||
|
} while (chaptersDto.hasNext())
|
||||||
|
|
||||||
|
return Observable.just(chapters)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchChapterListPage(mangaId: String, page: Int): Response {
|
||||||
|
val url = "$baseUrl/ajax/get_chapters.php".toHttpUrl().newBuilder()
|
||||||
|
.addQueryParameter("manga_id", mangaId)
|
||||||
|
.addQueryParameter("page", page.toString())
|
||||||
|
.build()
|
||||||
|
|
||||||
|
return client
|
||||||
|
.newCall(GET(url, headers))
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ROOT)
|
||||||
|
private val MANGA_URL_ID_REGEX = """\/obra\/(\d+)\/.+$""".toRegex()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user