From 25ff2ae5f08bae9ae671b4ac44214bffcca8817e Mon Sep 17 00:00:00 2001 From: Vetle Ledaal Date: Tue, 19 Sep 2023 22:41:45 +0000 Subject: [PATCH] Manga Demon: dynamic URL suffix, fix encoding (#18036) There might be some issues with duplicate manga, since the suffix is not stripped. --- src/en/mangademon/build.gradle | 3 +- .../extension/en/mangademon/MangaDemon.kt | 61 ++++++++++++++++++- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/en/mangademon/build.gradle b/src/en/mangademon/build.gradle index 3150415d0..f57fedf23 100644 --- a/src/en/mangademon/build.gradle +++ b/src/en/mangademon/build.gradle @@ -5,7 +5,8 @@ ext { extName = 'Manga Demon' pkgNameSuffix = 'en.mangademon' extClass = '.MangaDemon' - extVersionCode = 4 + extVersionCode = 5 + isNsfw = false } apply from: "$rootDir/common.gradle" diff --git a/src/en/mangademon/src/eu/kanade/tachiyomi/extension/en/mangademon/MangaDemon.kt b/src/en/mangademon/src/eu/kanade/tachiyomi/extension/en/mangademon/MangaDemon.kt index 7e353c6be..7c1b9777f 100644 --- a/src/en/mangademon/src/eu/kanade/tachiyomi/extension/en/mangademon/MangaDemon.kt +++ b/src/en/mangademon/src/eu/kanade/tachiyomi/extension/en/mangademon/MangaDemon.kt @@ -11,11 +11,14 @@ import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.util.asJsoup import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response +import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable +import java.net.URLEncoder import java.text.SimpleDateFormat import java.util.Locale @@ -28,8 +31,57 @@ class MangaDemon : ParsedHttpSource() { override val client = network.cloudflareClient.newBuilder() .rateLimit(1) + .addInterceptor(::dynamicUrlInterceptor) .build() + private var dynamicUrlSuffix: String? = null + + private fun dynamicUrlInterceptor(chain: Interceptor.Chain): Response { + val request = chain.request() + + // Check if request requires an up-to-date suffix + if (request.url.pathSegments[0] == "manga" && dynamicUrlSuffix != null) { + val newPath = request.url + .encodedPath + .replaceAfterLast("-", dynamicUrlSuffix!!) + + val newUrl = request.url.newBuilder() + .encodedPath(newPath) + .build() + + val newRequest = request.newBuilder() + .url(newUrl) + .build() + + return chain.proceed(newRequest) + } + + val response = chain.proceed(request) + if (dynamicUrlSuffix != null) { + return response + } + + // Don't have suffix, get it from the page + val document = Jsoup.parse( + response.peekBody(Long.MAX_VALUE).string(), + request.url.toString(), + ) + + val links = document.select("a[href^='/manga/']") + + // Get the most popular suffix after last `-` + val suffix = links.map { it.attr("href").substringAfterLast("-") } + .groupBy { it } + .maxByOrNull { it.value.size } + ?.key + + if (suffix != null) { + dynamicUrlSuffix = suffix + } + + return response + } + override fun headersBuilder() = super.headersBuilder() .add("Referer", baseUrl) @@ -45,7 +97,8 @@ class MangaDemon : ParsedHttpSource() { override fun latestUpdatesFromElement(element: Element) = SManga.create().apply { element.select("a").apply { title = attr("title") - setUrlWithoutDomain(attr("href")) + val url = URLEncoder.encode(attr("href"), "UTF-8") + setUrlWithoutDomain(url) } thumbnail_url = element.select("img").attr("abs:src") } @@ -111,7 +164,8 @@ class MangaDemon : ParsedHttpSource() { override fun searchMangaFromElement(element: Element) = SManga.create().apply { title = element.text() - setUrlWithoutDomain(element.attr("href")) + val url = URLEncoder.encode(element.attr("href"), "UTF-8") + setUrlWithoutDomain(url) val urlSorter = title.replace(":", "%20") thumbnail_url = ("https://readermc.org/images/thumbnails/$urlSorter.webp") } @@ -145,7 +199,8 @@ class MangaDemon : ParsedHttpSource() { override fun chapterFromElement(element: Element): SChapter { return SChapter.create().apply { element.select("a").let { urlElement -> - setUrlWithoutDomain(urlElement.attr("href")) + val url = URLEncoder.encode(urlElement.attr("href"), "UTF-8") + setUrlWithoutDomain(url) name = element.select("strong.chapter-title").text() } val date = element.select("time.chapter-update").text()