mirror of
https://github.com/keiyoushi/extensions-source.git
synced 2024-11-22 10:22:47 +01:00
SinMH: update sources (#831)
This commit is contained in:
parent
d49d78fb20
commit
2b60f3ecf4
@ -1,16 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.extension.zh.imitui
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.sinmh.SinMH
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
|
|
||||||
class Imitui : SinMH("爱米推漫画", "https://www.imitui.com") {
|
|
||||||
|
|
||||||
override fun chapterListSelector() = ".chapter-body li > a:not([href^=/comic/app/])"
|
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> =
|
|
||||||
document.select("img[onclick]").mapIndexed { index, img ->
|
|
||||||
val url = img.attr("data-src").ifEmpty { img.attr("src") }
|
|
||||||
Page(index, imageUrl = url)
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
13
multisrc/overrides/sinmh/jiuermanhua/src/JiuerManhua.kt
Normal file
13
multisrc/overrides/sinmh/jiuermanhua/src/JiuerManhua.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.zh.jiuermanhua
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.sinmh.SinMH
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
|
||||||
|
class JiuerManhua : SinMH("92漫画", "http://www.92mh.com") {
|
||||||
|
|
||||||
|
override fun mangaDetailsParse(document: Document) = mangaDetailsParseDMZJStyle(document, hasBreadcrumb = false)
|
||||||
|
|
||||||
|
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
|
||||||
|
}
|
@ -7,7 +7,7 @@ import org.jsoup.nodes.Document
|
|||||||
// This site blocks IP outside China
|
// This site blocks IP outside China
|
||||||
class YKMH : SinMH("优酷漫画", "http://www.ykmh.com") {
|
class YKMH : SinMH("优酷漫画", "http://www.ykmh.com") {
|
||||||
override val id = 1637952806167036168
|
override val id = 1637952806167036168
|
||||||
override val mobileUrl = "http://wap.ykmh.com"
|
override val mobileUrl = "http://h5.ykmh.com"
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document) = mangaDetailsParseDMZJStyle(document, hasBreadcrumb = false)
|
override fun mangaDetailsParse(document: Document) = mangaDetailsParseDMZJStyle(document, hasBreadcrumb = false)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import javax.crypto.Cipher
|
|||||||
import javax.crypto.spec.IvParameterSpec
|
import javax.crypto.spec.IvParameterSpec
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
class Qinqin : SinMH("亲亲漫画", "https://www.acgud.com") {
|
class Qinqin : SinMH("亲亲漫画", "http://www.acgwd.com") {
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/post/?page=$page", headers)
|
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/post/?page=$page", headers)
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
dependencies {
|
|
||||||
implementation project(':lib:unpacker')
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.extension.zh.wuqimanga
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.lib.unpacker.Unpacker
|
|
||||||
import eu.kanade.tachiyomi.multisrc.sinmh.SinMH
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
|
||||||
import okhttp3.Request
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import org.jsoup.select.Evaluator
|
|
||||||
|
|
||||||
// Memo: the old implementation had a string preference with key "IMAGE_SERVER"
|
|
||||||
// Updating the domain to www.wuqimh.com causes some requests to return 404
|
|
||||||
class WuqiManga : SinMH("57漫画", "http://www.wuqimh.net") {
|
|
||||||
|
|
||||||
override val nextPageSelector = "span.pager > a:last-child" // in the last page it's a span
|
|
||||||
override val comicItemSelector = "#contList > li, .book-result > li"
|
|
||||||
override val comicItemTitleSelector = "p > a, dt > a"
|
|
||||||
|
|
||||||
// 人气排序的漫画全是 404,所以就用默认的最新发布了
|
|
||||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/order-id-p-$page", headers)
|
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/list/order-addtime-p-$page", headers)
|
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
||||||
val isSearch = query.isNotEmpty()
|
|
||||||
val params = arrayListOf<String>()
|
|
||||||
if (isSearch) params.add(query)
|
|
||||||
filters.filterIsInstance<UriPartFilter>().mapTo(params) { it.toUriPart() }
|
|
||||||
params.add("p-")
|
|
||||||
val url = buildString(120) {
|
|
||||||
append(baseUrl)
|
|
||||||
append(if (isSearch) "/search/q_" else "/list/")
|
|
||||||
params.joinTo(this, separator = "-", postfix = page.toString())
|
|
||||||
}
|
|
||||||
return GET(url, headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document) = super.mangaDetailsParse(document).apply {
|
|
||||||
val comment = document.selectFirst(".book-title > h2")!!.text()
|
|
||||||
if (comment.isNotEmpty()) description = "$comment\n\n$description"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mangaDetailsParseDefaultGenre(document: Document, detailsList: Element): String =
|
|
||||||
document.selectFirst("div.crumb")!!.select("a[href^=/list/]")
|
|
||||||
.map { it.text().removeSuffix("年").removeSuffix("漫画") }
|
|
||||||
.filter { it.isNotEmpty() }.joinToString(", ")
|
|
||||||
|
|
||||||
override fun chapterListSelector() = ".chapter-list li > a"
|
|
||||||
override fun List<SChapter>.sortedDescending() = this
|
|
||||||
override val dateSelector = ".cont-list dt:contains(更新于) + dd"
|
|
||||||
|
|
||||||
override val imageHost: String by lazy {
|
|
||||||
client.newCall(GET("$mobileUrl/templates_pc/default/scripts/configs.js", headers)).execute().let {
|
|
||||||
Regex("""\['(.+?)']""").find(it.body.string())!!.groupValues[1].run { "http://$this" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
|
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
|
||||||
val script = document.selectFirst("body > script")!!.html()
|
|
||||||
val unpacked = Unpacker.unpack(script, ":[", "]")
|
|
||||||
.ifEmpty { return emptyList() }
|
|
||||||
.replace("\\", "")
|
|
||||||
.removeSurrounding("\"").split("\",\"")
|
|
||||||
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) {
|
|
||||||
if (categories.isNotEmpty()) return
|
|
||||||
val labelSelector = Evaluator.Tag("label")
|
|
||||||
val linkSelector = Evaluator.Tag("a")
|
|
||||||
val filterMap = LinkedHashMap<String, LinkedHashMap<String, String>>(8)
|
|
||||||
document.select(Evaluator.Class("filter")).forEach { row ->
|
|
||||||
val tags = row.select(linkSelector)
|
|
||||||
if (tags.isEmpty()) return@forEach
|
|
||||||
val name = row.selectFirst(labelSelector)!!.text().removeSuffix(":")
|
|
||||||
if (!filterMap.containsKey(name)) {
|
|
||||||
filterMap[name] = LinkedHashMap(tags.size * 2)
|
|
||||||
}
|
|
||||||
val tagMap = filterMap[name]!!
|
|
||||||
for (tag in tags) {
|
|
||||||
val tagName = tag.text()
|
|
||||||
if (!tagMap.containsKey(tagName)) {
|
|
||||||
tagMap[tagName] = tag.attr("href").removePrefix("/list/").substringBeforeLast("-order-")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
categories = filterMap.map {
|
|
||||||
val tagMap = it.value
|
|
||||||
Category(it.key, tagMap.keys.toTypedArray(), tagMap.values.toTypedArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFilterList(): FilterList {
|
|
||||||
val list: ArrayList<Filter<*>>
|
|
||||||
if (categories.isNotEmpty()) {
|
|
||||||
list = ArrayList(categories.size + 2)
|
|
||||||
with(list) {
|
|
||||||
add(Filter.Header("使用文本搜索时,只有地区、年份、字母选项有效"))
|
|
||||||
categories.forEach { add(it.toUriPartFilter()) }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list = ArrayList(4)
|
|
||||||
with(list) {
|
|
||||||
add(Filter.Header("点击“重置”即可刷新分类,如果失败,"))
|
|
||||||
add(Filter.Header("请尝试重新从图源列表点击进入图源"))
|
|
||||||
add(Filter.Header("使用文本搜索时,只有地区、年份、字母选项有效"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list.add(UriPartFilter("排序方式", sortNames, sortKeys))
|
|
||||||
return FilterList(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val sortNames = arrayOf("最新发布", "最近更新", "人气最旺", "评分最高")
|
|
||||||
private val sortKeys = arrayOf("order-id", "order-addtime", "order-hits", "order-gold")
|
|
||||||
}
|
|
@ -37,6 +37,7 @@ abstract class SinMH(
|
|||||||
override val client = network.client.newBuilder().rateLimit(2).build()
|
override val client = network.client.newBuilder().rateLimit(2).build()
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
|
.add("User-Agent", System.getProperty("http.agent")!!)
|
||||||
.add("Referer", baseUrl)
|
.add("Referer", baseUrl)
|
||||||
|
|
||||||
protected open val nextPageSelector = "ul.pagination > li.next:not(.disabled)"
|
protected open val nextPageSelector = "ul.pagination > li.next:not(.disabled)"
|
||||||
@ -100,6 +101,8 @@ abstract class SinMH(
|
|||||||
|
|
||||||
// Details
|
// Details
|
||||||
|
|
||||||
|
override fun getMangaUrl(manga: SManga) = mobileUrl + manga.url
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||||
title = document.selectFirst(".book-title > h1")!!.text()
|
title = document.selectFirst(".book-title > h1")!!.text()
|
||||||
val detailsList = document.selectFirst(Evaluator.Class("detail-list"))!!
|
val detailsList = document.selectFirst(Evaluator.Class("detail-list"))!!
|
||||||
@ -130,13 +133,13 @@ abstract class SinMH(
|
|||||||
title = detailsDiv.selectFirst(Evaluator.Tag("h1"))!!.text()
|
title = detailsDiv.selectFirst(Evaluator.Tag("h1"))!!.text()
|
||||||
val details = detailsDiv.select("> ul > li")
|
val details = detailsDiv.select("> ul > li")
|
||||||
val linkSelector = Evaluator.Tag("a")
|
val linkSelector = Evaluator.Tag("a")
|
||||||
author = details[0].selectFirst(linkSelector)!!.text()
|
author = details[0].text().removePrefix("作者:").trimStart()
|
||||||
status = when (details[1].selectFirst(linkSelector)!!.text()) {
|
status = when (details[1].selectFirst(linkSelector)!!.text()) {
|
||||||
"连载中" -> SManga.ONGOING
|
"连载中" -> SManga.ONGOING
|
||||||
"已完结" -> SManga.COMPLETED
|
"已完结" -> SManga.COMPLETED
|
||||||
else -> SManga.UNKNOWN
|
else -> SManga.UNKNOWN
|
||||||
}
|
}
|
||||||
genre = mutableListOf<Element>().apply {
|
genre = buildList {
|
||||||
add(details[2].selectFirst(linkSelector)!!) // 类别
|
add(details[2].selectFirst(linkSelector)!!) // 类别
|
||||||
addAll(details[3].select(linkSelector)) // 类型
|
addAll(details[3].select(linkSelector)) // 类型
|
||||||
if (hasBreadcrumb) addAll(document.selectFirst("div.mianbao")!!.select("a[href^=/list/]"))
|
if (hasBreadcrumb) addAll(document.selectFirst("div.mianbao")!!.select("a[href^=/list/]"))
|
||||||
@ -175,19 +178,21 @@ abstract class SinMH(
|
|||||||
/** 必须是 "section item" */
|
/** 必须是 "section item" */
|
||||||
override fun chapterListSelector() = ".chapter-body li > a"
|
override fun chapterListSelector() = ".chapter-body li > a"
|
||||||
override fun chapterFromElement(element: Element) = SChapter.create().apply {
|
override fun chapterFromElement(element: Element) = SChapter.create().apply {
|
||||||
runCatching { setUrlWithoutDomain(element.attr("href")) }.onFailure { url = "" }
|
setUrlWithoutDomain(element.attr("href"))
|
||||||
val children = element.children()
|
val children = element.children()
|
||||||
name = if (children.isEmpty()) element.text() else children[0].text()
|
name = if (children.isEmpty()) element.text() else children[0].text()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
|
|
||||||
|
override fun getChapterUrl(chapter: SChapter) = mobileUrl + chapter.url
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter) = GET(mobileUrl + chapter.url, headers)
|
override fun pageListRequest(chapter: SChapter) = GET(mobileUrl + chapter.url, headers)
|
||||||
|
|
||||||
protected open val imageHost: String by lazy {
|
protected open val imageHost: String by lazy {
|
||||||
client.newCall(GET("$baseUrl/js/config.js", headers)).execute().let {
|
client.newCall(GET("$baseUrl/js/config.js", headers)).execute().let {
|
||||||
Regex("""resHost:.+?"?domain"?:\["(.+?)"""").find(it.body.string())!!
|
Regex("""resHost:.+?"?domain"?:\["(.+?)"""").find(it.body.string())!!
|
||||||
.groupValues[1].substringAfter(':').run { "https:$this" }
|
.groupValues[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import generator.ThemeSourceGenerator
|
|||||||
class SinMHGenerator : ThemeSourceGenerator {
|
class SinMHGenerator : ThemeSourceGenerator {
|
||||||
override val themeClass = "SinMH"
|
override val themeClass = "SinMH"
|
||||||
override val themePkg = "sinmh"
|
override val themePkg = "sinmh"
|
||||||
override val baseVersionCode = 10
|
override val baseVersionCode = 11
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang(
|
SingleLang(
|
||||||
name = "Gufeng Manhua",
|
name = "Gufeng Manhua",
|
||||||
@ -16,18 +16,11 @@ class SinMHGenerator : ThemeSourceGenerator {
|
|||||||
sourceName = "古风漫画网",
|
sourceName = "古风漫画网",
|
||||||
overrideVersionCode = 6,
|
overrideVersionCode = 6,
|
||||||
),
|
),
|
||||||
SingleLang(
|
|
||||||
name = "Imitui Manhua",
|
|
||||||
baseUrl = "https://www.imitui.com",
|
|
||||||
lang = "zh",
|
|
||||||
className = "Imitui",
|
|
||||||
sourceName = "爱米推漫画",
|
|
||||||
overrideVersionCode = 3,
|
|
||||||
),
|
|
||||||
SingleLang( // This site blocks IP outside China
|
SingleLang( // This site blocks IP outside China
|
||||||
name = "YKMH",
|
name = "YKMH",
|
||||||
baseUrl = "http://www.ykmh.com",
|
baseUrl = "http://www.ykmh.com",
|
||||||
lang = "zh",
|
lang = "zh",
|
||||||
|
isNsfw = true,
|
||||||
className = "YKMH",
|
className = "YKMH",
|
||||||
pkgName = "manhuadui",
|
pkgName = "manhuadui",
|
||||||
sourceName = "优酷漫画",
|
sourceName = "优酷漫画",
|
||||||
@ -35,19 +28,20 @@ class SinMHGenerator : ThemeSourceGenerator {
|
|||||||
),
|
),
|
||||||
SingleLang(
|
SingleLang(
|
||||||
name = "Qinqin Manhua",
|
name = "Qinqin Manhua",
|
||||||
baseUrl = "https://www.acgud.com",
|
baseUrl = "http://www.acgwd.com",
|
||||||
lang = "zh",
|
lang = "zh",
|
||||||
className = "Qinqin",
|
className = "Qinqin",
|
||||||
sourceName = "亲亲漫画",
|
sourceName = "亲亲漫画",
|
||||||
overrideVersionCode = 2,
|
overrideVersionCode = 2,
|
||||||
),
|
),
|
||||||
SingleLang(
|
SingleLang(
|
||||||
name = "57Manhua",
|
name = "92Manhua",
|
||||||
baseUrl = "http://www.wuqimh.net",
|
baseUrl = "http://www.92mh.com",
|
||||||
lang = "zh",
|
lang = "zh",
|
||||||
className = "WuqiManga",
|
isNsfw = true,
|
||||||
sourceName = "57漫画",
|
className = "JiuerManhua",
|
||||||
overrideVersionCode = 5,
|
sourceName = "92漫画",
|
||||||
|
overrideVersionCode = 0,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user