Gufengmh: prefer PC chapter list page and SinMH cleanups (#12290)
This commit is contained in:
parent
afb387df25
commit
7de9719d0a
@ -1,10 +1,48 @@
|
||||
package eu.kanade.tachiyomi.extension.zh.gufengmh
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.sinmh.SinMH
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import org.jsoup.nodes.Document
|
||||
import rx.Observable
|
||||
import rx.Single
|
||||
|
||||
class Gufengmh : SinMH("古风漫画网", "https://www.gufengmh9.com") {
|
||||
|
||||
override val dateSelector = ".pic_zi:nth-of-type(4) > dd"
|
||||
override fun mangaDetailsParse(document: Document): SManga =
|
||||
super.mangaDetailsParse(document).apply {
|
||||
if (status == SManga.COMPLETED) return@apply
|
||||
val firstChapter = document.selectFirst(".chapter-body li > a") ?: return@apply
|
||||
if (firstChapter.attr("href").startsWith("javascript"))
|
||||
status = SManga.LICENSED
|
||||
}
|
||||
|
||||
override fun chapterListSelector() = ".list li > a"
|
||||
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> =
|
||||
Single.create<List<SChapter>> { subscriber ->
|
||||
val pcResponse = client.newCall(GET(baseUrl + manga.url, headers)).execute()
|
||||
val pcResult = chapterListParse(pcResponse, ".chapter-body li > a", "span.sj")
|
||||
if (pcResult.none { it.url.isEmpty() }) return@create subscriber.onSuccess(pcResult)
|
||||
// Example: https://www.gufengmh9.com/manhua/niaoling/
|
||||
val mobileResponse = client.newCall(GET(mobileUrl + manga.url, headers)).execute()
|
||||
val mobileResult = chapterListParse(mobileResponse, ".list li > a", ".pic_zi:nth-of-type(4) > dd")
|
||||
val pcAscending = pcResult.asReversed()
|
||||
val mobileAscending = mobileResult.asReversed()
|
||||
for ((pcChapter, mobileChapter) in pcAscending zip mobileAscending) {
|
||||
if (pcChapter.name != mobileChapter.name) return@create subscriber.onSuccess(mobileResult)
|
||||
pcChapter.url = mobileChapter.url
|
||||
}
|
||||
pcAscending.forEachIndexed { i, chapter ->
|
||||
if (chapter.url.isNotEmpty()) return@forEachIndexed
|
||||
if (i == 0) return@create subscriber.onSuccess(mobileResult)
|
||||
val prevUrl = pcAscending[i - 1].url
|
||||
val response = client.newCall(GET(baseUrl + prevUrl, headers)).execute()
|
||||
chapter.url = buildString {
|
||||
append(prevUrl, 0, prevUrl.lastIndexOf('/') + 1)
|
||||
append(ProgressiveParser(response.body!!.string()).substringBetween("""nextChapterData = {"id":""", ","))
|
||||
append(".html")
|
||||
}
|
||||
}
|
||||
subscriber.onSuccess(pcResult)
|
||||
}.toObservable()
|
||||
}
|
||||
|
@ -2,22 +2,25 @@ package eu.kanade.tachiyomi.extension.zh.imitui
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.sinmh.SinMH
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import rx.Observable
|
||||
import rx.Single
|
||||
|
||||
class Imitui : SinMH("爱米推漫画", "https://www.imitui.com") {
|
||||
|
||||
override fun chapterListSelector() = ".chapter-body li > a:not([href^=/comic/app/])"
|
||||
|
||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> =
|
||||
client.newCall(GET(baseUrl + chapter.url, headers)).asObservableSuccess().map {
|
||||
val pcResult = pageListParse(it)
|
||||
if (pcResult.isNotEmpty()) return@map pcResult
|
||||
val response = client.newCall(GET(mobileUrl + chapter.url, headers)).execute()
|
||||
mobilePageListParse(response.asJsoup())
|
||||
}
|
||||
Single.create<List<Page>> {
|
||||
val pcResponse = client.newCall(GET(baseUrl + chapter.url, headers)).execute()
|
||||
val pcResult = pageListParse(pcResponse.asJsoup())
|
||||
if (pcResult.isNotEmpty()) return@create it.onSuccess(pcResult)
|
||||
val mobileResponse = client.newCall(GET(mobileUrl + chapter.url, headers)).execute()
|
||||
it.onSuccess(mobilePageListParse(mobileResponse.asJsoup()))
|
||||
}.toObservable()
|
||||
|
||||
private fun mobilePageListParse(document: Document): List<Page> {
|
||||
val pageCount = document.select("div.image-content > p").text().removePrefix("1/").toInt()
|
||||
|
@ -52,7 +52,7 @@ class WuqiManga : SinMH("57漫画", "http://www.wuqimh.net") {
|
||||
override val dateSelector = ".cont-list dt:contains(更新于) + dd"
|
||||
|
||||
override val imageHost: String by lazy {
|
||||
client.newCall(GET("$baseUrl/templates/wuqi/default/scripts/configs.js", headers)).execute().use {
|
||||
client.newCall(GET("$baseUrl/templates/wuqi/default/scripts/configs.js", headers)).execute().let {
|
||||
Regex("""\['(.+?)']""").find(it.body!!.string())!!.groupValues[1].run { "http://$this" }
|
||||
}
|
||||
}
|
||||
@ -73,15 +73,14 @@ class WuqiManga : SinMH("57漫画", "http://www.wuqimh.net") {
|
||||
return@replace if (key < size) dictionary[key] else this
|
||||
}
|
||||
}.removeSurrounding("'").split("','")
|
||||
return unpacked.filterNot { it.endsWith("/ManHuaKu/222.jpg") }.mapIndexed { i, image ->
|
||||
val imageUrl = if (image.startsWith("http")) image else imageHost + image
|
||||
Page(i, imageUrl = imageUrl)
|
||||
}.also { list ->
|
||||
if (list.isEmpty()) return emptyList()
|
||||
client.newCall(GET(list[0].imageUrl!!, headers)).execute().use {
|
||||
if (!it.isSuccessful) throw Exception("该章节的图片加载出错:${it.code}")
|
||||
}
|
||||
val list = unpacked.filterNot { it.endsWith("/ManHuaKu/222.jpg") }.map { image ->
|
||||
if (image.startsWith("http")) image else imageHost + image
|
||||
}
|
||||
if (list.isEmpty()) return emptyList()
|
||||
client.newCall(GET(list[0], headers)).execute().apply { close() }.also {
|
||||
if (!it.isSuccessful) throw Exception("该章节的图片加载出错:${it.code}")
|
||||
}
|
||||
return list.mapIndexed { i, imageUrl -> Page(i, imageUrl = imageUrl) }
|
||||
}
|
||||
|
||||
override fun parseCategories(document: Document) {
|
||||
|
@ -151,8 +151,12 @@ abstract class SinMH(
|
||||
protected open fun List<SChapter>.sortedDescending() = this.asReversed()
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
return chapterListParse(response, chapterListSelector(), dateSelector)
|
||||
}
|
||||
|
||||
protected fun chapterListParse(response: Response, listSelector: String, dateSelector: String): List<SChapter> {
|
||||
val document = response.asJsoup()
|
||||
return document.select(chapterListSelector()).map { chapterFromElement(it) }.sortedDescending().apply {
|
||||
return document.select(listSelector).map { chapterFromElement(it) }.sortedDescending().apply {
|
||||
if (isNewDateLogic && this.isNotEmpty()) {
|
||||
val date = document.selectFirst(dateSelector).textNodes().last().text()
|
||||
this[0].date_upload = DATE_FORMAT.parse(date)?.time ?: 0L
|
||||
@ -160,9 +164,9 @@ abstract class SinMH(
|
||||
}
|
||||
}
|
||||
|
||||
override fun chapterListSelector() = ".chapter-body li > a:not([href^=/comic/app/])"
|
||||
override fun chapterListSelector() = ".chapter-body li > a"
|
||||
override fun chapterFromElement(element: Element) = SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.attr("href"))
|
||||
runCatching { setUrlWithoutDomain(element.attr("href")) }.onFailure { url = "" }
|
||||
val children = element.children()
|
||||
name = if (children.isEmpty()) element.text() else children[0].text()
|
||||
}
|
||||
@ -172,7 +176,7 @@ abstract class SinMH(
|
||||
override fun pageListRequest(chapter: SChapter) = GET(mobileUrl + chapter.url, headers)
|
||||
|
||||
protected open val imageHost: String by lazy {
|
||||
client.newCall(GET("$baseUrl/js/config.js", headers)).execute().use {
|
||||
client.newCall(GET("$baseUrl/js/config.js", headers)).execute().let {
|
||||
Regex("""resHost:.+?"domain":\["(.+?)"""").find(it.body!!.string())!!
|
||||
.groupValues[1].substringAfter(':').run { "https:$this" }
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class SinMHGenerator : ThemeSourceGenerator {
|
||||
override val sources = listOf(
|
||||
SingleLang(
|
||||
name = "Gufeng Manhua", baseUrl = "https://www.gufengmh9.com", lang = "zh",
|
||||
className = "Gufengmh", sourceName = "古风漫画网", overrideVersionCode = 5
|
||||
className = "Gufengmh", sourceName = "古风漫画网", overrideVersionCode = 6
|
||||
),
|
||||
SingleLang(
|
||||
name = "Imitui Manhua", baseUrl = "https://www.imitui.com", lang = "zh",
|
||||
|
Loading…
x
Reference in New Issue
Block a user