Horis 1 год назад
Родитель
Сommit
9e1cedd683

+ 6 - 6
app/src/main/java/io/legado/app/data/entities/BookSource.kt

@@ -148,12 +148,12 @@ data class BookSource(
         return rule
     }
 
-    fun getReviewRule(): ReviewRule {
-        ruleReview?.let { return it }
-        val rule = ReviewRule()
-        ruleReview = rule
-        return rule
-    }
+//    fun getReviewRule(): ReviewRule {
+//        ruleReview?.let { return it }
+//        val rule = ReviewRule()
+//        ruleReview = rule
+//        return rule
+//    }
 
     fun getDisPlayNameGroup(): String {
         return if (bookSourceGroup.isNullOrBlank()) {

+ 7 - 0
app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt

@@ -104,6 +104,13 @@ suspend fun BookSource.clearExploreKindsCache() {
     }
 }
 
+fun BookSource.exploreKindsJson(): String {
+    val exploreKindsKey = getExploreKindsKey()
+    return aCache.getAsString(exploreKindsKey)?.takeIf { it.isJsonArray() }
+        ?: exploreUrl.takeIf { it.isJsonArray() }
+        ?: ""
+}
+
 fun BookSource.getBookType(): Int {
     return when (bookSourceType) {
         BookSourceType.file -> BookType.text or BookType.webFile

+ 16 - 1
app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt

@@ -17,8 +17,10 @@ import io.legado.app.help.CacheManager
 import io.legado.app.help.JsExtensions
 import io.legado.app.help.http.CookieStore
 import io.legado.app.help.source.getShareScope
+import io.legado.app.model.Debug
 import io.legado.app.model.webBook.WebBook
 import io.legado.app.utils.GSON
+import io.legado.app.utils.GSONStrict
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.fromJsonObject
 import io.legado.app.utils.getOrPutLimit
@@ -78,6 +80,8 @@ class AnalyzeRule(
 
     private var coroutineContext: CoroutineContext = EmptyCoroutineContext
 
+    private var loggedNonStandardJSON = false
+
     @JvmOverloads
     fun setContent(content: Any?, baseUrl: String? = null): AnalyzeRule {
         if (content == null) throw AssertionError("内容不可空(Content cannot be null)")
@@ -408,9 +412,20 @@ class AnalyzeRule(
         val putMatcher = putPattern.matcher(vRuleStr)
         while (putMatcher.find()) {
             vRuleStr = vRuleStr.replace(putMatcher.group(), "")
-            GSON.fromJsonObject<Map<String, String>>(putMatcher.group(1))
+            val putJsonStr = putMatcher.group(1)
+            val putJson = GSONStrict.fromJsonObject<Map<String, String>>(putJsonStr)
+                .getOrNull()
+            if (putJson != null) {
+                putMap.putAll(putJson)
+                continue
+            }
+            GSON.fromJsonObject<Map<String, String>>(putJsonStr)
                 .getOrNull()
                 ?.let {
+                    if (!loggedNonStandardJSON) {
+                        Debug.log("≡@put 规则 JSON 格式不规范,请改为规范格式")
+                        loggedNonStandardJSON = true
+                    }
                     putMap.putAll(it)
                 }
         }

+ 11 - 2
app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt

@@ -39,8 +39,10 @@ import io.legado.app.help.http.postForm
 import io.legado.app.help.http.postJson
 import io.legado.app.help.http.postMultipart
 import io.legado.app.help.source.getShareScope
+import io.legado.app.model.Debug
 import io.legado.app.utils.EncoderUtils
 import io.legado.app.utils.GSON
+import io.legado.app.utils.GSONStrict
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.fromJsonArray
 import io.legado.app.utils.fromJsonObject
@@ -219,8 +221,15 @@ class AnalyzeUrl(
             baseUrl = it
         }
         if (urlNoOption.length != ruleUrl.length) {
-            GSON.fromJsonObject<UrlOption>(ruleUrl.substring(urlMatcher.end())).getOrNull()
-                ?.let { option ->
+            val urlOptionStr = ruleUrl.substring(urlMatcher.end())
+            var urlOption = GSONStrict.fromJsonObject<UrlOption>(urlOptionStr).getOrNull()
+            if (urlOption == null) {
+                urlOption = GSON.fromJsonObject<UrlOption>(urlOptionStr).getOrNull()
+                if (urlOption != null) {
+                    Debug.log("≡链接参数 JSON 格式不规范,请改为规范格式")
+                }
+            }
+            urlOption?.let { option ->
                     option.getMethod()?.let {
                         if (it.equals("POST", true)) method = RequestMethod.POST
                     }

+ 25 - 0
app/src/main/java/io/legado/app/model/webBook/BookList.kt

@@ -5,17 +5,22 @@ import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.SearchBook
 import io.legado.app.data.entities.rule.BookListRule
+import io.legado.app.data.entities.rule.ExploreKind
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.book.BookHelp
+import io.legado.app.help.source.exploreKindsJson
 import io.legado.app.help.source.getBookType
 import io.legado.app.model.Debug
 import io.legado.app.model.analyzeRule.AnalyzeRule
 import io.legado.app.model.analyzeRule.AnalyzeRule.Companion.setCoroutineContext
 import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.model.analyzeRule.RuleData
+import io.legado.app.utils.GSON
+import io.legado.app.utils.GSONStrict
 import io.legado.app.utils.HtmlFormatter
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.StringUtils.wordCountFormat
+import io.legado.app.utils.fromJsonArray
 import kotlinx.coroutines.ensureActive
 import splitties.init.appCtx
 import kotlin.coroutines.coroutineContext
@@ -50,6 +55,9 @@ object BookList {
         analyzeRule.setContent(body).setBaseUrl(baseUrl)
         analyzeRule.setRedirectUrl(baseUrl)
         analyzeRule.setCoroutineContext(coroutineContext)
+        if (!isSearch) {
+            checkExploreJson(bookSource)
+        }
         if (isSearch) bookSource.bookUrlPattern?.let {
             coroutineContext.ensureActive()
             if (baseUrl.matches(it.toRegex())) {
@@ -279,4 +287,21 @@ object BookList {
         return null
     }
 
+    private fun checkExploreJson(bookSource: BookSource) {
+        if (Debug.callback == null) {
+            return
+        }
+        val json = bookSource.exploreKindsJson()
+        if (json.isEmpty()) {
+            return
+        }
+        val kinds = GSONStrict.fromJsonArray<ExploreKind>(json).getOrNull()
+        if (kinds != null) {
+            return
+        }
+        GSON.fromJsonArray<ExploreKind>(json).getOrNull()?.let {
+            Debug.log("≡发现地址规则 JSON 格式不规范,请改为规范格式")
+        }
+    }
+
 }

+ 7 - 0
app/src/main/java/io/legado/app/utils/GsonExtensions.kt

@@ -7,6 +7,7 @@ import com.google.gson.JsonDeserializer
 import com.google.gson.JsonElement
 import com.google.gson.JsonParseException
 import com.google.gson.JsonSyntaxException
+import com.google.gson.Strictness
 import com.google.gson.ToNumberPolicy
 import com.google.gson.internal.LinkedTreeMap
 import com.google.gson.reflect.TypeToken
@@ -49,6 +50,12 @@ val GSON: Gson by lazy {
         .create()
 }
 
+val GSONStrict: Gson by lazy {
+    GSON.newBuilder()
+        .setStrictness(Strictness.STRICT)
+        .create()
+}
+
 inline fun <reified T> genericType(): Type = object : TypeToken<T>() {}.type
 
 inline fun <reified T> Gson.fromJsonObject(json: String?): Result<T> {