From 9ad099295c99083bb5099b22e042a8812c587dde Mon Sep 17 00:00:00 2001 From: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com> Date: Sun, 20 Apr 2025 06:29:04 +0500 Subject: [PATCH] Toonily: various fixes (#8544) * Toonily: various fixes - change `mangaSubString` -> serie - prevent 302 redirect - disable count views - 400 bad request - use LoadMoreRequest - fetch hd covers if possible * query cleanup * review changes --- src/en/toonily/build.gradle | 2 +- .../tachiyomi/extension/en/toonily/Toonily.kt | 96 +++++++++++-------- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/en/toonily/build.gradle b/src/en/toonily/build.gradle index 4c1ef4164..8e4a8dcd2 100644 --- a/src/en/toonily/build.gradle +++ b/src/en/toonily/build.gradle @@ -3,7 +3,7 @@ ext { extClass = '.Toonily' themePkg = 'madara' baseUrl = 'https://toonily.com' - overrideVersionCode = 12 + overrideVersionCode = 13 isNsfw = true } diff --git a/src/en/toonily/src/eu/kanade/tachiyomi/extension/en/toonily/Toonily.kt b/src/en/toonily/src/eu/kanade/tachiyomi/extension/en/toonily/Toonily.kt index c47873707..a3bc860b4 100644 --- a/src/en/toonily/src/eu/kanade/tachiyomi/extension/en/toonily/Toonily.kt +++ b/src/en/toonily/src/eu/kanade/tachiyomi/extension/en/toonily/Toonily.kt @@ -4,9 +4,10 @@ import eu.kanade.tachiyomi.lib.cookieinterceptor.CookieInterceptor import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.model.FilterList -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.OkHttpClient +import eu.kanade.tachiyomi.source.model.SManga +import okhttp3.Interceptor import okhttp3.Request +import okhttp3.Response import java.text.SimpleDateFormat import java.util.Locale @@ -17,63 +18,80 @@ class Toonily : Madara( "en", SimpleDateFormat("MMM d, yy", Locale.US), ) { - - override val client: OkHttpClient = super.client.newBuilder() + override val client = super.client.newBuilder() .addNetworkInterceptor(CookieInterceptor(domain, "toonily-mature" to "1")) + .addInterceptor(::hdCoverInterceptor) .build() - override val mangaSubString = "webtoon" + override val mangaSubString = "serie" + override val filterNonMangaItems = false + override val useNewChapterEndpoint = true + override val sendViewCount = false + override val useLoadMoreRequest = LoadMoreStrategy.Always - private fun searchPage(page: Int, query: String): String { - val urlQuery = query.trim() - .lowercase(Locale.US) - .replace(titleSpecialCharactersRegex, "-") - .replace(trailingHyphenRegex, "") - .let { if (it.isNotEmpty()) "$it/" else it } - return if (page > 1) { - "search/${urlQuery}page/$page/" - } else { - "search/$urlQuery" - } - } + override fun searchMangaSelector() = "div.page-item-detail.manga" override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val request = super.searchMangaRequest(page, query, filters) - - val queries = request.url.queryParameterNames - .filterNot { it == "s" } - - val newUrl = "$baseUrl/${searchPage(page, query)}".toHttpUrl().newBuilder().apply { - queries.map { q -> - request.url.queryParameterValues(q).map { - this.addQueryParameter(q, it) - } - } - }.build() - - return request.newBuilder() - .url(newUrl) - .build() + return super.searchMangaRequest( + page, + query.replace(titleSpecialCharactersRegex, " ").trim(), + filters, + ) } override fun genresRequest(): Request { return GET("$baseUrl/search/?post_type=wp-manga", headers) } - // The source customized the Madara theme and broke the filter. - override val filterNonMangaItems = false + override fun mangaDetailsRequest(manga: SManga): Request { + val newManga = SManga.create().apply { + url = manga.url.replace("/webtoon/", "/$mangaSubString/") + } + return super.mangaDetailsRequest(newManga) + } - override val useNewChapterEndpoint: Boolean = true - - override fun searchMangaSelector() = "div.page-item-detail.manga" + override fun chapterListRequest(manga: SManga): Request { + return mangaDetailsRequest(manga) + } override fun parseChapterDate(date: String?): Long { val formattedDate = if (date?.contains("UP") == true) "today" else date return super.parseChapterDate(formattedDate) } + private fun hdCoverInterceptor(chain: Interceptor.Chain): Response { + val request = chain.request() + val url = request.url + + return if ( + url.pathSegments.firstOrNull() == "wp-content" && + url.pathSegments.lastOrNull()?.contains(sdCoverRegex) == true + ) { + try { + val newUrl = url.newBuilder() + .removePathSegment(url.pathSegments.lastIndex) + .addPathSegment( + sdCoverRegex.replace( + url.pathSegments.last(), + "$1", + ), + ).build() + val newRequest = request.newBuilder() + .url(newUrl) + .build() + + chain.proceed(newRequest) + .also { assert(it.isSuccessful) } + } catch (_: Throwable) { + chain.proceed(request) + } + } else { + chain.proceed(request) + } + } + companion object { val titleSpecialCharactersRegex = "[^a-z0-9]+".toRegex() - val trailingHyphenRegex = "-+$".toRegex() + val sdCoverRegex = Regex("""-[0-9]+x[0-9]+(\.\w+)$""") } }