From 49efe333db148c598f53e130256979fd6198153b Mon Sep 17 00:00:00 2001 From: Chopper <156493704+choppeh@users.noreply.github.com> Date: Mon, 13 Jan 2025 10:01:58 -0300 Subject: [PATCH] SlimeReadTheme: Fix pagination and add scan id (#7152) Fix pagination and add scan id --- lib-multisrc/slimereadtheme/build.gradle.kts | 2 +- .../multisrc/slimereadtheme/SlimeReadTheme.kt | 73 ++++++++++++------- .../extension/pt/mahouscan/MahouScan.kt | 1 + 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/lib-multisrc/slimereadtheme/build.gradle.kts b/lib-multisrc/slimereadtheme/build.gradle.kts index 9dce2478c..e2f11e9c1 100644 --- a/lib-multisrc/slimereadtheme/build.gradle.kts +++ b/lib-multisrc/slimereadtheme/build.gradle.kts @@ -2,4 +2,4 @@ plugins { id("lib-multisrc") } -baseVersionCode = 2 +baseVersionCode = 3 diff --git a/lib-multisrc/slimereadtheme/src/eu/kanade/tachiyomi/multisrc/slimereadtheme/SlimeReadTheme.kt b/lib-multisrc/slimereadtheme/src/eu/kanade/tachiyomi/multisrc/slimereadtheme/SlimeReadTheme.kt index 04fc62377..ef3160788 100644 --- a/lib-multisrc/slimereadtheme/src/eu/kanade/tachiyomi/multisrc/slimereadtheme/SlimeReadTheme.kt +++ b/lib-multisrc/slimereadtheme/src/eu/kanade/tachiyomi/multisrc/slimereadtheme/SlimeReadTheme.kt @@ -33,6 +33,7 @@ abstract class SlimeReadTheme( override val name: String, override val baseUrl: String, override val lang: String, + private val scanId: String = "", ) : HttpSource() { protected open val apiUrl: String by lazy { getApiUrlFromPage() } @@ -72,35 +73,19 @@ abstract class SlimeReadTheme( } // ============================== Popular =============================== - private var currentSlice = 0 private var popularMangeCache: MangasPage? = null - override fun popularMangaRequest(page: Int) = - GET("$apiUrl/book_search?order=1&status=0", headers) + override fun popularMangaRequest(page: Int): Request { + val url = "$apiUrl/book_search?order=1&status=0".toHttpUrl().newBuilder() + .addIfNotBlank("scan_id", scanId) + .build() + return GET(url, headers) + } - // Returns a large JSON, so the app can't handle the list without pagination override fun fetchPopularManga(page: Int): Observable { - if (page == 1 || popularMangeCache == null) { - popularMangeCache = super.fetchPopularManga(page) - .toBlocking() - .last() - } - - // Handling a large manga list - return Observable.just(popularMangeCache!!) - .map { mangaPage -> - val mangas = mangaPage.mangas - val pageSize = 15 - - currentSlice = (page - 1) * pageSize - - val startIndex = min(mangas.size - 1, currentSlice) - val endIndex = min(mangas.size, currentSlice + pageSize) - - val slice = mangas.subList(startIndex, endIndex) - - MangasPage(slice, slice.isNotEmpty()) - } + popularMangeCache = popularMangeCache?.takeIf { page != 1 } + ?: super.fetchPopularManga(page).toBlocking().last() + return pageableOf(page, popularMangeCache!!) } override fun popularMangaParse(response: Response): MangasPage { @@ -110,7 +95,13 @@ abstract class SlimeReadTheme( } // =============================== Latest =============================== - override fun latestUpdatesRequest(page: Int) = GET("$apiUrl/books?page=$page", headers) + + override fun latestUpdatesRequest(page: Int): Request { + val url = "$apiUrl/books?page=$page".toHttpUrl().newBuilder() + .addIfNotBlank("scan_id", scanId) + .build() + return GET(url, headers) + } override fun latestUpdatesParse(response: Response): MangasPage { val dto = response.parseAs() @@ -120,6 +111,9 @@ abstract class SlimeReadTheme( } // =============================== Search =============================== + + private var searchMangaCache: MangasPage? = null + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler val id = query.removePrefix(PREFIX_SEARCH) @@ -127,7 +121,9 @@ abstract class SlimeReadTheme( .asObservableSuccess() .map(::searchMangaByIdParse) } else { - super.fetchSearchManga(page, query, filters) + searchMangaCache = searchMangaCache?.takeIf { page != 1 } + ?: super.fetchSearchManga(page, query, filters).toBlocking().last() + pageableOf(page, searchMangaCache!!) } } @@ -146,6 +142,7 @@ abstract class SlimeReadTheme( .addIfNotBlank("genre[]", params.genre) .addIfNotBlank("status", params.status) .addIfNotBlank("searchMethod", params.searchMethod) + .addIfNotBlank("scan_id", scanId) .apply { params.categories.forEach { addQueryParameter("categories[]", it) @@ -237,6 +234,28 @@ abstract class SlimeReadTheme( } // ============================= Utilities ============================== + + /** + * Handles a large manga list and returns a paginated response. + * The app can't handle the large JSON list without pagination. + * + * @param page The page number to retrieve. + * @param cache The cached manga page containing the full list of mangas. + */ + private fun pageableOf(page: Int, cache: MangasPage) = Observable.just(cache).map { mangaPage -> + val mangas = mangaPage.mangas + val pageSize = 15 + + val currentSlice = (page - 1) * pageSize + + val startIndex = min(mangas.size, currentSlice) + val endIndex = min(mangas.size, currentSlice + pageSize) + + val slice = mangas.subList(startIndex, endIndex) + + MangasPage(slice, hasNextPage = endIndex < mangas.size) + } + private inline fun Response.parseAs(): T = use { json.decodeFromStream(it.body.byteStream()) } diff --git a/src/pt/mahouscan/src/eu/kanade/tachiyomi/extension/pt/mahouscan/MahouScan.kt b/src/pt/mahouscan/src/eu/kanade/tachiyomi/extension/pt/mahouscan/MahouScan.kt index f00829d19..4e3d8b88f 100644 --- a/src/pt/mahouscan/src/eu/kanade/tachiyomi/extension/pt/mahouscan/MahouScan.kt +++ b/src/pt/mahouscan/src/eu/kanade/tachiyomi/extension/pt/mahouscan/MahouScan.kt @@ -7,6 +7,7 @@ class MahouScan : SlimeReadTheme( "MahouScan", "https://mahouscan.com", "pt-BR", + scanId = "1292193100", ) { override val client = super.client.newBuilder() .rateLimit(2)