Koushoku: fix temp ban again (#12825)

This commit is contained in:
Vetle Ledaal 2022-07-31 16:12:19 +00:00 committed by GitHub
parent 3172857f59
commit 26fa0af501
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 70 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'Koushoku'
pkgNameSuffix = 'en.koushoku'
extClass = '.Koushoku'
extVersionCode = 10
extVersionCode = 11
isNsfw = true
}

View File

@ -11,7 +11,6 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
@ -38,7 +37,8 @@ class Koushoku : ParsedHttpSource() {
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.rateLimit(1)
.addInterceptor(KoushokuWebViewInterceptor())
.rateLimit(1, 4)
.build()
override fun headersBuilder(): Headers.Builder = super.headersBuilder()
@ -123,9 +123,21 @@ class Koushoku : ParsedHttpSource() {
override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector()
override fun popularMangaFromElement(element: Element) = latestUpdatesFromElement(element)
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return if (!manga.initialized) {
super.fetchMangaDetails(manga)
} else {
Observable.just(manga)
}
}
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.selectFirst(".metadata .title").text()
// Reuse cover from browse
thumbnail_url = document.selectFirst(thumbnailSelector).attr("src")
.replace(Regex("/\\d+\\.webp\$"), "/288.webp")
artist = document.select(".metadata .artists a, .metadata .circles a")
.joinToString { it.text() }
author = artist
@ -139,7 +151,7 @@ class Koushoku : ParsedHttpSource() {
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
antiBan(document)
return listOf(
SChapter.create().apply {
setUrlWithoutDomain(response.request.url.encodedPath)
@ -174,6 +186,14 @@ class Koushoku : ParsedHttpSource() {
}
}
override fun imageRequest(page: Page): Request {
val newHeaders = headersBuilder()
.add("Origin", baseUrl)
.build()
return GET(page.imageUrl!!, newHeaders)
}
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
override fun getFilterList() = FilterList(
@ -253,70 +273,4 @@ class Koushoku : ParsedHttpSource() {
val size = document.selectFirst(".metadata .size td:nth-child(2)")
append("Size: ").append(size.text())
}
// anti-ban
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
antiBan(document)
val mangas = document.select(popularMangaSelector()).map { element ->
popularMangaFromElement(element)
}
val hasNextPage = popularMangaNextPageSelector()?.let { selector ->
document.select(selector).first()
} != null
return MangasPage(mangas, hasNextPage)
}
override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
antiBan(document)
val mangas = document.select(searchMangaSelector()).map { element ->
searchMangaFromElement(element)
}
val hasNextPage = searchMangaNextPageSelector()?.let { selector ->
document.select(selector).first()
} != null
return MangasPage(mangas, hasNextPage)
}
override fun latestUpdatesParse(response: Response): MangasPage {
val document = response.asJsoup()
antiBan(document)
val mangas = document.select(latestUpdatesSelector()).map { element ->
latestUpdatesFromElement(element)
}
val hasNextPage = latestUpdatesNextPageSelector()?.let { selector ->
document.select(selector).first()
} != null
return MangasPage(mangas, hasNextPage)
}
override fun mangaDetailsParse(response: Response): SManga {
return mangaDetailsParse(response.asJsoup())
}
override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup()
antiBan(document)
return pageListParse(document)
}
private fun antiBan(document: Document) {
val styles = document.select("link[rel=stylesheet]")
styles.forEach {
val request = GET(it.absUrl("href"), headers, CacheControl.FORCE_NETWORK)
runCatching { client.newCall(request).execute().close() }
}
}
}

View File

@ -0,0 +1,70 @@
package eu.kanade.tachiyomi.extension.en.koushoku
import android.annotation.SuppressLint
import android.app.Application
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.webkit.WebView
import android.webkit.WebViewClient
import okhttp3.Interceptor
import okhttp3.Response
import org.jsoup.Jsoup
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.IOException
import java.util.concurrent.CountDownLatch
class KoushokuWebViewInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
val responseBody = response.peekBody(1 * 1024 * 1024).toString()
val document = Jsoup.parse(responseBody)
if (document.selectFirst("h1")?.text()?.contains(Regex("banned$")) == true) {
throw Exception("You have been banned. Check WebView for details.")
} else if (response.headers("Content-Type").any { it.contains("text/html") }) {
try {
proceedWithWebView(response)
} catch (e: Exception) {
throw IOException(e)
}
}
return response
}
@SuppressLint("SetJavaScriptEnabled")
private fun proceedWithWebView(response: Response) {
val latch = CountDownLatch(1)
val handler = Handler(Looper.getMainLooper())
handler.post {
val webview = WebView(Injekt.get<Application>())
with(webview.settings) {
javaScriptEnabled = true
loadsImagesAutomatically = false
userAgentString = response.request.header("User-Agent")
}
webview.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
latch.countDown()
}
}
webview.loadDataWithBaseURL(
response.request.url.toString(),
response.peekBody(1 * 1024 * 1024).toString(),
"text/html",
"utf-8",
null
)
}
latch.await()
}
}