Fix missing response at SuperMangas. (#6180)

This commit is contained in:
Alessandro Jean 2021-03-15 10:14:23 -03:00 committed by GitHub
parent 644e5e556d
commit 4df4d1b562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 20 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'Super Mangás'
pkgNameSuffix = 'pt.supermangas'
extClass = '.SuperMangasFactory'
extVersionCode = 6
extVersionCode = 7
libVersion = '1.2'
containsNsfw = true
}

View File

@ -8,6 +8,7 @@ import com.github.salomonbrys.kotson.obj
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.squareup.duktape.Duktape
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.model.Filter
@ -21,12 +22,15 @@ import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.net.URLEncoder
typealias Content = Triple<String, String, String>
@ -40,14 +44,16 @@ abstract class SuperMangasGeneric(
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.addInterceptor(::paginatorIntercept)
.build()
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("User-Agent", USER_AGENT)
.add("Origin", baseUrl)
.add("Referer", baseUrl)
.add("Accept", ACCEPT_COMMON)
.add("Accept-Language", ACCEPT_LANGUAGE)
.add("Origin", baseUrl)
.add("Referer", baseUrl)
.add("User-Agent", USER_AGENT)
protected open val defaultFilter = mutableMapOf(
"filter_display_view" to "lista",
@ -77,6 +83,7 @@ abstract class SuperMangasGeneric(
filterGenreDel: List<String> = emptyList(),
page: Int = 1
): Request {
val filters = jsonObject(
"filter_data" to filterData.toUrlQueryParams(),
"filter_genre_add" to jsonArray(filterGenreAdd),
@ -95,7 +102,7 @@ abstract class SuperMangasGeneric(
.add("X-Requested-With", "XMLHttpRequest")
.add("Content-Type", form.contentType().toString())
.add("Content-Length", form.contentLength().toString())
.add("Host", "www." + baseUrl.substringAfter("//"))
.set("Accept", ACCEPT_JSON)
.set("Referer", "$baseUrl/$typeUrl")
.build()
@ -108,6 +115,24 @@ abstract class SuperMangasGeneric(
setUrlWithoutDomain(element.attr("href"))
}
private fun paginatorTokenRequest(): Request = GET("$baseUrl/$listPath", headers)
private fun paginatorTokenParse(document: Document): String {
val script = document.select("script:containsData(ajaxSetup)").firstOrNull()
?: return ""
val scriptContent = script.data()
.substringAfter("eval")
.substringBefore("function checkSize")
.substringBefore("eval")
.substringBeforeLast(")")
.replace("return p}", "return p})")
val unpacked = Duktape.create().evaluate(scriptContent) as String
return unpacked.substringAfter("TOKEN_CSRF=\"").substringBefore("\";")
}
override fun popularMangaRequest(page: Int): Request = genericPaginatedRequest(listPath, page = page)
override fun popularMangaParse(response: Response): MangasPage {
@ -122,9 +147,12 @@ abstract class SuperMangasGeneric(
popularMangaFromElement(element)
}
val requestBody = response.request().body() as FormBody
val requestBody = response.request().body().bodyToString()
val totalPage = result["total_page"].string.toInt()
val page = requestBody.value("page").toInt()
val page = requestBody
.substringAfter("page=")
.substringBefore("&")
.toInt()
val hasNextPage = page < totalPage
return MangasPage(mangas, hasNextPage)
@ -311,6 +339,33 @@ abstract class SuperMangasGeneric(
return GET(page.imageUrl!!, newHeaders)
}
private fun paginatorIntercept(chain: Interceptor.Chain): Response {
if (!chain.request().url().toString().contains("paginator.inc")) {
return chain.proceed(chain.request())
}
val csrfTokenRequest = paginatorTokenRequest()
val csrfTokenResponse = chain.proceed(csrfTokenRequest)
val csrfTokenDocument = csrfTokenResponse.asJsoup()
val csrfToken = paginatorTokenParse(csrfTokenDocument)
val totalPage = csrfTokenDocument.select("select.pageSelect option").last()
.attr("value")
val body = chain.request().body()!!
val newBody = "token=" + URLEncoder.encode(csrfToken, "utf-8") +
"&total_page=" + totalPage + "&" + body.bodyToString()
val requestBody = RequestBody.create(body.contentType(), newBody)
val newRequest = chain.request().newBuilder()
.header("Content-Length", newBody.length.toString())
.post(requestBody)
.build()
return chain.proceed(newRequest)
}
protected class Tag(val id: String, name: String) : Filter.TriState(name)
protected class ContentFilter(contents: List<Content>) : Filter.Select<String>(
@ -352,25 +407,34 @@ abstract class SuperMangasGeneric(
else -> SManga.UNKNOWN
}
protected fun Response.asJsonObject(): JsonObject =
JSON_PARSER.parse(body()!!.string().substringAfter("</b>")).obj
protected fun Response.asJsonObject(): JsonObject {
val body = body()!!.string().substringAfter("</b>")
if (body.isEmpty()) {
throw Exception(BLOCK_MESSAGE)
}
return JSON_PARSER.parse(body).obj
}
private fun RequestBody?.bodyToString(): String {
if (this == null) return ""
val buffer = okio.Buffer()
writeTo(buffer)
return buffer.readUtf8()
}
private fun Map<String, String>.toUrlQueryParams(): String =
map { (k, v) -> "$k=$v" }.joinToString("&")
private fun FormBody.value(name: String): String {
return (0 until size())
.first { name(it) == name }
.let { value(it) }
}
companion object {
private const val ACCEPT_COMMON = "text/html,application/xhtml+xml,application/xml;q=0.9," +
"image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
private const val ACCEPT_JSON = "application/json, text/javascript, */*; q=0.01"
private const val ACCEPT_LANGUAGE = "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,gl;q=0.5"
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
private const val BLOCK_MESSAGE = "O site está bloqueando o Tachiyomi. Tente novamente mais tarde ou migre para outra fonte."
private val JSON_PARSER by lazy { JsonParser() }

View File

@ -18,7 +18,7 @@ import org.jsoup.Jsoup
@Nsfw
class SuperHentais : SuperMangasGeneric(
"Super Hentais",
"https://superhentais.com",
"https://www.superhentais.com",
"hentai-manga"
) {
// Hardcode the id because the language wasn't specific.

View File

@ -13,9 +13,9 @@ import okhttp3.Response
class SuperMangas : SuperMangasGeneric(
"Super Mangás",
"https://supermangas.site"
"https://www.supermangas.site"
) {
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(::tempCoverImageFixIntercept)
.build()