Fix broken source (#13932)
* Auto generate id for chapter list requests * fix search * Bump Version * Refactor chapterListParse to immediately return if there's only 1 page Avoids an error that occurs if a series has no chapters
This commit is contained in:
parent
30ca25735b
commit
3bf40039e4
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'Reaper Scans'
|
extName = 'Reaper Scans'
|
||||||
pkgNameSuffix = 'en.reaperscans'
|
pkgNameSuffix = 'en.reaperscans'
|
||||||
extClass = '.ReaperScans'
|
extClass = '.ReaperScans'
|
||||||
extVersionCode = 38
|
extVersionCode = 39
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.jsoup.nodes.Element
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
class ReaperScans : ParsedHttpSource() {
|
class ReaperScans : ParsedHttpSource() {
|
||||||
|
|
||||||
|
@ -103,6 +104,8 @@ class ReaperScans : ParsedHttpSource() {
|
||||||
val routeName = livewareData.fingerprint["name"]?.jsonPrimitive?.contentOrNull
|
val routeName = livewareData.fingerprint["name"]?.jsonPrimitive?.contentOrNull
|
||||||
?: error("Couldn't find routeName")
|
?: error("Couldn't find routeName")
|
||||||
|
|
||||||
|
// Javascript: (Math.random() + 1).toString(36).substring(8)
|
||||||
|
val generateId = { -> "1.${Random.nextLong().toString(36)}".substring(10) } // Not exactly the same, but results in a 3-5 character string
|
||||||
val payload = buildJsonObject {
|
val payload = buildJsonObject {
|
||||||
put("fingerprint", livewareData.fingerprint)
|
put("fingerprint", livewareData.fingerprint)
|
||||||
put("serverMemo", livewareData.serverMemo)
|
put("serverMemo", livewareData.serverMemo)
|
||||||
|
@ -110,7 +113,7 @@ class ReaperScans : ParsedHttpSource() {
|
||||||
addJsonObject {
|
addJsonObject {
|
||||||
put("type", "syncInput")
|
put("type", "syncInput")
|
||||||
putJsonObject("payload") {
|
putJsonObject("payload") {
|
||||||
put("id", "03r6")
|
put("id", generateId())
|
||||||
put("name", "query")
|
put("name", "query")
|
||||||
put("value", query)
|
put("value", query)
|
||||||
}
|
}
|
||||||
|
@ -176,20 +179,24 @@ class ReaperScans : ParsedHttpSource() {
|
||||||
// Chapters
|
// Chapters
|
||||||
private fun chapterListNextPageSelector(): String = "button[wire:click*=nextPage]"
|
private fun chapterListNextPageSelector(): String = "button[wire:click*=nextPage]"
|
||||||
|
|
||||||
override fun chapterListSelector() = "div[wire:id] > ul[role=list] > li"
|
override fun chapterListSelector() = "div[wire:id] > div > ul[role=list] > li"
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
var document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val chapters = mutableListOf<SChapter>()
|
val chapters = mutableListOf<SChapter>()
|
||||||
|
document.select(chapterListSelector()).forEach { chapters.add(chapterFromElement(it)) }
|
||||||
|
var hasNextPage = document.selectFirst(chapterListNextPageSelector()) != null
|
||||||
|
|
||||||
|
if (!hasNextPage)
|
||||||
|
return chapters
|
||||||
|
|
||||||
val csrfToken = document.selectFirst("meta[name=csrf-token]")?.attr("content")
|
val csrfToken = document.selectFirst("meta[name=csrf-token]")?.attr("content")
|
||||||
|
?: error("Couldn't find csrf-token")
|
||||||
|
|
||||||
val livewareData = document.selectFirst("div[wire:initial-data*=Models\\\\Comic]")
|
val livewareData = document.selectFirst("div[wire:initial-data*=Models\\\\Comic]")
|
||||||
?.attr("wire:initial-data")
|
?.attr("wire:initial-data")
|
||||||
?.parseJson<LiveWireDataDto>()
|
?.parseJson<LiveWireDataDto>()
|
||||||
|
?: error("Couldn't find LiveWireData")
|
||||||
if (csrfToken == null) error("Couldn't find csrf-token")
|
|
||||||
if (livewareData == null) error("Couldn't find LiveWireData")
|
|
||||||
|
|
||||||
val routeName = livewareData.fingerprint["name"]?.jsonPrimitive?.contentOrNull
|
val routeName = livewareData.fingerprint["name"]?.jsonPrimitive?.contentOrNull
|
||||||
?: error("Couldn't find routeName")
|
?: error("Couldn't find routeName")
|
||||||
|
@ -197,45 +204,43 @@ class ReaperScans : ParsedHttpSource() {
|
||||||
val fingerprint = livewareData.fingerprint
|
val fingerprint = livewareData.fingerprint
|
||||||
var serverMemo = livewareData.serverMemo
|
var serverMemo = livewareData.serverMemo
|
||||||
|
|
||||||
var pageToQuery = 1
|
var pageToQuery = 2
|
||||||
var hasNextPage = true
|
|
||||||
|
|
||||||
|
// Javascript: (Math.random() + 1).toString(36).substring(8)
|
||||||
|
val generateId = { "1.${Random.nextLong().toString(36)}".substring(10) } // Not exactly the same, but results in a 3-5 character string
|
||||||
while (hasNextPage) {
|
while (hasNextPage) {
|
||||||
if (pageToQuery != 1) {
|
val payload = buildJsonObject {
|
||||||
val payload = buildJsonObject {
|
put("fingerprint", fingerprint)
|
||||||
put("fingerprint", fingerprint)
|
put("serverMemo", serverMemo)
|
||||||
put("serverMemo", serverMemo)
|
putJsonArray("updates") {
|
||||||
putJsonArray("updates") {
|
addJsonObject {
|
||||||
addJsonObject {
|
put("type", "callMethod")
|
||||||
put("type", "callMethod")
|
putJsonObject("payload") {
|
||||||
putJsonObject("payload") {
|
put("id", generateId())
|
||||||
put("id", "9jhcg")
|
put("method", "gotoPage")
|
||||||
put("method", "gotoPage")
|
putJsonArray("params") {
|
||||||
putJsonArray("params") {
|
add(pageToQuery)
|
||||||
add(pageToQuery)
|
add("page")
|
||||||
add("page")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.toString().toRequestBody(JSON_MEDIA_TYPE)
|
}
|
||||||
|
}.toString().toRequestBody(JSON_MEDIA_TYPE)
|
||||||
|
|
||||||
val headers = Headers.Builder()
|
val headers = Headers.Builder()
|
||||||
.add("x-csrf-token", csrfToken)
|
.add("x-csrf-token", csrfToken)
|
||||||
.add("x-livewire", "true")
|
.add("x-livewire", "true")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val request = POST("$baseUrl/livewire/message/$routeName", headers, payload)
|
val request = POST("$baseUrl/livewire/message/$routeName", headers, payload)
|
||||||
|
|
||||||
val responseData = client.newCall(request).execute().parseJson<LiveWireResponseDto>()
|
val responseData = client.newCall(request).execute().parseJson<LiveWireResponseDto>()
|
||||||
|
|
||||||
// response contains state that we need to preserve
|
// response contains state that we need to preserve
|
||||||
serverMemo = serverMemo.mergeLeft(responseData.serverMemo)
|
serverMemo = serverMemo.mergeLeft(responseData.serverMemo)
|
||||||
document = Jsoup.parse(responseData.effects.html, baseUrl)
|
val chaptersHtml = Jsoup.parse(responseData.effects.html, baseUrl)
|
||||||
}
|
chaptersHtml.select(chapterListSelector()).forEach { chapters.add(chapterFromElement(it)) }
|
||||||
|
hasNextPage = chaptersHtml.selectFirst(chapterListNextPageSelector()) != null
|
||||||
document.select(chapterListSelector()).forEach { chapters.add(chapterFromElement(it)) }
|
|
||||||
hasNextPage = document.selectFirst(chapterListNextPageSelector()) != null
|
|
||||||
pageToQuery++
|
pageToQuery++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue