Xfani:add new preference to ignore ssl verify issue. (#319)

* xfani: format source info for aniyomi

Tmporary disable ssl check for site certificate issue.

* xfani: add preference to ignore ssl verify issue.
This commit is contained in:
AlphaBoom 2024-10-21 18:36:02 +08:00 committed by GitHub
parent 80f3773bc1
commit 4dc9e2e2ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 86 additions and 19 deletions

View file

@ -1,7 +1,7 @@
ext { ext {
extName = 'Xfani' extName = 'Xfani'
extClass = '.Xfani' extClass = '.Xfani'
extVersionCode = 1 extVersionCode = 2
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View file

@ -1,9 +1,12 @@
package eu.kanade.tachiyomi.animeextension.zh.xfani package eu.kanade.tachiyomi.animeextension.zh.xfani
import android.annotation.SuppressLint
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.widget.Toast
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreferenceCompat
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
@ -19,12 +22,20 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLHandshakeException
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
class Xfani : AnimeHttpSource(), ConfigurableAnimeSource { class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
override val baseUrl: String override val baseUrl: String
@ -41,11 +52,53 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
private val numberRegex = Regex("\\d+") private val numberRegex = Regex("\\d+")
private fun OkHttpClient.Builder.ignoreAllSSLErrors(): OkHttpClient.Builder {
val naiveTrustManager =
@SuppressLint("CustomX509TrustManager")
object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray()
override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) =
Unit
override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) =
Unit
}
val insecureSocketFactory = SSLContext.getInstance("TLSv1.2").apply {
val trustAllCerts = arrayOf<TrustManager>(naiveTrustManager)
init(null, trustAllCerts, SecureRandom())
}.socketFactory
sslSocketFactory(insecureSocketFactory, naiveTrustManager)
hostnameVerifier { _, _ -> true }
return this
}
override val client: OkHttpClient
get() = if (preferences.getBoolean(PREF_KEY_IGNORE_SSL_ERROR, false)) {
network.client.newBuilder().ignoreAllSSLErrors().build()
} else {
network.client.newBuilder().addInterceptor(::checkSSLErrorInterceptor).build()
}
private val selectedVideoSource private val selectedVideoSource
get() = preferences.getString(PREF_KEY_VIDEO_SOURCE, DEFAULT_VIDEO_SOURCE)!!.toInt() get() = preferences.getString(PREF_KEY_VIDEO_SOURCE, DEFAULT_VIDEO_SOURCE)!!.toInt()
override fun animeDetailsParse(response: Response): SAnime = SAnime.create() private fun checkSSLErrorInterceptor(chain: Interceptor.Chain): Response {
try {
return chain.proceed(chain.request())
} catch (e: SSLHandshakeException) {
throw SSLHandshakeException("SSL证书验证异常可以尝试在设置中忽略SSL验证问题。")
}
}
override fun animeDetailsParse(response: Response): SAnime {
val jsoup = response.asJsoup()
return SAnime.create().apply {
description = jsoup.select("#height_limit.text").text()
title = jsoup.select(".slide-info-title").text()
}
}
override fun episodeListParse(response: Response): List<SEpisode> { override fun episodeListParse(response: Response): List<SEpisode> {
val jsoup = response.asJsoup() val jsoup = response.asJsoup()
@ -61,7 +114,7 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
url = it.attr("href") url = it.attr("href")
episode_number = numberRegex.find(name)?.value?.toFloat() ?: -1F episode_number = numberRegex.find(name)?.value?.toFloat() ?: -1F
} }
} }.sortedByDescending { it.episode_number }
} }
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
@ -92,9 +145,9 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
url = "/bangumi/${it.vodId}.html" url = "/bangumi/${it.vodId}.html"
thumbnail_url = it.vodPicThumb.ifEmpty { it.vodPic } thumbnail_url = it.vodPicThumb.ifEmpty { it.vodPic }
title = it.vodName title = it.vodName
author = it.vodActor author = it.vodActor.replace(",,,", "")
description = it.vodBlurb description = it.vodBlurb
genre = it.vodClass genre = it.vodClass.replace(",", ", ")
} }
} }
return AnimesPage( return AnimesPage(
@ -184,7 +237,8 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) { override fun setupPreferenceScreen(screen: PreferenceScreen) {
screen.addPreference( screen.apply {
addPreference(
ListPreference(screen.context).apply { ListPreference(screen.context).apply {
key = PREF_KEY_VIDEO_SOURCE key = PREF_KEY_VIDEO_SOURCE
title = "请设置首选视频源线路" title = "请设置首选视频源线路"
@ -198,10 +252,23 @@ class Xfani : AnimeHttpSource(), ConfigurableAnimeSource {
} }
}, },
) )
addPreference(
SwitchPreferenceCompat(screen.context).apply {
key = PREF_KEY_IGNORE_SSL_ERROR
title = "忽略SSL证书校验"
setDefaultValue(false)
setOnPreferenceChangeListener { _, _ ->
Toast.makeText(screen.context, "重启应用后生效", Toast.LENGTH_SHORT).show()
true
}
},
)
}
} }
companion object { companion object {
const val PREF_KEY_VIDEO_SOURCE = "PREF_KEY_VIDEO_SOURCE" const val PREF_KEY_VIDEO_SOURCE = "PREF_KEY_VIDEO_SOURCE"
const val PREF_KEY_IGNORE_SSL_ERROR = "PREF_KEY_IGNORE_SSL_ERROR"
const val DEFAULT_VIDEO_SOURCE = "0" const val DEFAULT_VIDEO_SOURCE = "0"