Mangahere - revert & tweak pages (#2582)
Mangahere - revert & tweak pages
This commit is contained in:
parent
f57916c741
commit
a6633e2545
|
@ -5,7 +5,7 @@ ext {
|
||||||
appName = 'Tachiyomi: Mangahere'
|
appName = 'Tachiyomi: Mangahere'
|
||||||
pkgNameSuffix = 'en.mangahere'
|
pkgNameSuffix = 'en.mangahere'
|
||||||
extClass = '.Mangahere'
|
extClass = '.Mangahere'
|
||||||
extVersionCode = 12
|
extVersionCode = 13
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
import java.lang.NumberFormatException
|
||||||
|
import java.lang.UnsupportedOperationException
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -25,7 +27,7 @@ class Mangahere : ParsedHttpSource() {
|
||||||
|
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
override val client = super.client.newBuilder()
|
override val client: OkHttpClient = super.client.newBuilder()
|
||||||
.cookieJar(object : CookieJar{
|
.cookieJar(object : CookieJar{
|
||||||
override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {}
|
override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {}
|
||||||
override fun loadForRequest(url: HttpUrl): MutableList<Cookie> {
|
override fun loadForRequest(url: HttpUrl): MutableList<Cookie> {
|
||||||
|
@ -96,7 +98,7 @@ class Mangahere : ParsedHttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
url.addEncodedQueryParameter("genres", includeGenres.joinToString(","))
|
url.addEncodedQueryParameter("genres", includeGenres.joinToString(","))
|
||||||
.addEncodedQueryParameter("nogenres", excludeGenres.joinToString(","))
|
.addEncodedQueryParameter("nogenres", excludeGenres.joinToString(","))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -191,19 +193,116 @@ class Mangahere : ParsedHttpSource() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
return GET("$baseUrl/${chapter.url}".replace("www","m"), headers)
|
val bar = document.select("script[src*=chapter_bar]")
|
||||||
|
val duktape = Duktape.create()
|
||||||
|
|
||||||
|
// if-branch is for webtoon reader, else is for page-by-page
|
||||||
|
return if (bar.isNotEmpty()) {
|
||||||
|
val script = document.select("script:containsData(function(p,a,c,k,e,d))").html().removePrefix("eval")
|
||||||
|
val deobfuscatedScript = duktape.evaluate(script).toString()
|
||||||
|
val urls = deobfuscatedScript.substringAfter("newImgs=['").substringBefore("'];").split("','")
|
||||||
|
duktape.close()
|
||||||
|
|
||||||
|
/*
|
||||||
|
last webtoon imageUrl is usually broken, working imageUrls are incremental (e.g. t001, t002, etc); if the difference between
|
||||||
|
the last two isn't 1 or doesn't have an Int at the end of the last imageUrl's filename, drop last Page
|
||||||
|
*/
|
||||||
|
urls.mapIndexed { index, s -> Page(index, "", "https:$s") }.let { pages ->
|
||||||
|
val list = pages.takeLast(2).map { page ->
|
||||||
|
try {
|
||||||
|
page.imageUrl!!.substringBeforeLast(".").substringAfterLast("/").takeLast(2).toInt()
|
||||||
|
} catch (_: NumberFormatException) {
|
||||||
|
return pages.dropLast(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when {
|
||||||
|
list[0] == 0 && 100 - list[1] == 1 -> pages
|
||||||
|
list[1] - list[0] == 1 -> pages
|
||||||
|
else -> pages.dropLast(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val html = document.html()
|
||||||
|
val link = document.location()
|
||||||
|
|
||||||
|
var secretKey = extractSecretKey(html, duktape)
|
||||||
|
|
||||||
|
val chapterIdStartLoc = html.indexOf("chapterid")
|
||||||
|
val chapterId = html.substring(
|
||||||
|
chapterIdStartLoc + 11,
|
||||||
|
html.indexOf(";", chapterIdStartLoc)).trim()
|
||||||
|
|
||||||
|
val chapterPagesElement = document.select(".pager-list-left > span").first()
|
||||||
|
val pagesLinksElements = chapterPagesElement.select("a")
|
||||||
|
val pagesNumber = pagesLinksElements[pagesLinksElements.size - 2].attr("data-page").toInt()
|
||||||
|
|
||||||
|
val pageBase = link.substring(0, link.lastIndexOf("/"))
|
||||||
|
|
||||||
|
IntRange(1, pagesNumber).map { i ->
|
||||||
|
|
||||||
|
val pageLink = "${pageBase}/chapterfun.ashx?cid=$chapterId&page=$i&key=$secretKey"
|
||||||
|
|
||||||
|
var responseText = ""
|
||||||
|
|
||||||
|
for (tr in 1..3){
|
||||||
|
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(pageLink)
|
||||||
|
.addHeader("Referer",link)
|
||||||
|
.addHeader("Accept","*/*")
|
||||||
|
.addHeader("Accept-Language","en-US,en;q=0.9")
|
||||||
|
.addHeader("Connection","keep-alive")
|
||||||
|
.addHeader("Host","www.mangahere.cc")
|
||||||
|
.addHeader("User-Agent", System.getProperty("http.agent") ?: "")
|
||||||
|
.addHeader("X-Requested-With","XMLHttpRequest")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
responseText = response.body()!!.string()
|
||||||
|
|
||||||
|
if (responseText.isNotEmpty())
|
||||||
|
break
|
||||||
|
else
|
||||||
|
secretKey = ""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val deobfuscatedScript = duktape.evaluate(responseText.removePrefix("eval")).toString()
|
||||||
|
|
||||||
|
val baseLinkStartPos = deobfuscatedScript.indexOf("pix=") + 5
|
||||||
|
val baseLinkEndPos = deobfuscatedScript.indexOf(";", baseLinkStartPos) - 1
|
||||||
|
val baseLink = deobfuscatedScript.substring(baseLinkStartPos, baseLinkEndPos)
|
||||||
|
|
||||||
|
val imageLinkStartPos = deobfuscatedScript.indexOf("pvalue=") + 9
|
||||||
|
val imageLinkEndPos = deobfuscatedScript.indexOf("\"", imageLinkStartPos)
|
||||||
|
val imageLink = deobfuscatedScript.substring(imageLinkStartPos, imageLinkEndPos)
|
||||||
|
|
||||||
|
Page(i - 1, "", "https:$baseLink$imageLink")
|
||||||
|
|
||||||
|
}
|
||||||
|
}.also { duktape.close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
|
private fun extractSecretKey(html: String, duktape: Duktape): String {
|
||||||
document.select("select option").forEach {
|
|
||||||
add(Page(size,"https:${it.attr("value")}"))
|
val secretKeyScriptLocation = html.indexOf("eval(function(p,a,c,k,e,d)")
|
||||||
}
|
val secretKeyScriptEndLocation = html.indexOf("</script>", secretKeyScriptLocation)
|
||||||
|
val secretKeyScript = html.substring(secretKeyScriptLocation, secretKeyScriptEndLocation).removePrefix("eval")
|
||||||
|
|
||||||
|
val secretKeyDeobfuscatedScript = duktape.evaluate(secretKeyScript).toString()
|
||||||
|
|
||||||
|
val secretKeyStartLoc = secretKeyDeobfuscatedScript.indexOf("'")
|
||||||
|
val secretKeyEndLoc = secretKeyDeobfuscatedScript.indexOf(";")
|
||||||
|
|
||||||
|
val secretKeyResultScript = secretKeyDeobfuscatedScript.substring(
|
||||||
|
secretKeyStartLoc, secretKeyEndLoc)
|
||||||
|
|
||||||
|
return duktape.evaluate(secretKeyResultScript).toString()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun imageUrlParse(document: Document): String {
|
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
|
||||||
return document.select("img#image").attr("src")
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Genre(title: String, val id: Int) : Filter.TriState(title)
|
private class Genre(title: String, val id: Int) : Filter.TriState(title)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue