154 lines
5.8 KiB
Kotlin

package eu.kanade.tachiyomi.extension.zh.baozimhorg
import android.app.Application
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Evaluator
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat
import java.util.Locale
// Uses Elementor + Madara theme.
class BaozimhOrg : ConfigurableSource, Madara(
"包子漫画导航",
"",
"zh",
SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
) {
override val baseUrl: String
init {
val mirrors = MIRRORS
val mirrorIndex = Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
.getString(MIRROR_PREF, "0")!!.toInt().coerceAtMost(mirrors.size - 1)
baseUrl = "https://" + mirrors[mirrorIndex]
}
override val client = network.client
override val useLoadMoreSearch = false
override val sendViewCount = false
override fun popularMangaRequest(page: Int) = GET("$baseUrl/hots/$page/", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/dayup/$page/", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
if (query.isNotEmpty()) {
val url = "$baseUrl/page/$page/".toHttpUrl().newBuilder()
.addQueryParameter("s", query)
return Request.Builder().url(url.build()).headers(headers).build()
}
for (filter in filters) {
if (filter is UriPartFilter) return GET(baseUrl + filter.toUriPart() + "page/$page/", headers)
}
return popularMangaRequest(page)
}
override val popularMangaUrlSelector = "h3 > a"
override fun latestUpdatesParse(response: Response) = popularMangaParse(response)
override fun searchMangaParse(response: Response) = popularMangaParse(response)
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup().also(::parseGenresInternal)
val mangas = document.select(Evaluator.Tag("article")).map(::popularMangaFromElement)
val hasNextPage = document.selectFirst(Evaluator.Class("next"))?.tagName() == "a"
return MangasPage(mangas, hasNextPage)
}
override val mangaDetailsSelectorStatus = "none"
override val mangaDetailsSelectorDescription = "div.summary_content > div.post-content_item:last-child"
override val seriesTypeSelector = "none"
override val altNameSelector = "none"
override fun mangaDetailsParse(document: Document): SManga {
val manga = super.mangaDetailsParse(document)
val genre = manga.genre ?: return manga
val genreList = genre.split(", ") as ArrayList<String>
for ((index, tag) in genreList.withIndex()) {
val status = when (tag) {
"连载中" -> SManga.ONGOING
"已完结" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
if (status != SManga.UNKNOWN) {
manga.status = status
genreList.removeAt(index)
manga.genre = genreList.joinToString()
return manga
}
}
return manga
}
override fun chapterFromElement(element: Element) = SChapter.create().apply {
val link = element.selectFirst(Evaluator.Tag("a"))
url = link.attr("href").removePrefix(baseUrl)
name = link.ownText()
date_upload = parseChapterDate(link.child(0).text())
}
override fun parseRelativeDate(date: String) =
super.parseRelativeDate(date.replace("小时", "hour"))
// Jsoup won't ignore duplicates inside <noscript> tag
override val pageListParseSelector = ".text-left img.lazyload"
var genres: Array<Pair<String, String>> = emptyArray()
private fun parseGenresInternal(document: Document) {
if (genres.isNotEmpty()) return
val box = document.selectFirst("[data-elementor-type=header] + div nav > ul") ?: return
val items = box.select(Evaluator.Class("menu-item-type-custom"))
genres = buildList(items.size + 1) {
add(Pair("全部", "/allmanga/"))
items.mapTo(this) {
val link = it.child(0)
Pair(link.ownText(), link.attr("href"))
}
}.toTypedArray()
}
override fun getFilterList(): FilterList =
if (genres.isEmpty()) {
FilterList(listOf(Filter.Header("点击“重置”刷新分类")))
} else {
val list = listOf(
Filter.Header("分类(搜索文本时无效)"),
UriPartFilter("分类", genres),
)
FilterList(list)
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
ListPreference(screen.context).apply {
val mirrors = MIRRORS
key = MIRROR_PREF
title = "镜像网址"
summary = "%s\n重启生效"
entries = mirrors
entryValues = Array(mirrors.size) { it.toString() }
setDefaultValue("0")
}.let(screen::addPreference)
}
companion object {
private const val MIRROR_PREF = "MIRROR"
private val MIRRORS get() = arrayOf("baozimh.org", "cn.godamanga.com")
}
}