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:
DitFranXX 2021-02-22 00:19:52 +09:00 committed by GitHub
parent 2582da9ae8
commit 60d4529dd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 115 additions and 22 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'NewToki / ManaToki'
pkgNameSuffix = 'ko.newtoki'
extClass = '.NewTokiFactory'
extVersionCode = 20
extVersionCode = 21
libVersion = '1.2'
}

View File

@ -230,7 +230,7 @@ class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domai
private class SearchSortTypeList : Filter.Select<String>(
"Sort",
arrayOf(
"기본",
"기본(날짜순)",
"인기순",
"추천순",
"업데이트순"

View File

@ -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))
.build()
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 details = mangaDetailsParse(document)
details.url = urlPath
listOf(details)
} else if (fullListButton?.text()?.contains("전체목록")
?: false
) { // Check this page is chapter page
val url = fullListButton.attr("abs:href")
val details = mangaDetailsParse(client.newCall(GET(url)).execute())
details.url = getUrlPath(url)
listOf(details)
} else emptyList()
val list: List<SManga> = when {
firstChapterButton?.text()?.contains("첫회보기") == true -> { // Check this page is detail page
val details = mangaDetailsParse(document)
details.url = urlPath
listOf(details)
}
fullListButton?.text()?.contains("전체목록") == true -> { // Check this page is chapter page
val url = fullListButton.attr("abs:href")
val details = mangaDetailsParse(rateLimitedClient.newCall(GET(url)).execute())
details.url = getUrlPath(url)
listOf(details)
}
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:"
}
}

View File

@ -146,7 +146,7 @@ class NewTokiWebtoon : NewToki("NewToki", "https://newtoki$domainNumber.com", "w
private class SearchSortTypeList : Filter.Select<String>(
"Sort",
arrayOf(
"기본",
"기본(업데이트순)",
"인기순",
"추천순",
)