From 609af00c7b2776dd071f52ef38a25ae9354cb32a Mon Sep 17 00:00:00 2001 From: stevenyomi <95685115+stevenyomi@users.noreply.github.com> Date: Thu, 15 Sep 2022 00:12:02 +0800 Subject: [PATCH] BoyLove: fix page list parsing and balance server load (#13463) * BoyLove: fix page list parsing and balance server load * revert chapter list part --- src/zh/boylove/build.gradle | 2 +- .../tachiyomi/extension/zh/boylove/BoyLove.kt | 24 ++++++++- .../extension/zh/boylove/BoyLoveDto.kt | 54 +++++++++---------- 3 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/zh/boylove/build.gradle b/src/zh/boylove/build.gradle index b5ed97a48..b51182b66 100644 --- a/src/zh/boylove/build.gradle +++ b/src/zh/boylove/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'BoyLove' pkgNameSuffix = 'zh.boylove' extClass = '.BoyLove' - extVersionCode = 2 + extVersionCode = 3 isNsfw = true } diff --git a/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLove.kt b/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLove.kt index 8d7c55045..93618b6a8 100644 --- a/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLove.kt +++ b/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLove.kt @@ -21,12 +21,14 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import okhttp3.Request import okhttp3.Response +import org.jsoup.select.Evaluator import rx.Observable import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy import kotlin.concurrent.thread +// Uses MACCMS http://www.maccms.la/ // 支持站点,不要添加屏蔽广告选项,何况广告本来就不多 class BoyLove : HttpSource(), ConfigurableSource { override val name = "香香腐宅" @@ -93,12 +95,30 @@ class BoyLove : HttpSource(), ConfigurableSource { override fun chapterListParse(response: Response): List = response.parseAs>().list.map { it.toSChapter() } - override fun fetchPageList(chapter: SChapter): Observable> = - chapter.url.substringAfter(':').ifEmpty { + override fun fetchPageList(chapter: SChapter): Observable> { + val chapterUrl = chapter.url + val index = chapterUrl.indexOf(':') // old URL format + if (index == -1) return fetchPageList(chapterUrl) + return chapterUrl.substring(index + 1).ifEmpty { return Observable.just(emptyList()) }.split(',').mapIndexed { i, url -> Page(i, imageUrl = url.toImageUrl()) }.let { Observable.just(it) } + } + + private fun fetchPageList(chapterUrl: String): Observable> = + client.newCall(GET(baseUrl + chapterUrl, headers)).asObservableSuccess().map { response -> + val root = response.asJsoup().selectFirst(Evaluator.Tag("section")) + val images = root.select(Evaluator.Class("reader-cartoon-image")) + val urlList = if (images.isEmpty()) { + root.select(Evaluator.Tag("img")).map { it.attr("src").trim().toImageUrl() } + } else { + images.map { it.child(0) } + .filter { it.attr("src").endsWith("load.png") } + .map { it.attr("data-original").trim().toImageUrl() } + } + urlList.mapIndexed { index, imageUrl -> Page(index, imageUrl = imageUrl) } + } override fun pageListParse(response: Response) = throw UnsupportedOperationException("Not used.") override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not used.") diff --git a/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLoveDto.kt b/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLoveDto.kt index 82d5e5a6e..abba4841f 100644 --- a/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLoveDto.kt +++ b/src/zh/boylove/src/eu/kanade/tachiyomi/extension/zh/boylove/BoyLoveDto.kt @@ -3,28 +3,33 @@ package eu.kanade.tachiyomi.extension.zh.boylove import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import kotlinx.serialization.Serializable -import org.jsoup.Jsoup -import org.jsoup.select.Evaluator +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.long import java.text.SimpleDateFormat +import java.util.Date import java.util.Locale -internal const val IMAGE_HOST = "https://blcnimghost1.cc" // 也有 2 - @Serializable class MangaDto( val id: Int, - val title: String, - val image: String, - val auther: String, - val desc: String, - val mhstatus: Int, - val keyword: String, + private val title: String, + private val update_time: JsonPrimitive, + private val image: String, + private val auther: String, + private val desc: String, + private val mhstatus: Int, + private val keyword: String, ) { fun toSManga() = SManga.create().apply { url = id.toString() title = this@MangaDto.title author = auther - description = desc + val updateTime = if (update_time.isString) { + update_time.content + } else { + dateFormat.format(Date(update_time.long * 1000)) + } + description = "更新时间:$updateTime\n\n$desc" genre = keyword.replace(",", ", ") status = when (mhstatus) { 0 -> SManga.ONGOING @@ -36,29 +41,22 @@ class MangaDto( } } -fun String.toImageUrl() = if (startsWith("http")) this else "$IMAGE_HOST$this" +fun String.toImageUrl() = + if (startsWith("http")) { + this + } else { + val i = (hashCode() and 1) + 1 // 1 or 2 + "https://blcnimghost$i.cc$this" + } @Serializable class ChapterDto( - val id: Int, - val title: String, - val manhua_id: Int, - val update_time: String, - val content: String?, - val imagelist: String, + private val id: Int, + private val title: String, ) { fun toSChapter() = SChapter.create().apply { - url = "$manhua_id/$id:${getImages()}" + url = "/home/book/capter/id/$id" name = title.trim() - date_upload = dateFormat.parse(update_time)?.time ?: 0 - } - - private fun getImages(): String { - return imagelist.ifEmpty { - if (content == null) return "" - Jsoup.parse(content).select(Evaluator.Tag("img")) - .joinToString(",") { it.attr("src") } - } } }