Try to avoid 404 in NS when they change the manga path. (#11493)

This commit is contained in:
Alessandro Jean 2022-04-16 17:38:42 -03:00 committed by GitHub
parent 5f515275ea
commit 9899f2c9d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 1 deletions

View File

@ -9,18 +9,24 @@ import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservable import eu.kanade.tachiyomi.network.asObservable
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response
import rx.Observable import rx.Observable
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.UUID
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.Exception import kotlin.Exception
@ -36,6 +42,7 @@ class NeoxScanlator :
override val client: OkHttpClient = network.cloudflareClient.newBuilder() override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(1, TimeUnit.MINUTES) .connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES) .readTimeout(1, TimeUnit.MINUTES)
.addInterceptor(::titleCollectionIntercept)
.addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS)) .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
.build() .build()
@ -49,11 +56,43 @@ class NeoxScanlator :
preferences.getString(BASE_URL_PREF_KEY, DEFAULT_BASE_URL)!! preferences.getString(BASE_URL_PREF_KEY, DEFAULT_BASE_URL)!!
} }
private var titleCollectionPath: String? = null
override fun headersBuilder(): Headers.Builder = super.headersBuilder() override fun headersBuilder(): Headers.Builder = super.headersBuilder()
.add("Accept", ACCEPT) .add("Accept", ACCEPT)
.add("Accept-Language", ACCEPT_LANGUAGE) .add("Accept-Language", ACCEPT_LANGUAGE)
.add("Referer", REFERER) .add("Referer", REFERER)
override fun popularMangaParse(response: Response): MangasPage {
val popularPage = super.popularMangaParse(response)
titleCollectionPath = popularPage.mangas.firstOrNull()?.url
?.removePrefix("/")
?.substringBefore("/")
return popularPage
}
override fun latestUpdatesParse(response: Response): MangasPage {
val latestPage = super.latestUpdatesParse(response)
titleCollectionPath = latestPage.mangas.firstOrNull()?.url
?.removePrefix("/")
?.substringBefore("/")
return latestPage
}
override fun searchMangaParse(response: Response): MangasPage {
val searchPage = super.searchMangaParse(response)
titleCollectionPath = searchPage.mangas.firstOrNull()?.url
?.removePrefix("/")
?.substringBefore("/")
return searchPage
}
// Sometimes the site changes the manga URL. This override will // Sometimes the site changes the manga URL. This override will
// add an error instead of the HTTP 404 to inform the user to // add an error instead of the HTTP 404 to inform the user to
// migrate from Neox to Neox to update the URL. // migrate from Neox to Neox to update the URL.
@ -71,6 +110,25 @@ class NeoxScanlator :
} }
} }
override fun mangaDetailsRequest(manga: SManga): Request {
val mangaSlug = manga.url.removePrefix("/").substringAfter("/")
val mangaUrl = "/" + (titleCollectionPath ?: TITLE_PATH_PLACEHOLDER) + "/" + mangaSlug
return GET(baseUrl + mangaUrl, headers)
}
override fun xhrChaptersRequest(mangaUrl: String): Request {
val xhrHeaders = headersBuilder()
.add("Referer", baseUrl)
.add("X-Requested-With", "XMLHttpRequest")
.build()
val mangaSlug = mangaUrl.toHttpUrl().pathSegments[1]
val fixedUrl = (titleCollectionPath ?: TITLE_PATH_PLACEHOLDER) + "/" + mangaSlug
return POST("$baseUrl/$fixedUrl/ajax/chapters", xhrHeaders)
}
override fun imageRequest(page: Page): Request { override fun imageRequest(page: Page): Request {
val newHeaders = headersBuilder() val newHeaders = headersBuilder()
.set("Accept", ACCEPT_IMAGE) .set("Accept", ACCEPT_IMAGE)
@ -106,6 +164,34 @@ class NeoxScanlator :
screen.addPreference(baseUrlPref) screen.addPreference(baseUrlPref)
} }
private fun titleCollectionIntercept(chain: Interceptor.Chain): Response {
val request = chain.request()
if (!request.url.toString().contains(TITLE_PATH_PLACEHOLDER)) {
return chain.proceed(request)
}
val titlePathResult = runCatching {
val popularResponse = chain.proceed(popularMangaRequest(1))
val popularPage = popularMangaParse(popularResponse)
popularPage.mangas.firstOrNull()?.url
?.removePrefix("/")
?.substringBefore("/")
}
titleCollectionPath = titlePathResult.getOrNull()
val fixedUrl = request.url.toString()
.replace(TITLE_PATH_PLACEHOLDER, titleCollectionPath ?: "comicz")
val fixedRequest = request.newBuilder()
.url(fixedUrl)
.build()
return chain.proceed(fixedRequest)
}
companion object { companion object {
private const val MIGRATION_MESSAGE = "O URL deste mangá mudou. " + private const val MIGRATION_MESSAGE = "O URL deste mangá mudou. " +
"Faça a migração do Neox para o Neox para atualizar a URL." "Faça a migração do Neox para o Neox para atualizar a URL."
@ -123,5 +209,7 @@ class NeoxScanlator :
"extensão, esta configuração será apagada." "extensão, esta configuração será apagada."
private const val RESTART_TACHIYOMI = "Reinicie o Tachiyomi para aplicar as configurações." private const val RESTART_TACHIYOMI = "Reinicie o Tachiyomi para aplicar as configurações."
private val TITLE_PATH_PLACEHOLDER = UUID.randomUUID().toString()
} }
} }

View File

@ -338,7 +338,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("NeatManga", "https://neatmanga.com", "en", overrideVersionCode = 2), SingleLang("NeatManga", "https://neatmanga.com", "en", overrideVersionCode = 2),
SingleLang("NekoBreaker Scan", "https://nekobreakerscan.com", "pt-BR", overrideVersionCode = 1), SingleLang("NekoBreaker Scan", "https://nekobreakerscan.com", "pt-BR", overrideVersionCode = 1),
SingleLang("NekoScan", "https://nekoscan.com", "en", overrideVersionCode = 2), SingleLang("NekoScan", "https://nekoscan.com", "en", overrideVersionCode = 2),
SingleLang("Neox Scanlator", "https://neoxscans.net", "pt-BR", overrideVersionCode = 8), SingleLang("Neox Scanlator", "https://neoxscans.net", "pt-BR", overrideVersionCode = 9),
SingleLang("Night Comic", "https://www.nightcomic.com", "en", overrideVersionCode = 1), SingleLang("Night Comic", "https://www.nightcomic.com", "en", overrideVersionCode = 1),
SingleLang("Niji Translations", "https://niji-translations.com", "ar", overrideVersionCode = 1), SingleLang("Niji Translations", "https://niji-translations.com", "ar", overrideVersionCode = 1),
SingleLang("Ninja Scan", "https://ninjascan.xyz", "pt-BR", overrideVersionCode = 1), SingleLang("Ninja Scan", "https://ninjascan.xyz", "pt-BR", overrideVersionCode = 1),