From ef6c1015d9504af721f2a54ffeb89114fa775724 Mon Sep 17 00:00:00 2001 From: stevenyomi <95685115+stevenyomi@users.noreply.github.com> Date: Fri, 19 May 2023 18:15:56 +0800 Subject: [PATCH] WNACG: auto update domains (#16436) * WNACG: auto update domains * mark updated if unchanged * Dedupe * Fix * Reorder parameters --- src/zh/wnacg/build.gradle | 2 +- .../extension/zh/wnacg/Preferences.kt | 126 ++++++++++++++---- .../tachiyomi/extension/zh/wnacg/wnacg.kt | 19 ++- 3 files changed, 112 insertions(+), 35 deletions(-) diff --git a/src/zh/wnacg/build.gradle b/src/zh/wnacg/build.gradle index 00488f84c..0e50b8a2e 100644 --- a/src/zh/wnacg/build.gradle +++ b/src/zh/wnacg/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'WNACG' pkgNameSuffix = 'zh.wnacg' extClass = '.wnacg' - extVersionCode = 12 + extVersionCode = 13 isNsfw = true } diff --git a/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/Preferences.kt b/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/Preferences.kt index 26ebb0ba9..70525cac5 100644 --- a/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/Preferences.kt +++ b/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/Preferences.kt @@ -1,43 +1,113 @@ package eu.kanade.tachiyomi.extension.zh.wnacg +import android.app.Application import android.content.Context import android.content.SharedPreferences -import androidx.preference.EditTextPreference +import androidx.preference.ListPreference +import eu.kanade.tachiyomi.network.GET +import okhttp3.Interceptor +import okhttp3.Response +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get +import java.io.IOException +import kotlin.random.Random -private const val BASE_URL = "http://www.htmanga3.top" +private const val DEFAULT_LIST = "https://www.htmanga3.top,https://www.htmanga4.top,https://www.htmanga5.top" -fun getPreferencesInternal(context: Context, preferences: SharedPreferences) = arrayOf( - EditTextPreference(context).apply { - key = OVERRIDE_BASE_URL_PREF +fun getPreferencesInternal( + context: Context, + preferences: SharedPreferences, + isUrlUpdated: Boolean, +) = arrayOf( + ListPreference(context).apply { + key = URL_INDEX_PREF title = "网址" - summary = "默认网址为:$BASE_URL\n" + - "可以尝试的网址有:\n" + - " http://www.htmanga4.top\n" + - " http://www.htmanga5.top\n" + - "可以到 www.wnacglink.top 查看最新网址。\n" + - "如果默认网址失效,可以在此填写新的网址。重启生效。" + summary = if (isUrlUpdated) "%s\n网址已自动更新,请重启应用。" else "%s\n正常情况下会自动更新。重启生效。" - setOnPreferenceChangeListener { _, _ -> - preferences.edit().putString(DEFAULT_BASE_URL_PREF, BASE_URL).apply() - true - } + val options = preferences.urlList + val count = options.size + entries = options.toTypedArray() + entryValues = Array(count, Int::toString) }, ) val SharedPreferences.baseUrl: String get() { - val overrideBaseUrl = getString(OVERRIDE_BASE_URL_PREF, "")!! - if (overrideBaseUrl.isNotEmpty()) { - val defaultBaseUrl = getString(DEFAULT_BASE_URL_PREF, "")!! - if (defaultBaseUrl == BASE_URL) return overrideBaseUrl - // Outdated - edit() - .remove(OVERRIDE_BASE_URL_PREF) - .remove(DEFAULT_BASE_URL_PREF) - .apply() - } - return BASE_URL + val list = urlList + return list.getOrNull(urlIndex) ?: list[0] } -private const val OVERRIDE_BASE_URL_PREF = "overrideBaseUrl" -private const val DEFAULT_BASE_URL_PREF = "defaultBaseUrl" +val SharedPreferences.urlIndex get() = getString(URL_INDEX_PREF, "-1")!!.toInt() +val SharedPreferences.urlList get() = getString(URL_LIST_PREF, DEFAULT_LIST)!!.split(",") + +fun getCiBaseUrl() = DEFAULT_LIST.replace(",", ", ") + +fun getSharedPreferences(id: Long): SharedPreferences { + val preferences: SharedPreferences = Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) + if (preferences.getString(DEFAULT_LIST_PREF, "")!! == DEFAULT_LIST) return preferences + preferences.edit() + .remove("overrideBaseUrl") + .putString(DEFAULT_LIST_PREF, DEFAULT_LIST) + .setUrlList(DEFAULT_LIST, preferences.urlIndex) + .apply() + return preferences +} + +fun SharedPreferences.Editor.setUrlList(urlList: String, oldIndex: Int): SharedPreferences.Editor { + putString(URL_LIST_PREF, urlList) + val maxIndex = urlList.count { it == ',' } + if (oldIndex in 0..maxIndex) return this + val newIndex = Random.nextInt(0, maxIndex + 1) + return putString(URL_INDEX_PREF, newIndex.toString()) +} + +class UpdateUrlInterceptor(private val preferences: SharedPreferences) : Interceptor { + private val baseUrl = preferences.baseUrl + var isUpdated = false + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + if (!request.url.toString().startsWith(baseUrl)) return chain.proceed(request) + + val failedResponse = try { + val response = chain.proceed(request) + if (response.isSuccessful) return response + Result.success(response) + } catch (e: Throwable) { + if (chain.call().isCanceled()) throw e + Result.failure(e) + } + + if (isUpdated || updateUrl(chain)) { + failedResponse.onSuccess(Response::close) + throw IOException("网址已自动更新,请重启应用") + } + return failedResponse.getOrThrow() + } + + @Synchronized + private fun updateUrl(chain: Interceptor.Chain): Boolean { + if (isUpdated) return true + val response = try { + chain.proceed(GET("https://stevenyomi.github.io/source-domains/wnacg.txt")) + } catch (_: Throwable) { + return false + } + if (!response.isSuccessful) { + response.close() + return false + } + val newList = response.body.string() + if (newList != preferences.getString(URL_LIST_PREF, "")!!) { + preferences.edit() + .setUrlList(newList, preferences.urlIndex) + .apply() + } + isUpdated = true + return true + } +} + +private const val DEFAULT_LIST_PREF = "defaultBaseUrl" +private const val URL_LIST_PREF = "baseUrlList" +private const val URL_INDEX_PREF = "baseUrlIndex" diff --git a/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/wnacg.kt b/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/wnacg.kt index 49bcaadd6..a2e6e4a3b 100644 --- a/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/wnacg.kt +++ b/src/zh/wnacg/src/eu/kanade/tachiyomi/extension/zh/wnacg/wnacg.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.extension.zh.wnacg -import android.app.Application import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.ConfigurableSource @@ -17,8 +16,6 @@ import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get // URL can be found at https://www.wnacglink.top/ class wnacg : ParsedHttpSource(), ConfigurableSource { @@ -26,8 +23,18 @@ class wnacg : ParsedHttpSource(), ConfigurableSource { override val lang = "zh" override val supportsLatest = false - private val preferences = Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)!! - override val baseUrl = preferences.baseUrl + private val preferences = getSharedPreferences(id) + + override val baseUrl = when (System.getenv("CI")) { + "true" -> getCiBaseUrl() + else -> preferences.baseUrl + } + + private val updateUrlInterceptor = UpdateUrlInterceptor(preferences) + + override val client = network.client.newBuilder() + .addInterceptor(updateUrlInterceptor) + .build() override fun popularMangaSelector() = ".gallary_item" override fun latestUpdatesSelector() = throw Exception("Not used") @@ -155,6 +162,6 @@ class wnacg : ParsedHttpSource(), ConfigurableSource { // <<< Filters <<< override fun setupPreferenceScreen(screen: PreferenceScreen) { - getPreferencesInternal(screen.context, preferences).forEach(screen::addPreference) + getPreferencesInternal(screen.context, preferences, updateUrlInterceptor.isUpdated).forEach(screen::addPreference) } }