BoyLove: fix page list parsing and balance server load (#13463)
* BoyLove: fix page list parsing and balance server load * revert chapter list part
This commit is contained in:
parent
b2f0bc043e
commit
609af00c7b
|
@ -6,7 +6,7 @@ ext {
|
|||
extName = 'BoyLove'
|
||||
pkgNameSuffix = 'zh.boylove'
|
||||
extClass = '.BoyLove'
|
||||
extVersionCode = 2
|
||||
extVersionCode = 3
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
|
|
|
@ -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<SChapter> =
|
||||
response.parseAs<ListPageDto<ChapterDto>>().list.map { it.toSChapter() }
|
||||
|
||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> =
|
||||
chapter.url.substringAfter(':').ifEmpty {
|
||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
||||
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<List<Page>> =
|
||||
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.")
|
||||
|
|
|
@ -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") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue