kunfei 4 years ago
parent
commit
873dd1a9d1

+ 4 - 71
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<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()
     }

+ 0 - 40
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<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

+ 1 - 0
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

+ 72 - 0
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<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())
+    }
+}

+ 51 - 0
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<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())
+    }
+}

+ 1 - 1
app/src/main/java/io/legado/app/help/SourceAnalyzer.kt → 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

+ 2 - 3
app/src/main/java/io/legado/app/help/SourceHelp.kt → 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
     }

+ 3 - 1
app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt → 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

+ 2 - 3
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()) {

+ 1 - 0
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

+ 1 - 1
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.*
 
 

+ 1 - 1
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) {

+ 1 - 1
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

+ 1 - 1
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

+ 2 - 0
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

+ 1 - 0
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