Mangahub (ru): fix popular, latest, pages, author (#2114)
* Mangahub (ru): fix popular, latest, pages, author * only check form in text/html responses
This commit is contained in:
parent
01de950ce9
commit
937843c751
|
@ -1,7 +1,8 @@
|
|||
ext {
|
||||
extName = 'Mangahub'
|
||||
extClass = '.Mangahub'
|
||||
extVersionCode = 17
|
||||
extVersionCode = 18
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
||||
|
|
|
@ -7,16 +7,16 @@ import eu.kanade.tachiyomi.source.model.Page
|
|||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import kotlin.math.absoluteValue
|
||||
|
@ -33,9 +33,39 @@ open class Mangahub : ParsedHttpSource() {
|
|||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
||||
.addInterceptor(::confirmAgeInterceptor)
|
||||
.rateLimit(2)
|
||||
.build()
|
||||
|
||||
private fun confirmAgeInterceptor(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
val response = chain.proceed(request)
|
||||
|
||||
if (request.method != "GET" ||
|
||||
response.header("Content-Type")?.contains("text/html") != true
|
||||
) {
|
||||
return response
|
||||
}
|
||||
|
||||
val document = Jsoup.parse(
|
||||
response.peekBody(Long.MAX_VALUE).string(),
|
||||
request.url.toString(),
|
||||
)
|
||||
|
||||
val formElement = document.selectFirst("#confirm_age__token")
|
||||
?: return response
|
||||
|
||||
val formBody = FormBody.Builder()
|
||||
.addEncoded(formElement.attr("name"), formElement.attr("value"))
|
||||
.build()
|
||||
|
||||
val confirmAgeRequest = request.newBuilder()
|
||||
.method("POST", formBody)
|
||||
.build()
|
||||
|
||||
return client.newCall(confirmAgeRequest).execute()
|
||||
}
|
||||
|
||||
private val userAgentRandomizer = "${Random.nextInt().absoluteValue}"
|
||||
|
||||
override fun headersBuilder() = Headers.Builder().apply {
|
||||
|
@ -43,13 +73,15 @@ open class Mangahub : ParsedHttpSource() {
|
|||
add("Referer", baseUrl)
|
||||
}
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
override fun popularMangaRequest(page: Int): Request {
|
||||
val pageStr = if (page > 1) "?page=$page" else ""
|
||||
return GET("$baseUrl/explore/sort-is-rating$pageStr", headers)
|
||||
}
|
||||
|
||||
override fun popularMangaRequest(page: Int): Request =
|
||||
GET("$baseUrl/explore?filter[sort]=rating&filter[dateStart][left_number]=1900&filter[dateStart][right_number]=2099&page=$page", headers)
|
||||
|
||||
override fun latestUpdatesRequest(page: Int): Request =
|
||||
GET("$baseUrl/explore?filter[sort]=update&filter[dateStart][left_number]=1900&filter[dateStart][right_number]=2099&page=$page", headers)
|
||||
override fun latestUpdatesRequest(page: Int): Request {
|
||||
val pageStr = if (page > 1) "?page=$page" else ""
|
||||
return GET("$baseUrl/explore/sort-is-update$pageStr", headers)
|
||||
}
|
||||
|
||||
override fun popularMangaSelector() = "div.comic-grid-col-xl"
|
||||
|
||||
|
@ -71,7 +103,11 @@ open class Mangahub : ParsedHttpSource() {
|
|||
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
return GET("$baseUrl/search/manga?query=$query&sort=rating_short&page=$page")
|
||||
val url = "$baseUrl/search/manga".toHttpUrl().newBuilder().apply {
|
||||
addQueryParameter("query", query)
|
||||
if (page > 1) addQueryParameter("page", page.toString())
|
||||
}
|
||||
return GET(url.build(), headers)
|
||||
}
|
||||
|
||||
override fun searchMangaSelector() = popularMangaSelector()
|
||||
|
@ -87,7 +123,7 @@ open class Mangahub : ParsedHttpSource() {
|
|||
|
||||
override fun mangaDetailsParse(document: Document): SManga {
|
||||
val manga = SManga.create()
|
||||
manga.author = document.select("div.detail-attr:contains(Автор) div:gt(0)").text() // TODO: Add "Сценарист" and "Художник"
|
||||
manga.author = document.select(".attr-name:contains(Автор) + .attr-value").text() // TODO: Add "Сценарист" and "Художник"
|
||||
manga.genre = document.select(".tags a").joinToString { it.text() }
|
||||
manga.description = document.select("div.markdown-style").text()
|
||||
manga.status = parseStatus(document.select("div.detail-attr:contains(перевод):eq(0)").toString())
|
||||
|
@ -125,14 +161,10 @@ open class Mangahub : ParsedHttpSource() {
|
|||
}
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
val chapInfo = document.select("reader")
|
||||
.attr("data-store")
|
||||
.replace(""", "\"")
|
||||
.replace("\\/", "/")
|
||||
val chapter = json.parseToJsonElement(chapInfo).jsonObject
|
||||
|
||||
return chapter["scans"]!!.jsonArray.mapIndexed { i, jsonEl ->
|
||||
Page(i, "", "https:" + jsonEl.jsonObject["src"]!!.jsonPrimitive.content)
|
||||
val images = document.select("img.reader-viewer-img")
|
||||
return images.mapIndexed { i, img ->
|
||||
val url = img.attr("data-src").let { if (it.startsWith("//")) "https:$it" else it }
|
||||
Page(i, document.location(), url)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue