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.AppPattern
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.data.entities.rule.* import io.legado.app.data.entities.rule.*
import io.legado.app.help.SourceAnalyzer import io.legado.app.help.source.SourceAnalyzer
import io.legado.app.utils.* import io.legado.app.utils.GSON
import kotlinx.coroutines.Dispatchers.IO import io.legado.app.utils.fromJsonObject
import kotlinx.coroutines.sync.Mutex import io.legado.app.utils.splitNotBlank
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import java.io.InputStream import java.io.InputStream
@ -93,70 +90,6 @@ data class BookSource(
return bookSourceUrl 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 { override fun hashCode(): Int {
return bookSourceUrl.hashCode() return bookSourceUrl.hashCode()
} }

View File

@ -9,8 +9,6 @@ import androidx.room.PrimaryKey
import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.DocumentContext
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
@ -135,44 +133,6 @@ data class RssSource(
return this 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 { fun getDisplayVariableComment(otherComment: String): String {
return if (variableComment.isNullOrBlank()) { return if (variableComment.isNullOrBlank()) {
otherComment 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.CookieStore
import io.legado.app.help.http.SSLHelper import io.legado.app.help.http.SSLHelper
import io.legado.app.help.http.StrResponse 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.Debug
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.analyzeRule.QueryTTF 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 androidx.annotation.Keep
import com.jayway.jsonpath.JsonPath 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.Handler
import android.os.Looper import android.os.Looper
@ -53,7 +53,7 @@ object SourceHelp {
val baseUrl = NetworkUtils.getBaseUrl(url) val baseUrl = NetworkUtils.getBaseUrl(url)
baseUrl ?: return false baseUrl ?: return false
if (AppConfig.isGooglePlay) return false if (AppConfig.isGooglePlay) return false
try { kotlin.runCatching {
val host = baseUrl.split("//", ".") val host = baseUrl.split("//", ".")
val base64Url = EncoderUtils.base64Encode("${host[host.lastIndex - 1]}.${host.last()}") val base64Url = EncoderUtils.base64Encode("${host[host.lastIndex - 1]}.${host.last()}")
list18Plus.forEach { list18Plus.forEach {
@ -61,7 +61,6 @@ object SourceHelp {
return true return true
} }
} }
} catch (e: Exception) {
} }
return false 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.constant.AppLog
import io.legado.app.data.entities.BaseSource import io.legado.app.data.entities.BaseSource
import io.legado.app.exception.NoStackTraceException 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.association.VerificationCodeActivity
import io.legado.app.ui.browser.WebViewActivity import io.legado.app.ui.browser.WebViewActivity
import io.legado.app.utils.startActivity 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.constant.BookType
import io.legado.app.data.entities.* import io.legado.app.data.entities.*
import io.legado.app.help.coroutine.CompositeCoroutine 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.rss.Rss
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.HtmlFormatter import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.stackTraceStr import io.legado.app.utils.stackTraceStr
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -107,7 +106,7 @@ object Debug {
cancelDebug() cancelDebug()
debugSource = rssSource.sourceUrl debugSource = rssSource.sourceUrl
log(debugSource, "︾开始解析") log(debugSource, "︾开始解析")
val sort = withContext(IO) { rssSource.sortUrls().first() } val sort = rssSource.sortUrls().first()
Rss.getArticles(scope, sort.first, sort.second, rssSource, 1) Rss.getArticles(scope, sort.first, sort.second, rssSource, 1)
.onSuccess { .onSuccess {
if (it.first.isEmpty()) { 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.NoStackTraceException
import io.legado.app.exception.TocEmptyException import io.legado.app.exception.TocEmptyException
import io.legado.app.help.config.AppConfig 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.CheckSource
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.model.webBook.WebBook 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.data.entities.BookSource
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.ContentProcessor import io.legado.app.help.ContentProcessor
import io.legado.app.help.SourceHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.help.source.SourceHelp
import io.legado.app.utils.* 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.appDb
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.SourceHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.help.source.SourceHelp
import io.legado.app.utils.* import io.legado.app.utils.*
class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { 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.base.BaseDialogFragment
import io.legado.app.databinding.DialogVerificationCodeViewBinding import io.legado.app.databinding.DialogVerificationCodeViewBinding
import io.legado.app.help.CacheManager 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.ImageLoader
import io.legado.app.help.glide.OkHttpModelLoader 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.lib.theme.primaryColor
import io.legado.app.ui.widget.dialog.PhotoDialog import io.legado.app.ui.widget.dialog.PhotoDialog
import io.legado.app.utils.applyTint 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.base.VMBaseActivity
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.databinding.ActivityWebViewBinding import io.legado.app.databinding.ActivityWebViewBinding
import io.legado.app.help.SourceVerificationHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.CookieStore 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.dialogs.SelectItem
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.model.Download 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.ItemFilletTextBinding
import io.legado.app.databinding.ItemFindBookBinding import io.legado.app.databinding.ItemFindBookBinding
import io.legado.app.help.coroutine.Coroutine 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.lib.theme.accentColor
import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.ui.login.SourceLoginActivity
import io.legado.app.ui.widget.dialog.TextDialog 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.base.VMBaseActivity
import io.legado.app.databinding.ActivityRssArtivlesBinding import io.legado.app.databinding.ActivityRssArtivlesBinding
import io.legado.app.databinding.DialogEditTextBinding 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.dialogs.alert
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.ui.login.SourceLoginActivity