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:
h-hyuuga 2022-10-20 07:54:23 -04:00 committed by GitHub
parent 30ca25735b
commit 3bf40039e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 37 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'Reaper Scans'
pkgNameSuffix = 'en.reaperscans'
extClass = '.ReaperScans'
extVersionCode = 38
extVersionCode = 39
}
apply from: "$rootDir/common.gradle"

View File

@ -33,6 +33,7 @@ import org.jsoup.nodes.Element
import uy.kohesive.injekt.injectLazy
import java.util.Calendar
import java.util.concurrent.TimeUnit
import kotlin.random.Random
class ReaperScans : ParsedHttpSource() {
@ -103,6 +104,8 @@ class ReaperScans : ParsedHttpSource() {
val routeName = livewareData.fingerprint["name"]?.jsonPrimitive?.contentOrNull
?: 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 {
put("fingerprint", livewareData.fingerprint)
put("serverMemo", livewareData.serverMemo)
@ -110,7 +113,7 @@ class ReaperScans : ParsedHttpSource() {
addJsonObject {
put("type", "syncInput")
putJsonObject("payload") {
put("id", "03r6")
put("id", generateId())
put("name", "query")
put("value", query)
}
@ -176,20 +179,24 @@ class ReaperScans : ParsedHttpSource() {
// Chapters
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> {
var document = response.asJsoup()
val document = response.asJsoup()
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")
?: error("Couldn't find csrf-token")
val livewareData = document.selectFirst("div[wire:initial-data*=Models\\\\Comic]")
?.attr("wire:initial-data")
?.parseJson<LiveWireDataDto>()
if (csrfToken == null) error("Couldn't find csrf-token")
if (livewareData == null) error("Couldn't find LiveWireData")
?: error("Couldn't find LiveWireData")
val routeName = livewareData.fingerprint["name"]?.jsonPrimitive?.contentOrNull
?: error("Couldn't find routeName")
@ -197,45 +204,43 @@ class ReaperScans : ParsedHttpSource() {
val fingerprint = livewareData.fingerprint
var serverMemo = livewareData.serverMemo
var pageToQuery = 1
var hasNextPage = true
var pageToQuery = 2
// 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) {
if (pageToQuery != 1) {
val payload = buildJsonObject {
put("fingerprint", fingerprint)
put("serverMemo", serverMemo)
putJsonArray("updates") {
addJsonObject {
put("type", "callMethod")
putJsonObject("payload") {
put("id", "9jhcg")
put("method", "gotoPage")
putJsonArray("params") {
add(pageToQuery)
add("page")
}
val payload = buildJsonObject {
put("fingerprint", fingerprint)
put("serverMemo", serverMemo)
putJsonArray("updates") {
addJsonObject {
put("type", "callMethod")
putJsonObject("payload") {
put("id", generateId())
put("method", "gotoPage")
putJsonArray("params") {
add(pageToQuery)
add("page")
}
}
}
}.toString().toRequestBody(JSON_MEDIA_TYPE)
}
}.toString().toRequestBody(JSON_MEDIA_TYPE)
val headers = Headers.Builder()
.add("x-csrf-token", csrfToken)
.add("x-livewire", "true")
.build()
val headers = Headers.Builder()
.add("x-csrf-token", csrfToken)
.add("x-livewire", "true")
.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
serverMemo = serverMemo.mergeLeft(responseData.serverMemo)
document = Jsoup.parse(responseData.effects.html, baseUrl)
}
document.select(chapterListSelector()).forEach { chapters.add(chapterFromElement(it)) }
hasNextPage = document.selectFirst(chapterListNextPageSelector()) != null
// response contains state that we need to preserve
serverMemo = serverMemo.mergeLeft(responseData.serverMemo)
val chaptersHtml = Jsoup.parse(responseData.effects.html, baseUrl)
chaptersHtml.select(chapterListSelector()).forEach { chapters.add(chapterFromElement(it)) }
hasNextPage = chaptersHtml.selectFirst(chapterListNextPageSelector()) != null
pageToQuery++
}