Fix missing pages and add chapter auth check at Viz. (#6773)

This commit is contained in:
Alessandro Jean 2021-04-30 18:39:52 -03:00 committed by GitHub
parent b13ccc27ec
commit b2fc487395
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 16 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'VIZ Shonen Jump'
pkgNameSuffix = 'en.vizshonenjump'
extClass = '.VizShonenJump'
extVersionCode = 6
extVersionCode = 7
libVersion = '1.2'
}

View File

@ -1,5 +1,11 @@
package eu.kanade.tachiyomi.extension.en.vizshonenjump
import com.github.salomonbrys.kotson.bool
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.nullObj
import com.github.salomonbrys.kotson.obj
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
@ -11,6 +17,7 @@ import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
@ -32,6 +39,8 @@ class VizShonenJump : ParsedHttpSource() {
override val supportsLatest = true
override val client: OkHttpClient = network.client.newBuilder()
.addInterceptor(::authCheckIntercept)
.addInterceptor(::authChapterCheckIntercept)
.addInterceptor(VizImageInterceptor())
.build()
@ -42,6 +51,8 @@ class VizShonenJump : ParsedHttpSource() {
private var mangaList: List<SManga>? = null
private var loggedIn: Boolean? = null
override fun popularMangaRequest(page: Int): Request {
val newHeaders = headersBuilder()
.set("Referer", baseUrl)
@ -147,20 +158,10 @@ class VizShonenJump : ParsedHttpSource() {
override fun chapterListParse(response: Response): List<SChapter> {
val allChapters = super.chapterListParse(response)
val newHeaders = headersBuilder()
.add("X-Requested-With", "XMLHttpRequest")
.set("Referer", response.request.url.toString())
.build()
val loginCheckRequest = GET(REFRESH_LOGIN_LINKS_URL, newHeaders)
val document = client.newCall(loginCheckRequest).execute().asJsoup()
val isLoggedIn = document.select("div#o_account-links-content").first()!!
.attr("logged_in")!!.toBoolean()
if (isLoggedIn) {
if (loggedIn == true) {
return allChapters.map { oldChapter ->
oldChapter.apply {
url = url.substringAfter("'").substringBeforeLast("'")
url = url.substringAfter("'").substringBeforeLast("'") + "&locked=true"
}
}
}
@ -212,7 +213,7 @@ class VizShonenJump : ParsedHttpSource() {
.substringAfterLast("/")
.substringBefore("?")
return IntRange(1, pageCount)
return IntRange(0, pageCount)
.map {
val imageUrl = "$baseUrl/manga/get_manga_url".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("device_id", "3")
@ -233,6 +234,7 @@ class VizShonenJump : ParsedHttpSource() {
.toString()
val newHeaders = headersBuilder()
.add("X-Client-Login", (loggedIn ?: false).toString())
.add("X-Requested-With", "XMLHttpRequest")
.set("Referer", referer)
.build()
@ -265,6 +267,72 @@ class VizShonenJump : ParsedHttpSource() {
return GET(newImageUrl, newHeaders)
}
private fun authCheckIntercept(chain: Interceptor.Chain): Response {
if (loggedIn == null) {
val refreshHeaders = headersBuilder()
.add("X-Requested-With", "XMLHttpRequest")
.build()
val loginCheckRequest = GET("$baseUrl/$REFRESH_LOGIN_LINKS_URL", refreshHeaders)
val loginCheckResponse = chain.proceed(loginCheckRequest)
val document = loginCheckResponse.asJsoup()
loggedIn = document.select("div#o_account-links-content").first()!!
.attr("logged_in")!!.toBoolean()
loginCheckResponse.close()
}
return chain.proceed(chain.request())
}
private fun authChapterCheckIntercept(chain: Interceptor.Chain): Response {
val requestUrl = chain.request().url.toString()
if (!requestUrl.contains("/chapter/") || !requestUrl.contains("&locked=true")) {
return chain.proceed(chain.request())
}
val mangaId = requestUrl.substringAfterLast("/").substringBefore("?")
val authCheckHeaders = headersBuilder()
.add("Accept", ACCEPT_JSON)
.add("X-Client-Login", (loggedIn ?: false).toString())
.add("X-Requested-With", "XMLHttpRequest")
.build()
val authCheckUrl = "$baseUrl/$MANGA_AUTH_CHECK_URL".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("device_id", "3")
.addQueryParameter("manga_id", mangaId)
.toString()
val authCheckRequest = GET(authCheckUrl, authCheckHeaders)
val authCheckResponse = chain.proceed(authCheckRequest)
val authCheckJson = JsonParser.parseString(authCheckResponse.body!!.string()).obj
authCheckResponse.close()
if (authCheckJson["ok"].bool && authCheckJson["archive_info"]["ok"].bool) {
val newChapterUrl = chain.request().url.newBuilder()
.removeAllQueryParameters("locked")
.build()
val newChapterRequest = chain.request().newBuilder()
.url(newChapterUrl)
.build()
return chain.proceed(newChapterRequest)
}
if (
authCheckJson["archive_info"]["err"].nullObj != null &&
authCheckJson["archive_info"]["err"]["code"].int == 4 &&
loggedIn == true
) {
throw Exception(SESSION_EXPIRED)
}
throw Exception(AUTH_CHECK_FAILED)
}
private fun String.toDate(): Long {
return try {
DATE_FORMATTER.parse(this)!!.time
@ -274,15 +342,19 @@ class VizShonenJump : ParsedHttpSource() {
}
companion object {
private const val ACCEPT_JSON = "application/json, text/javascript, */*; q=0.01"
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
private val DATE_FORMATTER by lazy {
SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH)
}
private const val COUNTRY_NOT_SUPPORTED = "Your country is not supported, try using a VPN."
private const val SESSION_EXPIRED = "Your session has expired, please log in through WebView again."
private const val AUTH_CHECK_FAILED = "Something went wrong in the auth check."
private const val REFRESH_LOGIN_LINKS_URL = "https://www.viz.com/account/refresh_login_links"
private const val REFRESH_LOGIN_LINKS_URL = "account/refresh_login_links"
private const val MANGA_AUTH_CHECK_URL = "manga/auth"
}
}