TMO and LectorManga: Fix occasionally "No pages found" (again) (#64)

This commit is contained in:
bapeey 2024-01-10 01:27:51 -05:00 committed by GitHub
parent 525daaa6d9
commit 12c70ed62f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 34 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'LectorManga' extName = 'LectorManga'
pkgNameSuffix = 'es.lectormanga' pkgNameSuffix = 'es.lectormanga'
extClass = '.LectorManga' extClass = '.LectorManga'
extVersionCode = 32 extVersionCode = 33
isNsfw = true isNsfw = true
} }

View File

@ -303,7 +303,10 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
} }
if (currentUrl != newUrl) { if (currentUrl != newUrl) {
doc = client.newCall(GET(newUrl, headers)).execute().asJsoup() val redirectHeaders = super.headersBuilder()
.set("Referer", doc.location())
.build()
doc = client.newCall(GET(newUrl, redirectHeaders)).execute().asJsoup()
} }
doc.select("div.viewer-container img:not(noscript img)").forEach { doc.select("div.viewer-container img:not(noscript img)").forEach {
@ -323,50 +326,80 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
} }
} }
// Some chapters uses JavaScript to redirect to read page
private fun redirectToReadPage(document: Document): Document { private fun redirectToReadPage(document: Document): Document {
val script1 = document.selectFirst("script:containsData(uniqid)") val script1 = document.selectFirst("script:containsData(uniqid)")
val script2 = document.selectFirst("script:containsData(window.location.replace)") val script2 = document.selectFirst("script:containsData(window.location.replace)")
val script3 = document.selectFirst("script:containsData(redirectUrl)") val script3 = document.selectFirst("script:containsData(redirectUrl)")
val script4 = document.selectFirst("input#redir")
val script5 = document.selectFirst("script:containsData(window.opener):containsData(location.replace)")
val redirectHeaders = Headers.Builder() val redirectHeaders = super.headersBuilder()
.add("Referer", document.baseUri()) .set("Referer", document.location())
.build() .build()
if (script1 != null) { if (script1 != null) {
val data = script1.data() val data = script1.data()
val regexParams = """\{uniqid:'(.+)',cascade:(.+)\}""".toRegex() val regexParams = """\{uniqid:'(.+)',cascade:(.+)\}""".toRegex()
val regexAction = """form\.action\s?=\s?'(.+)'""".toRegex() val regexAction = """form\.action\s?=\s?'(.+)'""".toRegex()
val params = regexParams.find(data)!! val params = regexParams.find(data)
val action = regexAction.find(data)!!.groupValues[1] val action = regexAction.find(data)?.groupValues?.get(1)?.unescapeUrl()
val formBody = FormBody.Builder() if (params != null && action != null) {
.add("uniqid", params.groupValues[1]) val formBody = FormBody.Builder()
.add("cascade", params.groupValues[2]) .add("uniqid", params.groupValues[1])
.build() .add("cascade", params.groupValues[2])
.build()
return redirectToReadPage(client.newCall(POST(action, redirectHeaders, formBody)).execute().asJsoup()) return redirectToReadPage(client.newCall(POST(action, redirectHeaders, formBody)).execute().asJsoup())
}
} }
if (script2 != null) { if (script2 != null) {
val data = script2.data() val data = script2.data()
val regexRedirect = """window\.location\.replace\('(.+)'\)""".toRegex() val regexRedirect = """window\.location\.replace\(['"](.+)['"]\)""".toRegex()
val url = regexRedirect.find(data)!!.groupValues[1] val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl()
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup()) if (url != null) {
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
}
} }
if (script3 != null) { if (script3 != null) {
val data = script3.data() val data = script3.data()
val regexRedirect = """redirectUrl\s?=\s?'(.+)'""".toRegex() val regexRedirect = """redirectUrl\s?=\s?'(.+)'""".toRegex()
val url = regexRedirect.find(data)!!.groupValues[1] val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl()
if (url != null) {
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
}
}
if (script4 != null) {
val url = script4.attr("value").unescapeUrl()
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup()) return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
} }
if (script5 != null) {
val data = script5.data()
val regexRedirect = """;[^.]location\.replace\(['"](.+)['"]\)""".toRegex()
val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl()
if (url != null) {
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
}
}
return document return document
} }
private fun String.unescapeUrl(): String {
return if (this.startsWith("http:\\/\\/") || this.startsWith("https:\\/\\/")) {
this.replace("\\/", "/")
} else {
this
}
}
override fun imageRequest(page: Page) = GET( override fun imageRequest(page: Page) = GET(
url = page.imageUrl!!, url = page.imageUrl!!,
headers = headers.newBuilder() headers = headers.newBuilder()

View File

@ -5,7 +5,7 @@ ext {
extName = 'TuMangaOnline' extName = 'TuMangaOnline'
pkgNameSuffix = 'es.tumangaonline' pkgNameSuffix = 'es.tumangaonline'
extClass = '.TuMangaOnline' extClass = '.TuMangaOnline'
extVersionCode = 47 extVersionCode = 48
isNsfw = true isNsfw = true
} }

View File

@ -279,7 +279,10 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
} }
if (currentUrl != newUrl) { if (currentUrl != newUrl) {
doc = client.newCall(GET(newUrl, headers)).execute().asJsoup() val redirectHeaders = super.headersBuilder()
.set("Referer", doc.location())
.build()
doc = client.newCall(GET(newUrl, redirectHeaders)).execute().asJsoup()
} }
doc.select("div.viewer-container img:not(noscript img)").forEach { doc.select("div.viewer-container img:not(noscript img)").forEach {
@ -299,50 +302,80 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
} }
} }
// Some chapters uses JavaScript to redirect to read page
private fun redirectToReadPage(document: Document): Document { private fun redirectToReadPage(document: Document): Document {
val script1 = document.selectFirst("script:containsData(uniqid)") val script1 = document.selectFirst("script:containsData(uniqid)")
val script2 = document.selectFirst("script:containsData(window.location.replace)") val script2 = document.selectFirst("script:containsData(window.location.replace)")
val script3 = document.selectFirst("script:containsData(redirectUrl)") val script3 = document.selectFirst("script:containsData(redirectUrl)")
val script4 = document.selectFirst("input#redir")
val script5 = document.selectFirst("script:containsData(window.opener):containsData(location.replace)")
val redirectHeaders = Headers.Builder() val redirectHeaders = super.headersBuilder()
.add("Referer", document.baseUri()) .set("Referer", document.location())
.build() .build()
if (script1 != null) { if (script1 != null) {
val data = script1.data() val data = script1.data()
val regexParams = """\{uniqid:'(.+)',cascade:(.+)\}""".toRegex() val regexParams = """\{uniqid:'(.+)',cascade:(.+)\}""".toRegex()
val regexAction = """form\.action\s?=\s?'(.+)'""".toRegex() val regexAction = """form\.action\s?=\s?'(.+)'""".toRegex()
val params = regexParams.find(data)!! val params = regexParams.find(data)
val action = regexAction.find(data)!!.groupValues[1] val action = regexAction.find(data)?.groupValues?.get(1)?.unescapeUrl()
val formBody = FormBody.Builder() if (params != null && action != null) {
.add("uniqid", params.groupValues[1]) val formBody = FormBody.Builder()
.add("cascade", params.groupValues[2]) .add("uniqid", params.groupValues[1])
.build() .add("cascade", params.groupValues[2])
.build()
return redirectToReadPage(client.newCall(POST(action, redirectHeaders, formBody)).execute().asJsoup()) return redirectToReadPage(client.newCall(POST(action, redirectHeaders, formBody)).execute().asJsoup())
}
} }
if (script2 != null) { if (script2 != null) {
val data = script2.data() val data = script2.data()
val regexRedirect = """window\.location\.replace\('(.+)'\)""".toRegex() val regexRedirect = """window\.location\.replace\(['"](.+)['"]\)""".toRegex()
val url = regexRedirect.find(data)!!.groupValues[1] val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl()
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup()) if (url != null) {
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
}
} }
if (script3 != null) { if (script3 != null) {
val data = script3.data() val data = script3.data()
val regexRedirect = """redirectUrl\s?=\s?'(.+)'""".toRegex() val regexRedirect = """redirectUrl\s?=\s?'(.+)'""".toRegex()
val url = regexRedirect.find(data)!!.groupValues[1] val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl()
if (url != null) {
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
}
}
if (script4 != null) {
val url = script4.attr("value").unescapeUrl()
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup()) return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
} }
if (script5 != null) {
val data = script5.data()
val regexRedirect = """;[^.]location\.replace\(['"](.+)['"]\)""".toRegex()
val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl()
if (url != null) {
return redirectToReadPage(client.newCall(GET(url, redirectHeaders)).execute().asJsoup())
}
}
return document return document
} }
private fun String.unescapeUrl(): String {
return if (this.startsWith("http:\\/\\/") || this.startsWith("https:\\/\\/")) {
this.replace("\\/", "/")
} else {
this
}
}
// Note: At this moment (05/04/2023) it's necessary to make the image request with headers to prevent 403. // Note: At this moment (05/04/2023) it's necessary to make the image request with headers to prevent 403.
override fun imageRequest(page: Page): Request { override fun imageRequest(page: Page): Request {
val imageHeaders = Headers.Builder() val imageHeaders = Headers.Builder()