This commit is contained in:
kunfei 2022-09-20 10:17:12 +08:00
parent b22e1ffb34
commit c695985b75
16 changed files with 144 additions and 123 deletions

View File

@ -6,13 +6,10 @@ import androidx.room.*
import io.legado.app.constant.AppPattern
import io.legado.app.constant.BookType
import io.legado.app.data.entities.rule.*
import io.legado.app.help.SourceAnalyzer
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlinx.parcelize.IgnoredOnParcel
import io.legado.app.help.source.SourceAnalyzer
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.splitNotBlank
import kotlinx.parcelize.Parcelize
import java.io.InputStream
@ -93,70 +90,6 @@ data class BookSource(
return bookSourceUrl
}
@Ignore
@IgnoredOnParcel
@Transient
private var exploreKinds: List<ExploreKind>? = null
@Ignore
@IgnoredOnParcel
@Transient
private val mutex = Mutex()
suspend fun exploreKinds(): List<ExploreKind> {
exploreKinds?.let { return it }
val exploreUrl = exploreUrl
if (exploreUrl.isNullOrBlank()) {
return emptyList()
}
mutex.withLock {
exploreKinds?.let { return it }
val kinds = arrayListOf<ExploreKind>()
var ruleStr: String = exploreUrl
withContext(IO) {
kotlin.runCatching {
if (exploreUrl.startsWith("<js>", false)
|| exploreUrl.startsWith("@js:", false)
) {
val aCache = ACache.get("explore")
ruleStr = aCache.getAsString(bookSourceUrl) ?: ""
if (ruleStr.isBlank()) {
val jsStr = if (exploreUrl.startsWith("@")) {
exploreUrl.substring(4)
} else {
exploreUrl.substring(4, exploreUrl.lastIndexOf("<"))
}
ruleStr = evalJS(jsStr).toString().trim()
aCache.put(bookSourceUrl, ruleStr)
}
}
if (ruleStr.isJsonArray()) {
GSON.fromJsonArray<ExploreKind>(ruleStr).getOrThrow()?.let {
kinds.addAll(it)
}
} else {
ruleStr.split("(&&|\n)+".toRegex()).forEach { kindStr ->
val kindCfg = kindStr.split("::")
kinds.add(ExploreKind(kindCfg.first(), kindCfg.getOrNull(1)))
}
}
}.onFailure {
kinds.add(ExploreKind("ERROR:${it.localizedMessage}", it.stackTraceToString()))
it.printOnDebug()
}
}
exploreKinds = kinds
return kinds
}
}
suspend fun clearExploreKindsCache() {
withContext(IO) {
ACache.get("explore").remove(bookSourceUrl)
exploreKinds = null
}
}
override fun hashCode(): Int {
return bookSourceUrl.hashCode()
}

View File

@ -9,8 +9,6 @@ import androidx.room.PrimaryKey
import com.jayway.jsonpath.DocumentContext
import io.legado.app.constant.AppPattern
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
@Parcelize
@ -135,44 +133,6 @@ data class RssSource(
return this
}
suspend fun sortUrls(): List<Pair<String, String>> = arrayListOf<Pair<String, String>>().apply {
withContext(IO) {
kotlin.runCatching {
var a = sortUrl
if (sortUrl?.startsWith("<js>", false) == true
|| sortUrl?.startsWith("@js:", false) == true
) {
val aCache = ACache.get("rssSortUrl")
a = aCache.getAsString(sourceUrl) ?: ""
if (a.isBlank()) {
val jsStr = if (sortUrl!!.startsWith("@")) {
sortUrl!!.substring(4)
} else {
sortUrl!!.substring(4, sortUrl!!.lastIndexOf("<"))
}
a = evalJS(jsStr).toString()
aCache.put(sourceUrl, a)
}
}
a?.split("(&&|\n)+".toRegex())?.forEach { c ->
val d = c.split("::")
if (d.size > 1)
add(Pair(d[0], d[1]))
}
if (isEmpty()) {
add(Pair("", sourceUrl))
}
}
}
}
suspend fun removeSortCache() {
withContext(IO) {
val aCache = ACache.get("rssSortUrl")
aCache.remove(sourceUrl)
}
}
fun getDisplayVariableComment(otherComment: String): String {
return if (variableComment.isNullOrBlank()) {
otherComment

View File

@ -14,6 +14,7 @@ import io.legado.app.help.http.BackstageWebView
import io.legado.app.help.http.CookieStore
import io.legado.app.help.http.SSLHelper
import io.legado.app.help.http.StrResponse
import io.legado.app.help.source.SourceVerificationHelp
import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.analyzeRule.QueryTTF

View File

@ -0,0 +1,72 @@
package io.legado.app.help.source
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
private val mutexMap by lazy { hashMapOf<String, Mutex>() }
private val exploreKindsMap by lazy { hashMapOf<String, List<ExploreKind>>() }
private val aCache by lazy { ACache.get("explore") }
private fun BookSource.exploreKindsKey(): String {
return MD5Utils.md5Encode(bookSourceUrl + exploreUrl)
}
suspend fun BookSource.exploreKinds(): List<ExploreKind> {
val exploreKindsKey = exploreKindsKey()
exploreKindsMap[exploreKindsKey]?.let { return it }
val exploreUrl = exploreUrl
if (exploreUrl.isNullOrBlank()) {
return emptyList()
}
val mutex = mutexMap[bookSourceUrl] ?: Mutex().apply { mutexMap[bookSourceUrl] = this }
mutex.withLock {
exploreKindsMap[exploreKindsKey()]?.let { return it }
val kinds = arrayListOf<ExploreKind>()
var ruleStr: String = exploreUrl
withContext(Dispatchers.IO) {
kotlin.runCatching {
if (exploreUrl.startsWith("<js>", false)
|| exploreUrl.startsWith("@js:", false)
) {
ruleStr = aCache.getAsString(bookSourceUrl) ?: ""
if (ruleStr.isBlank()) {
val jsStr = if (exploreUrl.startsWith("@")) {
exploreUrl.substring(4)
} else {
exploreUrl.substring(4, exploreUrl.lastIndexOf("<"))
}
ruleStr = evalJS(jsStr).toString().trim()
aCache.put(exploreKindsKey, ruleStr)
}
}
if (ruleStr.isJsonArray()) {
GSON.fromJsonArray<ExploreKind>(ruleStr).getOrThrow()?.let {
kinds.addAll(it)
}
} else {
ruleStr.split("(&&|\n)+".toRegex()).forEach { kindStr ->
val kindCfg = kindStr.split("::")
kinds.add(ExploreKind(kindCfg.first(), kindCfg.getOrNull(1)))
}
}
}.onFailure {
kinds.add(ExploreKind("ERROR:${it.localizedMessage}", it.stackTraceToString()))
it.printOnDebug()
}
}
exploreKindsMap[exploreKindsKey] = kinds
return kinds
}
}
suspend fun BookSource.clearExploreKindsCache() {
withContext(Dispatchers.IO) {
aCache.remove(bookSourceUrl)
exploreKindsMap.remove(exploreKindsKey())
}
}

View File

@ -0,0 +1,51 @@
package io.legado.app.help.source
import io.legado.app.data.entities.RssSource
import io.legado.app.utils.ACache
import io.legado.app.utils.MD5Utils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
private val aCache by lazy { ACache.get("rssSortUrl") }
private fun RssSource.sortUrlsKey(): String {
return MD5Utils.md5Encode(sourceUrl + sortUrl)
}
suspend fun RssSource.sortUrls(): List<Pair<String, String>> =
arrayListOf<Pair<String, String>>().apply {
val sortUrlsKey = sortUrlsKey()
withContext(Dispatchers.IO) {
kotlin.runCatching {
var a = sortUrl
if (sortUrl?.startsWith("<js>", false) == true
|| sortUrl?.startsWith("@js:", false) == true
) {
a = aCache.getAsString(sortUrlsKey) ?: ""
if (a.isBlank()) {
val jsStr = if (sortUrl!!.startsWith("@")) {
sortUrl!!.substring(4)
} else {
sortUrl!!.substring(4, sortUrl!!.lastIndexOf("<"))
}
a = evalJS(jsStr).toString()
aCache.put(sortUrlsKey, a)
}
}
a?.split("(&&|\n)+".toRegex())?.forEach { c ->
val d = c.split("::")
if (d.size > 1)
add(Pair(d[0], d[1]))
}
if (isEmpty()) {
add(Pair("", sourceUrl))
}
}
}
}
suspend fun RssSource.removeSortCache() {
withContext(Dispatchers.IO) {
aCache.remove(sortUrlsKey())
}
}

View File

@ -1,4 +1,4 @@
package io.legado.app.help
package io.legado.app.help.source
import androidx.annotation.Keep
import com.jayway.jsonpath.JsonPath

View File

@ -1,4 +1,4 @@
package io.legado.app.help
package io.legado.app.help.source
import android.os.Handler
import android.os.Looper
@ -53,7 +53,7 @@ object SourceHelp {
val baseUrl = NetworkUtils.getBaseUrl(url)
baseUrl ?: return false
if (AppConfig.isGooglePlay) return false
try {
kotlin.runCatching {
val host = baseUrl.split("//", ".")
val base64Url = EncoderUtils.base64Encode("${host[host.lastIndex - 1]}.${host.last()}")
list18Plus.forEach {
@ -61,7 +61,6 @@ object SourceHelp {
return true
}
}
} catch (e: Exception) {
}
return false
}

View File

@ -1,8 +1,10 @@
package io.legado.app.help
package io.legado.app.help.source
import io.legado.app.constant.AppLog
import io.legado.app.data.entities.BaseSource
import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.CacheManager
import io.legado.app.help.IntentData
import io.legado.app.ui.association.VerificationCodeActivity
import io.legado.app.ui.browser.WebViewActivity
import io.legado.app.utils.startActivity

View File

@ -5,14 +5,13 @@ import io.legado.app.constant.AppPattern
import io.legado.app.constant.BookType
import io.legado.app.data.entities.*
import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.help.source.sortUrls
import io.legado.app.model.rss.Rss
import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.stackTraceStr
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.*
@ -107,7 +106,7 @@ object Debug {
cancelDebug()
debugSource = rssSource.sourceUrl
log(debugSource, "︾开始解析")
val sort = withContext(IO) { rssSource.sortUrls().first() }
val sort = rssSource.sortUrls().first()
Rss.getArticles(scope, sort.first, sort.second, rssSource, 1)
.onSuccess {
if (it.first.isEmpty()) {

View File

@ -16,6 +16,7 @@ import io.legado.app.exception.ContentEmptyException
import io.legado.app.exception.NoStackTraceException
import io.legado.app.exception.TocEmptyException
import io.legado.app.help.config.AppConfig
import io.legado.app.help.source.exploreKinds
import io.legado.app.model.CheckSource
import io.legado.app.model.Debug
import io.legado.app.model.webBook.WebBook

View File

@ -11,10 +11,10 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.BookSource
import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.ContentProcessor
import io.legado.app.help.SourceHelp
import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient
import io.legado.app.help.source.SourceHelp
import io.legado.app.utils.*

View File

@ -9,10 +9,10 @@ import io.legado.app.constant.AppPattern
import io.legado.app.data.appDb
import io.legado.app.data.entities.RssSource
import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.SourceHelp
import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient
import io.legado.app.help.source.SourceHelp
import io.legado.app.utils.*
class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {

View File

@ -12,9 +12,9 @@ import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogVerificationCodeViewBinding
import io.legado.app.help.CacheManager
import io.legado.app.help.SourceVerificationHelp
import io.legado.app.help.glide.ImageLoader
import io.legado.app.help.glide.OkHttpModelLoader
import io.legado.app.help.source.SourceVerificationHelp
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.dialog.PhotoDialog
import io.legado.app.utils.applyTint

View File

@ -15,9 +15,9 @@ import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppConst
import io.legado.app.databinding.ActivityWebViewBinding
import io.legado.app.help.SourceVerificationHelp
import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.CookieStore
import io.legado.app.help.source.SourceVerificationHelp
import io.legado.app.lib.dialogs.SelectItem
import io.legado.app.lib.theme.accentColor
import io.legado.app.model.Download

View File

@ -15,6 +15,8 @@ import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.databinding.ItemFilletTextBinding
import io.legado.app.databinding.ItemFindBookBinding
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.source.clearExploreKindsCache
import io.legado.app.help.source.exploreKinds
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.login.SourceLoginActivity
import io.legado.app.ui.widget.dialog.TextDialog

View File

@ -13,6 +13,7 @@ import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.databinding.ActivityRssArtivlesBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.source.sortUrls
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.login.SourceLoginActivity