MDB: clean up and fix ManhuaDB thumbnail (#12671)
* ManhuaDB: fix thumbnail URL * MDB: inline selectors and clean up * MDB: bump version
This commit is contained in:
parent
5972fde3e4
commit
e4a6bf97f0
@ -12,8 +12,6 @@ import kotlinx.serialization.decodeFromString
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import org.jsoup.select.Evaluator
|
|
||||||
import org.jsoup.select.QueryParser
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
@ -33,7 +31,7 @@ class ManhuaDB : MDB("漫画DB", "https://www.manhuadb.com"), ConfigurableSource
|
|||||||
override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used.")
|
override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used.")
|
||||||
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("Not used.")
|
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("Not used.")
|
||||||
|
|
||||||
override val authorSelector: Evaluator = QueryParser.parse("a.comic-creator")
|
override val authorSelector = "a.comic-creator"
|
||||||
override fun transformDescription(description: String) = description.substringBeforeLast("欢迎在漫画DB观看")
|
override fun transformDescription(description: String) = description.substringBeforeLast("欢迎在漫画DB观看")
|
||||||
|
|
||||||
override fun chapterListParse(response: Response) = super.chapterListParse(response).asReversed()
|
override fun chapterListParse(response: Response) = super.chapterListParse(response).asReversed()
|
||||||
@ -65,10 +63,6 @@ class ManhuaDB : MDB("漫画DB", "https://www.manhuadb.com"), ConfigurableSource
|
|||||||
title = "优先使用 WebP 图片格式"
|
title = "优先使用 WebP 图片格式"
|
||||||
summary = "默认开启,可以节省网站流量"
|
summary = "默认开启,可以节省网站流量"
|
||||||
setDefaultValue(true)
|
setDefaultValue(true)
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
|
||||||
preferences.edit().putBoolean(WEBP_PREF, newValue as Boolean).apply()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}.let { screen.addPreference(it) }
|
}.let { screen.addPreference(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
|||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import org.jsoup.select.Evaluator
|
|
||||||
import org.jsoup.select.QueryParser
|
|
||||||
import rufus.lzstring4java.LZString
|
import rufus.lzstring4java.LZString
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -29,7 +27,7 @@ class Maofly : MDB("漫画猫", "https://www.maofly.com") {
|
|||||||
override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
|
override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
|
||||||
|
|
||||||
override fun transformTitle(title: String) = title.run { substring(1, length - 1) } // 《title》
|
override fun transformTitle(title: String) = title.run { substring(1, length - 1) } // 《title》
|
||||||
override val authorSelector: Evaluator = QueryParser.parse("td.pub-duration")
|
override val authorSelector = "td.pub-duration"
|
||||||
override fun transformDescription(description: String) =
|
override fun transformDescription(description: String) =
|
||||||
description.substringAfter("的漫画作品。").substringBeforeLast(" 。。欢迎您到漫画猫畅快阅读。")
|
description.substringAfter("的漫画作品。").substringBeforeLast(" 。。欢迎您到漫画猫畅快阅读。")
|
||||||
|
|
||||||
@ -37,7 +35,7 @@ class Maofly : MDB("漫画猫", "https://www.maofly.com") {
|
|||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
return document.select(chapterListSelector()).map { chapterFromElement(it) }.apply {
|
return document.select(chapterListSelector()).map { chapterFromElement(it) }.apply {
|
||||||
if (!isNewDateLogic) return@apply
|
if (!isNewDateLogic) return@apply
|
||||||
this[0].date_upload = document.selectFirst(dateSelector).text()
|
this[0].date_upload = document.selectFirst("th:contains(上次更新) + td").text()
|
||||||
.let { dateFormat.parse(it)!!.time }
|
.let { dateFormat.parse(it)!!.time }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,8 +48,7 @@ class Maofly : MDB("漫画猫", "https://www.maofly.com") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val dateSelector = QueryParser.parse("th:contains(上次更新) + td")
|
private val dateFormat by lazy { SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH) }
|
||||||
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)
|
|
||||||
private val isNewDateLogic = AppInfo.getVersionCode() >= 81
|
private val isNewDateLogic = AppInfo.getVersionCode() >= 81
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ import okhttp3.Response
|
|||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import org.jsoup.select.Evaluator
|
import org.jsoup.select.Evaluator
|
||||||
import org.jsoup.select.QueryParser
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
|
||||||
/** ManhuaDB: https://www.manhuadb.com/ */
|
/** ManhuaDB: https://www.manhuadb.com/ */
|
||||||
@ -36,10 +35,10 @@ abstract class MDB(
|
|||||||
override fun popularMangaRequest(page: Int) = GET(listUrl("page-$page"), headers)
|
override fun popularMangaRequest(page: Int) = GET(listUrl("page-$page"), headers)
|
||||||
override fun popularMangaSelector() = "div.comic-main-section > div.comic-book-unit"
|
override fun popularMangaSelector() = "div.comic-main-section > div.comic-book-unit"
|
||||||
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
|
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
|
||||||
val link = element.selectFirst(listComicLinkSelector)
|
val link = element.selectFirst("h2 > a")
|
||||||
setUrlWithoutDomain(link.attr("href"))
|
setUrlWithoutDomain(link.attr("href"))
|
||||||
title = link.text()
|
title = link.text()
|
||||||
thumbnail_url = element.selectFirst(imgSelector).absUrl("src")
|
thumbnail_url = element.selectFirst(Evaluator.Tag("img")).absUrl("src")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
@ -68,27 +67,27 @@ abstract class MDB(
|
|||||||
throw UnsupportedOperationException("Not used.")
|
throw UnsupportedOperationException("Not used.")
|
||||||
|
|
||||||
protected open fun transformTitle(title: String) = title
|
protected open fun transformTitle(title: String) = title
|
||||||
protected abstract val authorSelector: Evaluator
|
protected abstract val authorSelector: String
|
||||||
protected open fun transformDescription(description: String) = description
|
protected open fun transformDescription(description: String) = description
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||||
title = document.selectFirst(h1Selector).text().let { transformTitle(it) }
|
title = document.selectFirst(Evaluator.Tag("h1")).text().let { transformTitle(it) }
|
||||||
author = document.selectFirst(authorSelector).text()
|
author = document.selectFirst(authorSelector).text()
|
||||||
description = document.selectFirst(descriptionSelector).text().let { transformDescription(it) }
|
description = document.selectFirst("p.comic_story").text().let { transformDescription(it) }
|
||||||
genre = parseGenre(document).joinToString(", ")
|
genre = parseGenre(document).joinToString(", ")
|
||||||
status = when (document.selectFirst(statusSelector).text()) {
|
status = when (document.selectFirst("a.comic-pub-state").text()) {
|
||||||
"连载中" -> SManga.ONGOING
|
"连载中" -> SManga.ONGOING
|
||||||
"已完结" -> SManga.COMPLETED
|
"已完结" -> SManga.COMPLETED
|
||||||
else -> SManga.UNKNOWN
|
else -> SManga.UNKNOWN
|
||||||
}
|
}
|
||||||
thumbnail_url = document.selectFirst(coverSelector).attr("src")
|
thumbnail_url = document.selectFirst("td.comic-cover > img").absUrl("src")
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun parseGenre(document: Document): List<String> {
|
protected open fun parseGenre(document: Document): List<String> {
|
||||||
val list = mutableListOf<String>()
|
val list = mutableListOf<String>()
|
||||||
list.add(document.selectFirst(regionSelector).text())
|
list.add(document.selectFirst("th:contains(地区) + td").text())
|
||||||
list.add(document.selectFirst(audienceSelector).text().removeSuffix("漫画"))
|
list.add(document.selectFirst("th:contains(面向读者) + td").text().removeSuffix("漫画"))
|
||||||
val tags = document.select(tagSelector)
|
val tags = document.select("ul.tags > li > a")
|
||||||
for (i in 1 until tags.size) { // skip status
|
for (i in 1 until tags.size) { // skip status
|
||||||
list.add(tags[i].text())
|
list.add(tags[i].text())
|
||||||
}
|
}
|
||||||
@ -102,12 +101,12 @@ abstract class MDB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
val imgData = document.selectFirst(scriptSelector).data()
|
val imgData = document.selectFirst("body > script:containsData(img_data)").data()
|
||||||
.substringAfter("img_data = ").run {
|
.substringAfter("img_data = ").run {
|
||||||
val endIndex = indexOf(this[0], startIndex = 1) // find end quote
|
val endIndex = indexOf(this[0], startIndex = 1) // find end quote
|
||||||
substring(1, endIndex)
|
substring(1, endIndex)
|
||||||
}
|
}
|
||||||
val readerConfig = document.selectFirst(readerConfigSelector)
|
val readerConfig = document.selectFirst(Evaluator.Class("vg-r-data"))
|
||||||
return parseImages(imgData, readerConfig).mapIndexed { i, it ->
|
return parseImages(imgData, readerConfig).mapIndexed { i, it ->
|
||||||
Page(i, imageUrl = it)
|
Page(i, imageUrl = it)
|
||||||
}
|
}
|
||||||
@ -117,11 +116,11 @@ abstract class MDB(
|
|||||||
|
|
||||||
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
|
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
|
||||||
|
|
||||||
protected data class Category(val name: String, val values: Array<String>, val params: List<String>) {
|
protected class Category(val name: String, private val values: Array<String>, private val params: List<String>) {
|
||||||
fun toFilter() = CategoryFilter(name, values, params)
|
fun toFilter() = CategoryFilter(name, values, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class CategoryFilter(name: String, values: Array<String>, val params: List<String>) :
|
protected class CategoryFilter(name: String, values: Array<String>, private val params: List<String>) :
|
||||||
Filter.Select<String>(name, values) {
|
Filter.Select<String>(name, values) {
|
||||||
fun getParam() = params[state]
|
fun getParam() = params[state]
|
||||||
}
|
}
|
||||||
@ -130,7 +129,7 @@ abstract class MDB(
|
|||||||
|
|
||||||
protected open fun parseCategories(document: Document) {
|
protected open fun parseCategories(document: Document) {
|
||||||
if (::categories.isInitialized) return
|
if (::categories.isInitialized) return
|
||||||
val filters = document.select(filterSelector)
|
val filters = document.select("div.search_div > div")
|
||||||
val list = ArrayList<Category>(filters.size + 1)
|
val list = ArrayList<Category>(filters.size + 1)
|
||||||
for (filter in filters) {
|
for (filter in filters) {
|
||||||
val children = filter.children()
|
val children = filter.children()
|
||||||
@ -144,9 +143,10 @@ abstract class MDB(
|
|||||||
values.add(link.text())
|
values.add(link.text())
|
||||||
params.add(link.attr("href").let(::extractParams).let(::parseParam))
|
params.add(link.attr("href").let(::extractParams).let(::parseParam))
|
||||||
}
|
}
|
||||||
list.add(Category(children[0].selectFirst(spanSelector).text(), values.toTypedArray(), params))
|
val name = children[0].selectFirst(Evaluator.Tag("span")).text()
|
||||||
|
list.add(Category(name, values.toTypedArray(), params))
|
||||||
} else if (filterContainer.hasClass("form-row")) { // Dropdown filter
|
} else if (filterContainer.hasClass("form-row")) { // Dropdown filter
|
||||||
for (select in filterContainer.select(selectSelector)) {
|
for (select in filterContainer.select(Evaluator.Tag("select"))) {
|
||||||
val options = select.children()
|
val options = select.children()
|
||||||
val values = ArrayList<String>(options.size).apply { add("全部") }
|
val values = ArrayList<String>(options.size).apply { add("全部") }
|
||||||
val params = ArrayList<String>(options.size).apply { add("") }
|
val params = ArrayList<String>(options.size).apply { add("") }
|
||||||
@ -177,21 +177,4 @@ abstract class MDB(
|
|||||||
Filter.Header("点击“重置”即可刷新分类,如果失败,"),
|
Filter.Header("点击“重置”即可刷新分类,如果失败,"),
|
||||||
Filter.Header("请尝试重新从图源列表点击进入图源"),
|
Filter.Header("请尝试重新从图源列表点击进入图源"),
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val listComicLinkSelector = QueryParser.parse("h2 > a")
|
|
||||||
private val imgSelector = Evaluator.Tag("img")
|
|
||||||
private val h1Selector = Evaluator.Tag("h1")
|
|
||||||
private val coverSelector = QueryParser.parse("td.comic-cover > img")
|
|
||||||
private val descriptionSelector = QueryParser.parse("p.comic_story")
|
|
||||||
private val tagSelector = QueryParser.parse("ul.tags > li > a")
|
|
||||||
private val statusSelector = QueryParser.parse("a.comic-pub-state")
|
|
||||||
private val regionSelector = QueryParser.parse("th:contains(地区) + td")
|
|
||||||
private val audienceSelector = QueryParser.parse("th:contains(面向读者) + td")
|
|
||||||
private val scriptSelector = QueryParser.parse("body > script:containsData(img_data)")
|
|
||||||
private val readerConfigSelector = Evaluator.Class("vg-r-data")
|
|
||||||
private val filterSelector = QueryParser.parse("div.search_div > div")
|
|
||||||
private val spanSelector = Evaluator.Tag("span")
|
|
||||||
private val selectSelector = Evaluator.Tag("select")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import generator.ThemeSourceGenerator
|
|||||||
class MDBGenerator : ThemeSourceGenerator {
|
class MDBGenerator : ThemeSourceGenerator {
|
||||||
override val themeClass = "MDB"
|
override val themeClass = "MDB"
|
||||||
override val themePkg = "mdb"
|
override val themePkg = "mdb"
|
||||||
override val baseVersionCode = 1
|
override val baseVersionCode = 2
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang("ManhuaDB", "https://www.manhuadb.com", "zh", sourceName = "漫画DB", overrideVersionCode = 4),
|
SingleLang("ManhuaDB", "https://www.manhuadb.com", "zh", sourceName = "漫画DB", overrideVersionCode = 4),
|
||||||
SingleLang("Maofly", "https://www.maofly.com", "zh", sourceName = "漫画猫", overrideVersionCode = 1),
|
SingleLang("Maofly", "https://www.maofly.com", "zh", sourceName = "漫画猫", overrideVersionCode = 1),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user