diff --git a/src/en/reaperscans/build.gradle b/src/en/reaperscans/build.gradle index 752009cb5..cb656be6b 100644 --- a/src/en/reaperscans/build.gradle +++ b/src/en/reaperscans/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'Reaper Scans' pkgNameSuffix = 'en.reaperscans' extClass = '.ReaperScans' - extVersionCode = 38 + extVersionCode = 39 } apply from: "$rootDir/common.gradle" diff --git a/src/en/reaperscans/src/eu/kanade/tachiyomi/extension/en/reaperscans/ReaperScans.kt b/src/en/reaperscans/src/eu/kanade/tachiyomi/extension/en/reaperscans/ReaperScans.kt index a3a637e11..0379cbe5c 100644 --- a/src/en/reaperscans/src/eu/kanade/tachiyomi/extension/en/reaperscans/ReaperScans.kt +++ b/src/en/reaperscans/src/eu/kanade/tachiyomi/extension/en/reaperscans/ReaperScans.kt @@ -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 { - var document = response.asJsoup() + val document = response.asJsoup() val chapters = mutableListOf() + 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() - - 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() + val responseData = client.newCall(request).execute().parseJson() - // 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++ }