feat(buondua): split chapters into individual pages (#8803)

* feat(buondua): split chapters into individual pages

- Migrate from single-chapter to per-page architecture
- Fix long loading time issues

* fix(buondua): Remove chapter_number configuration

- Drop deprecated chapter_number field setup
This commit is contained in:
marioplus 2025-05-12 21:21:48 +08:00 committed by Draff
parent d0357da16a
commit d3fa36c82d
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
2 changed files with 21 additions and 28 deletions

View File

@ -1,7 +1,7 @@
ext { ext {
extName = 'Buon Dua' extName = 'Buon Dua'
extClass = '.BuonDua' extClass = '.BuonDua'
extVersionCode = 3 extVersionCode = 4
isNsfw = true isNsfw = true
} }

View File

@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.util.asJsoup
import keiyoushi.utils.tryParse import keiyoushi.utils.tryParse
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -60,7 +61,6 @@ class BuonDua() : ParsedHttpSource() {
override fun popularMangaSelector() = latestUpdatesSelector() override fun popularMangaSelector() = latestUpdatesSelector()
// Search // Search
override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element) override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element)
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector() override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
@ -87,34 +87,27 @@ class BuonDua() : ParsedHttpSource() {
return manga return manga
} }
override fun chapterFromElement(element: Element): SChapter { override fun chapterListSelector() = throw UnsupportedOperationException()
val chapter = SChapter.create() override fun chapterFromElement(element: Element) = throw UnsupportedOperationException()
chapter.setUrlWithoutDomain(element.select(".is-current").first()!!.attr("abs:href")) override fun chapterListParse(response: Response): List<SChapter> {
chapter.chapter_number = 0F val doc = response.asJsoup()
chapter.name = element.select(".article-header").text() val dateUploadStr = doc.selectFirst(".article-info > small")?.text()
chapter.date_upload = DATE_FORMAT.tryParse(element.selectFirst(".article-info > small")?.text()) val dateUpload = DATE_FORMAT.tryParse(dateUploadStr)
return chapter val maxPage = doc.select("nav.pagination:first-of-type a.pagination-link").last()?.text()?.toInt() ?: 1
} val basePageUrl = response.request.url
return (maxPage downTo 1).map { page ->
override fun chapterListSelector() = "html" SChapter.create().apply {
setUrlWithoutDomain("$basePageUrl?page=$page")
// Pages name = "Page $page"
date_upload = dateUpload
override fun pageListParse(document: Document): List<Page> {
val numpages = document.selectFirst(".pagination-list")!!.select(".pagination-link")
val pages = mutableListOf<Page>()
numpages.forEachIndexed { index, page ->
val doc = when (index) {
0 -> document
else -> client.newCall(GET(page.attr("abs:href"))).execute().asJsoup()
}
doc.select(".article-fulltext img").forEach {
val itUrl = it.attr("abs:src")
pages.add(Page(pages.size, "", itUrl))
} }
} }
return pages }
// Pages
override fun pageListParse(document: Document): List<Page> {
return document.select(".article-fulltext img")
.mapIndexed { i, imgEl -> Page(i, imageUrl = imgEl.absUrl("src")) }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()