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
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
2 changed files with 58 additions and 40 deletions

View File

@ -3,7 +3,7 @@ ext {
extClass = '.Toonily'
themePkg = 'madara'
baseUrl = 'https://toonily.com'
overrideVersionCode = 12
overrideVersionCode = 13
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.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+)$""")
}
}