Update NewToki extension to v1.2.21 (#5935)
* Improve newtoki extension. * Optimize a Id detection. * Specify the filter default settings. * Add Rate Limit Period Pref. * Fix mistake about range. and default value. * Fix bug about setDefaultValue, And pref description. * fix bugs. * More follow default variable. * lazy init to rateLimitedClient as it required to access preference. * bump up version to v1.2.21 * Follow the defaultRateLimitPeriod on load pref function * Trying to fixes #5657 as sub string baseUrl when failed to parse uri.
This commit is contained in:
parent
2582da9ae8
commit
60d4529dd6
|
@ -5,7 +5,7 @@ ext {
|
|||
extName = 'NewToki / ManaToki'
|
||||
pkgNameSuffix = 'ko.newtoki'
|
||||
extClass = '.NewTokiFactory'
|
||||
extVersionCode = 20
|
||||
extVersionCode = 21
|
||||
libVersion = '1.2'
|
||||
}
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domai
|
|||
private class SearchSortTypeList : Filter.Select<String>(
|
||||
"Sort",
|
||||
arrayOf(
|
||||
"기본",
|
||||
"기본(날짜순)",
|
||||
"인기순",
|
||||
"추천순",
|
||||
"업데이트순"
|
||||
|
|
|
@ -41,9 +41,11 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
override val lang: String = "ko"
|
||||
override val supportsLatest = true
|
||||
override val client: OkHttpClient = network.cloudflareClient
|
||||
protected val rateLimitedClient: OkHttpClient = network.cloudflareClient.newBuilder()
|
||||
.addNetworkInterceptor(RateLimitInterceptor(1))
|
||||
protected val rateLimitedClient: OkHttpClient by lazy {
|
||||
network.cloudflareClient.newBuilder()
|
||||
.addNetworkInterceptor(RateLimitInterceptor(1, getRateLimitPeriod()))
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun popularMangaSelector() = "div#webtoon-list > ul > li"
|
||||
|
||||
|
@ -70,7 +72,7 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
return if (query.startsWith(PREFIX_ID_SEARCH)) {
|
||||
val realQuery = query.removePrefix(PREFIX_ID_SEARCH)
|
||||
val urlPath = "/$boardName/$realQuery"
|
||||
client.newCall(GET("$baseUrl$urlPath"))
|
||||
rateLimitedClient.newCall(GET("$baseUrl$urlPath"))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
// the id is matches any of 'post' from their CMS board.
|
||||
|
@ -88,20 +90,20 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
// only exists on chapter with proper manga detail page.
|
||||
val fullListButton = document.select(".comic-navbar .toon-nav a").last()
|
||||
|
||||
val list: List<SManga> = if (firstChapterButton?.text()?.contains("첫회보기")
|
||||
?: false
|
||||
) { // Check this page is detail page
|
||||
val list: List<SManga> = when {
|
||||
firstChapterButton?.text()?.contains("첫회보기") == true -> { // Check this page is detail page
|
||||
val details = mangaDetailsParse(document)
|
||||
details.url = urlPath
|
||||
listOf(details)
|
||||
} else if (fullListButton?.text()?.contains("전체목록")
|
||||
?: false
|
||||
) { // Check this page is chapter page
|
||||
}
|
||||
fullListButton?.text()?.contains("전체목록") == true -> { // Check this page is chapter page
|
||||
val url = fullListButton.attr("abs:href")
|
||||
val details = mangaDetailsParse(client.newCall(GET(url)).execute())
|
||||
val details = mangaDetailsParse(rateLimitedClient.newCall(GET(url)).execute())
|
||||
details.url = getUrlPath(url)
|
||||
listOf(details)
|
||||
} else emptyList()
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
return MangasPage(list, false)
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
val rawName = linkElement.ownText().trim()
|
||||
|
||||
val chapter = SChapter.create()
|
||||
chapter.setUrlWithoutDomain(linkElement.attr("href"))
|
||||
chapter.url = getUrlWithoutDomainWithFallback(linkElement.attr("href"))
|
||||
chapter.chapter_number = parseChapterNumber(rawName)
|
||||
chapter.name = rawName
|
||||
chapter.date_upload = parseChapterDate(element.select(".wr-date").last().text().trim())
|
||||
|
@ -301,11 +303,39 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
}
|
||||
}
|
||||
|
||||
val rateLimitPeriodPref = androidx.preference.EditTextPreference(screen.context).apply {
|
||||
key = RATE_LIMIT_PERIOD_PREF_TITLE
|
||||
title = RATE_LIMIT_PERIOD_PREF_TITLE
|
||||
summary = RATE_LIMIT_PERIOD_PREF_SUMMARY
|
||||
this.setDefaultValue(defaultRateLimitPeriod.toString())
|
||||
dialogTitle = RATE_LIMIT_PERIOD_PREF_TITLE
|
||||
dialogMessage = "Min 1 to Max 9, Invalid value will treat as $defaultRateLimitPeriod. Only Integer.\nDefault: $defaultRateLimitPeriod"
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
try {
|
||||
// Make sure to validate the value.
|
||||
val p = (newValue as String).toLongOrNull(10)
|
||||
var value = p ?: defaultRateLimitPeriod
|
||||
if (p == null || value !in 1..9) {
|
||||
Toast.makeText(screen.context, RATE_LIMIT_PERIOD_PREF_WARNING_INVALID_VALUE, Toast.LENGTH_LONG).show()
|
||||
value = defaultRateLimitPeriod
|
||||
}
|
||||
val res = preferences.edit().putLong(RATE_LIMIT_PERIOD_PREF, value).commit()
|
||||
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
||||
res
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
screen.addPreference(baseUrlPref)
|
||||
if (name == "ManaToki") {
|
||||
screen.addPreference(latestExperimentPref)
|
||||
screen.addPreference(latestWithDetailPref)
|
||||
}
|
||||
screen.addPreference(rateLimitPeriodPref)
|
||||
}
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
|
@ -363,11 +393,39 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
}
|
||||
}
|
||||
|
||||
val rateLimitPeriodPref = EditTextPreference(screen.context).apply {
|
||||
key = RATE_LIMIT_PERIOD_PREF_TITLE
|
||||
title = RATE_LIMIT_PERIOD_PREF_TITLE
|
||||
summary = RATE_LIMIT_PERIOD_PREF_SUMMARY
|
||||
this.setDefaultValue(defaultRateLimitPeriod.toString())
|
||||
dialogTitle = RATE_LIMIT_PERIOD_PREF_TITLE
|
||||
dialogMessage = "Min 1 to Max 9, Invalid value will treat as $defaultRateLimitPeriod. Only Integer.\nDefault: $defaultRateLimitPeriod"
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
try {
|
||||
// Make sure to validate the value.
|
||||
val p = (newValue as String).toLongOrNull(10)
|
||||
var value = p ?: defaultRateLimitPeriod
|
||||
if (p == null || value !in 1..9) {
|
||||
Toast.makeText(screen.context, RATE_LIMIT_PERIOD_PREF_WARNING_INVALID_VALUE, Toast.LENGTH_LONG).show()
|
||||
value = defaultRateLimitPeriod
|
||||
}
|
||||
val res = preferences.edit().putLong(RATE_LIMIT_PERIOD_PREF, value).commit()
|
||||
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
||||
res
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
screen.addPreference(baseUrlPref)
|
||||
if (name == "ManaToki") {
|
||||
screen.addPreference(latestExperimentPref)
|
||||
screen.addPreference(latestWithDetailPref)
|
||||
}
|
||||
screen.addPreference(rateLimitPeriodPref)
|
||||
}
|
||||
|
||||
protected fun getUrlPath(orig: String): String {
|
||||
|
@ -378,9 +436,33 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
}
|
||||
}
|
||||
|
||||
// This is just replicate of original method but with fallback.
|
||||
protected fun getUrlWithoutDomainWithFallback(orig: String): String {
|
||||
return try {
|
||||
val uri = URI(orig)
|
||||
var out = uri.path
|
||||
if (uri.query != null) {
|
||||
out += "?" + uri.query
|
||||
}
|
||||
if (uri.fragment != null) {
|
||||
out += "#" + uri.fragment
|
||||
}
|
||||
out
|
||||
} catch (e: URISyntaxException) {
|
||||
// fallback method. may not work.
|
||||
orig.substringAfter(baseUrl)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPrefBaseUrl(): String = preferences.getString(BASE_URL_PREF, defaultBaseUrl)!!
|
||||
protected fun getExperimentLatest(): Boolean = preferences.getBoolean(EXPERIMENTAL_LATEST_PREF, false)
|
||||
protected fun getLatestWithDetail(): Boolean = preferences.getBoolean(EXPERIMENTAL_LATEST_WITH_DETAIL_PREF, false)
|
||||
private fun getRateLimitPeriod(): Long = try { // Check again as preference is bit weirdly buggy.
|
||||
val v = preferences.getLong(RATE_LIMIT_PERIOD_PREF, defaultRateLimitPeriod)
|
||||
if (v in 1..9) v else defaultRateLimitPeriod
|
||||
} catch (e: Exception) {
|
||||
defaultRateLimitPeriod
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val RESTART_TACHIYOMI = "Restart Tachiyomi to apply new setting."
|
||||
|
@ -402,6 +484,17 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
|
|||
"But makes chance of IP Ban, Also makes bunch of requests, For prevent IP ban, rate limit is set. so may slow,\n" +
|
||||
"Still, It's experiment. Required to enable `Enable Latest (Experimental).`"
|
||||
|
||||
// Settings: Rate Limit Period
|
||||
private const val defaultRateLimitPeriod: Long = 2L
|
||||
private const val RATE_LIMIT_PERIOD_PREF_TITLE = "Rate Limit Request Period Seconds"
|
||||
private const val RATE_LIMIT_PERIOD_PREF = "rateLimitPeriod"
|
||||
private const val RATE_LIMIT_PERIOD_PREF_SUMMARY =
|
||||
"As Source is using Temporary IP ban system to who makes bunch of request, Some of requests are rate limited\n" +
|
||||
"If you want to reduce limit, Use this option.\n" +
|
||||
"Invalid value will treat as default $defaultRateLimitPeriod seconds.\n" +
|
||||
"(Valid: Min 1 to Max 9)"
|
||||
private const val RATE_LIMIT_PERIOD_PREF_WARNING_INVALID_VALUE = "Invalid value detected. Treating as $defaultRateLimitPeriod..."
|
||||
|
||||
const val PREFIX_ID_SEARCH = "id:"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ class NewTokiWebtoon : NewToki("NewToki", "https://newtoki$domainNumber.com", "w
|
|||
private class SearchSortTypeList : Filter.Select<String>(
|
||||
"Sort",
|
||||
arrayOf(
|
||||
"기본",
|
||||
"기본(업데이트순)",
|
||||
"인기순",
|
||||
"추천순",
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue