diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index e6371ac79..7f68e9fa8 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -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? = null - - @Ignore - @IgnoredOnParcel - @Transient - private val mutex = Mutex() - - suspend fun exploreKinds(): List { - exploreKinds?.let { return it } - val exploreUrl = exploreUrl - if (exploreUrl.isNullOrBlank()) { - return emptyList() - } - mutex.withLock { - exploreKinds?.let { return it } - val kinds = arrayListOf() - var ruleStr: String = exploreUrl - withContext(IO) { - kotlin.runCatching { - if (exploreUrl.startsWith("", 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(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() } diff --git a/app/src/main/java/io/legado/app/data/entities/RssSource.kt b/app/src/main/java/io/legado/app/data/entities/RssSource.kt index 17b270f33..9982e4196 100644 --- a/app/src/main/java/io/legado/app/data/entities/RssSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/RssSource.kt @@ -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> = arrayListOf>().apply { - withContext(IO) { - kotlin.runCatching { - var a = sortUrl - if (sortUrl?.startsWith("", 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 diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 16c9dc14e..7990165aa 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt b/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt new file mode 100644 index 000000000..07c875971 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt @@ -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() } +private val exploreKindsMap by lazy { hashMapOf>() } +private val aCache by lazy { ACache.get("explore") } + +private fun BookSource.exploreKindsKey(): String { + return MD5Utils.md5Encode(bookSourceUrl + exploreUrl) +} + +suspend fun BookSource.exploreKinds(): List { + 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() + var ruleStr: String = exploreUrl + withContext(Dispatchers.IO) { + kotlin.runCatching { + if (exploreUrl.startsWith("", 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(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()) + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/source/RssSourceExtensions.kt b/app/src/main/java/io/legado/app/help/source/RssSourceExtensions.kt new file mode 100644 index 000000000..e7332ad34 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/source/RssSourceExtensions.kt @@ -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> = + arrayListOf>().apply { + val sortUrlsKey = sortUrlsKey() + withContext(Dispatchers.IO) { + kotlin.runCatching { + var a = sortUrl + if (sortUrl?.startsWith("", 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()) + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt b/app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt similarity index 99% rename from app/src/main/java/io/legado/app/help/SourceAnalyzer.kt rename to app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt index 25b80b893..f958c09b3 100644 --- a/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt +++ b/app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt @@ -1,4 +1,4 @@ -package io.legado.app.help +package io.legado.app.help.source import androidx.annotation.Keep import com.jayway.jsonpath.JsonPath diff --git a/app/src/main/java/io/legado/app/help/SourceHelp.kt b/app/src/main/java/io/legado/app/help/source/SourceHelp.kt similarity index 96% rename from app/src/main/java/io/legado/app/help/SourceHelp.kt rename to app/src/main/java/io/legado/app/help/source/SourceHelp.kt index c4b4bfdb1..17fdea0da 100644 --- a/app/src/main/java/io/legado/app/help/SourceHelp.kt +++ b/app/src/main/java/io/legado/app/help/source/SourceHelp.kt @@ -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 } diff --git a/app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt b/app/src/main/java/io/legado/app/help/source/SourceVerificationHelp.kt similarity index 95% rename from app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt rename to app/src/main/java/io/legado/app/help/source/SourceVerificationHelp.kt index 93e6c7e6e..908ad1a1f 100644 --- a/app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt +++ b/app/src/main/java/io/legado/app/help/source/SourceVerificationHelp.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/model/Debug.kt b/app/src/main/java/io/legado/app/model/Debug.kt index fef2b45a9..c2b3e70c6 100644 --- a/app/src/main/java/io/legado/app/model/Debug.kt +++ b/app/src/main/java/io/legado/app/model/Debug.kt @@ -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()) { diff --git a/app/src/main/java/io/legado/app/service/CheckSourceService.kt b/app/src/main/java/io/legado/app/service/CheckSourceService.kt index dda58ba7f..868c92d62 100644 --- a/app/src/main/java/io/legado/app/service/CheckSourceService.kt +++ b/app/src/main/java/io/legado/app/service/CheckSourceService.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt index 89268f2e4..be268cdef 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt @@ -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.* diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt index d44414c9a..73cd1314c 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt @@ -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) { diff --git a/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt b/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt index c6408ccf6..7fb494395 100644 --- a/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt +++ b/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt b/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt index 63d22f039..9dc9d8e05 100644 --- a/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt +++ b/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt index e8681fa52..7f945a1ef 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt index 27ef2a11f..69c015e0c 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt @@ -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