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' 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"

View File

@ -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++
} }