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
This commit is contained in:
AwkwardPeak7 2025-04-20 06:29:04 +05:00 committed by Draff
parent 1c2876f7a5
commit 9ad099295c
Signed by: Draff
GPG Key ID: E8A89F3211677653
2 changed files with 58 additions and 40 deletions

View File

@ -3,7 +3,7 @@ ext {
extClass = '.Toonily' extClass = '.Toonily'
themePkg = 'madara' themePkg = 'madara'
baseUrl = 'https://toonily.com' baseUrl = 'https://toonily.com'
overrideVersionCode = 12 overrideVersionCode = 13
isNsfw = true isNsfw = true
} }

View File

@ -4,9 +4,10 @@ import eu.kanade.tachiyomi.lib.cookieinterceptor.CookieInterceptor
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import okhttp3.HttpUrl.Companion.toHttpUrl import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.OkHttpClient import okhttp3.Interceptor
import okhttp3.Request import okhttp3.Request
import okhttp3.Response
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -17,63 +18,80 @@ class Toonily : Madara(
"en", "en",
SimpleDateFormat("MMM d, yy", Locale.US), SimpleDateFormat("MMM d, yy", Locale.US),
) { ) {
override val client = super.client.newBuilder()
override val client: OkHttpClient = super.client.newBuilder()
.addNetworkInterceptor(CookieInterceptor(domain, "toonily-mature" to "1")) .addNetworkInterceptor(CookieInterceptor(domain, "toonily-mature" to "1"))
.addInterceptor(::hdCoverInterceptor)
.build() .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 { override fun searchMangaSelector() = "div.page-item-detail.manga"
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 searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val request = super.searchMangaRequest(page, query, filters) return super.searchMangaRequest(
page,
val queries = request.url.queryParameterNames query.replace(titleSpecialCharactersRegex, " ").trim(),
.filterNot { it == "s" } filters,
)
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()
} }
override fun genresRequest(): Request { override fun genresRequest(): Request {
return GET("$baseUrl/search/?post_type=wp-manga", headers) return GET("$baseUrl/search/?post_type=wp-manga", headers)
} }
// The source customized the Madara theme and broke the filter. override fun mangaDetailsRequest(manga: SManga): Request {
override val filterNonMangaItems = false val newManga = SManga.create().apply {
url = manga.url.replace("/webtoon/", "/$mangaSubString/")
}
return super.mangaDetailsRequest(newManga)
}
override val useNewChapterEndpoint: Boolean = true override fun chapterListRequest(manga: SManga): Request {
return mangaDetailsRequest(manga)
override fun searchMangaSelector() = "div.page-item-detail.manga" }
override fun parseChapterDate(date: String?): Long { override fun parseChapterDate(date: String?): Long {
val formattedDate = if (date?.contains("UP") == true) "today" else date val formattedDate = if (date?.contains("UP") == true) "today" else date
return super.parseChapterDate(formattedDate) 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 { companion object {
val titleSpecialCharactersRegex = "[^a-z0-9]+".toRegex() val titleSpecialCharactersRegex = "[^a-z0-9]+".toRegex()
val trailingHyphenRegex = "-+$".toRegex() val sdCoverRegex = Regex("""-[0-9]+x[0-9]+(\.\w+)$""")
} }
} }