From 70b3cca0b1d198cf9e30f6f1666fb3d123d93d18 Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Thu, 24 Nov 2022 22:00:07 +0600 Subject: [PATCH] Webnovel.com: Don't use api for getting pages (#14366) --- src/en/webnovel/build.gradle | 2 +- .../extension/en/webnovel/Webnovel.kt | 47 ++++++++++++++----- .../extension/en/webnovel/WebnovelDto.kt | 17 ------- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/en/webnovel/build.gradle b/src/en/webnovel/build.gradle index 906a9e87e..3ba61b4ac 100644 --- a/src/en/webnovel/build.gradle +++ b/src/en/webnovel/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'Webnovel.com' pkgNameSuffix = 'en.webnovel' extClass = '.Webnovel' - extVersionCode = 5 + extVersionCode = 6 } apply from: "$rootDir/common.gradle" diff --git a/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/Webnovel.kt b/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/Webnovel.kt index bc1b78adc..04d1ac30b 100644 --- a/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/Webnovel.kt +++ b/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/Webnovel.kt @@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource +import eu.kanade.tachiyomi.util.asJsoup import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import okhttp3.HttpUrl @@ -17,6 +18,7 @@ import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import org.jsoup.nodes.Document import rx.Observable import uy.kohesive.injekt.injectLazy import java.io.IOException @@ -214,22 +216,42 @@ class Webnovel : HttpSource() { return pageListRequest(comicId, chapterId) } - private fun pageListRequest(comicId: String, chapterId: String): Request { - return GET("$baseApiUrl/comic/getContent?comicId=$comicId&chapterId=$chapterId") + private val pageRequestHeaders by lazy { + headers.newBuilder().set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0").build() } - // LinkedHashMap with a capacity of 25. When exceeding the capacity the oldest entry is removed. - private val chapterPageCache = object : LinkedHashMap<Long, List<ChapterPageDto>>() { + private fun pageListRequest(comicId: String, chapterId: String): Request { + return GET("$baseUrl/comic/$comicId/$chapterId", pageRequestHeaders) + } - override fun removeEldestEntry(eldest: MutableMap.MutableEntry<Long, List<ChapterPageDto>>?): Boolean { + data class ChapterPage( + val id: String, + val url: String + ) + + // LinkedHashMap with a capacity of 25. When exceeding the capacity the oldest entry is removed. + private val chapterPageCache = object : LinkedHashMap<String, List<ChapterPage>>() { + + override fun removeEldestEntry(eldest: MutableMap.MutableEntry<String, List<ChapterPage>>?): Boolean { return size > 25 } } override fun pageListParse(response: Response): List<Page> { - val chapterContent = response.checkAndParseAs<ChapterContentResponseDto>().chapterContent - chapterPageCache[chapterContent.chapterId] = chapterContent.chapterPage - return chapterContent.chapterPage.mapIndexed { i, page -> Page(i, imageUrl = page.url) } + val document = response.asJsoup() + val chapterId = response.request.url.pathSegments[2] + return document.parseToChapterPage(chapterId).mapIndexed { i, chapterPage -> + Page(i, imageUrl = chapterPage.url) + } + } + + private fun Document.parseToChapterPage(chapterId: String): List<ChapterPage> { + return select("#comicPageContainer img").map { + ChapterPage( + id = it.attr("data-page"), + url = it.attr("data-original") + ) + }.also { chapterPageCache[chapterId] = it } } override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not Used") @@ -290,16 +312,15 @@ class Webnovel : HttpSource() { // Page url is not valid anymore so we check if cache has updated one val pageId = pageFileName.substringBefore("!") - val cachedPageUrl = chapterPageCache[chapterId.toLong()]?.firstOrNull { it.id == pageId }?.url + val cachedPageUrl = chapterPageCache[chapterId]?.firstOrNull { it.id == pageId }?.url if (cachedPageUrl != null && isPageUrlStillValid(cachedPageUrl.toHttpUrl())) return chain.proceed(originalRequest) - // Time to get it from api + // Time to get it from site val pageListResponse = chain.proceed(pageListRequest(comicId, chapterId)) - val chapterContent = pageListResponse.checkAndParseAs<ChapterContentResponseDto>().chapterContent + val chapterPages = pageListResponse.asJsoup().parseToChapterPage(chapterId) pageListResponse.close() - chapterPageCache[chapterContent.chapterId] = chapterContent.chapterPage - val newPageUrl = chapterContent.chapterPage.firstOrNull { it.id == pageId }?.url?.toHttpUrl() + val newPageUrl = chapterPages.firstOrNull { it.id == pageId }?.url?.toHttpUrl() ?: throw IOException("Couldn't regenerate expired image url") val newRequest = originalRequest.newBuilder().url(newPageUrl).build() diff --git a/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/WebnovelDto.kt b/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/WebnovelDto.kt index 91016a241..8c8c66eac 100644 --- a/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/WebnovelDto.kt +++ b/src/en/webnovel/src/eu/kanade/tachiyomi/extension/en/webnovel/WebnovelDto.kt @@ -60,20 +60,3 @@ data class ComicChapterDto( val chapterLevel: Int, val userLevel: Int, ) - -@Serializable -data class ChapterContentResponseDto( - @SerialName("chapterInfo") val chapterContent: ChapterContentDto -) - -@Serializable -data class ChapterContentDto( - val chapterId: Long, - val chapterPage: List<ChapterPageDto> -) - -@Serializable -data class ChapterPageDto( - @SerialName("pageId") val id: String, - val url: String -)