diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt index fb9c9c3b5..879d18b05 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt @@ -17,8 +17,6 @@ import java.util.* */ class AnalyzeByJSoup { - private val validKeys = listOf("class", "id", "tag", "text") - private var element: Element? = null fun parse(doc: Any): AnalyzeByJSoup { @@ -75,44 +73,58 @@ class AnalyzeByJSoup { return textS } //拆分规则 - val elementsType: String - val ruleStrS: Array - when { - ruleStr.contains("&&") -> { - elementsType = "&" - ruleStrS = ruleStr.splitNotBlank("&&") - } - ruleStr.contains("%%") -> { - elementsType = "%" - ruleStrS = ruleStr.splitNotBlank("%%") - } - else -> { - elementsType = "|" - ruleStrS = ruleStr.splitNotBlank("||") + val sourceRule = SourceRule(ruleStr) + if (isEmpty(sourceRule.elementsRule)) { + textS.add(element!!.data()) + } else { + val elementsType: String + val ruleStrS: Array + when { + sourceRule.elementsRule.contains("&&") -> { + elementsType = "&" + ruleStrS = sourceRule.elementsRule.splitNotBlank("&&") + } + sourceRule.elementsRule.contains("%%") -> { + elementsType = "%" + ruleStrS = sourceRule.elementsRule.splitNotBlank("%%") + } + else -> { + elementsType = "|" + ruleStrS = sourceRule.elementsRule.splitNotBlank("||") + } } - } - val results = ArrayList>() - for (ruleStrX in ruleStrS) { - val temp: List? = getResultList(ruleStrX) - if (temp != null && temp.isNotEmpty()) { - results.add(temp) - if (results.isNotEmpty() && elementsType == "|") { - break + val results = ArrayList>() + for (ruleStrX in ruleStrS) { + val temp: List? + temp = if (sourceRule.isCss) { + val lastIndex = ruleStrX.lastIndexOf('@') + getResultLast( + element!!.select(ruleStrX.substring(0, lastIndex)), + ruleStrX.substring(lastIndex + 1) + ) + } else { + getResultList(ruleStrX) + } + if (temp != null && temp.isNotEmpty()) { + results.add(temp) + if (results.isNotEmpty() && elementsType == "|") { + break + } } } - } - if (results.size > 0) { - if ("%" == elementsType) { - for (i in 0 until results[0].size) { - for (temp in results) { - if (i < temp.size) { - textS.add(temp[i]) + if (results.size > 0) { + if ("%" == elementsType) { + for (i in 0 until results[0].size) { + for (temp in results) { + if (i < temp.size) { + textS.add(temp[i]) + } } } - } - } else { - for (temp in results) { - textS.addAll(temp) + } else { + for (temp in results) { + textS.addAll(temp) + } } } } @@ -127,28 +139,39 @@ class AnalyzeByJSoup { if (temp == null || isEmpty(rule)) { return elements } + val sourceRule = SourceRule(rule) val elementsType: String val ruleStrS: Array when { - rule.contains("&&") -> { + sourceRule.elementsRule.contains("&&") -> { elementsType = "&" - ruleStrS = rule.splitNotBlank("&&") + ruleStrS = sourceRule.elementsRule.splitNotBlank("&&") } - rule.contains("%%") -> { + sourceRule.elementsRule.contains("%%") -> { elementsType = "%" - ruleStrS = rule.splitNotBlank("%%") + ruleStrS = sourceRule.elementsRule.splitNotBlank("%%") } else -> { elementsType = "|" - ruleStrS = rule.splitNotBlank("||") + ruleStrS = sourceRule.elementsRule.splitNotBlank("||") } } val elementsList = ArrayList() - for (ruleStr in ruleStrS) { - val tempS = getElementsSingle(temp, ruleStr) - elementsList.add(tempS) - if (tempS.size > 0 && elementsType == "|") { - break + if (sourceRule.isCss) { + for (ruleStr in ruleStrS) { + val tempS = temp.select(ruleStr) + elementsList.add(tempS) + if (tempS.size > 0 && elementsType == "|") { + break + } + } + } else { + for (ruleStr in ruleStrS) { + val tempS = getElementsSingle(temp, ruleStr) + elementsList.add(tempS) + if (tempS.size > 0 && elementsType == "|") { + break + } } } if (elementsList.size > 0) { @@ -206,19 +229,21 @@ class AnalyzeByJSoup { } } else { val rulePcx = rule.splitNotBlank("!") - val rulePc = rulePcx[0].trim { it <= ' ' }.splitNotBlank(">") - val rules = rulePc[0].trim { it <= ' ' }.splitNotBlank(".") + val rulePc = + rulePcx[0].trim { it <= ' ' }.splitNotBlank(">") + val rules = + rulePc[0].trim { it <= ' ' }.splitNotBlank(".") var filterRules: Array? = null var needFilterElements = rulePc.size > 1 && !isEmpty(rulePc[1].trim { it <= ' ' }) if (needFilterElements) { filterRules = rulePc[1].trim { it <= ' ' }.splitNotBlank(".") filterRules[0] = filterRules[0].trim { it <= ' ' } + val validKeys = listOf("class", "id", "tag", "text") if (filterRules.size < 2 || !validKeys.contains(filterRules[0]) || isEmpty(filterRules[1].trim { it <= ' ' })) { needFilterElements = false } filterRules[1] = filterRules[1].trim { it <= ' ' } } - var isCss = false when (rules[0]) { "children" -> { var children = temp.children() @@ -277,12 +302,9 @@ class AnalyzeByJSoup { elementsByText = filterElements(elementsByText, filterRules) elements.addAll(elementsByText) } - else -> { - elements.addAll(temp.select(rule)) - isCss = true - } + else -> elements.addAll(temp.select(rulePcx[0])) } - if (!isCss && rulePcx.size > 1) { + if (rulePcx.size > 1) { val rulePcs = rulePcx[1].splitNotBlank(":") for (pc in rulePcs) { val pcInt = Integer.parseInt(pc) @@ -364,4 +386,18 @@ class AnalyzeByJSoup { return textS } + internal inner class SourceRule(ruleStr: String) { + var isCss = false + var elementsRule: String + + init { + if (ruleStr.startsWith("@CSS:", true)) { + isCss = true + elementsRule = ruleStr.substring(5).trim { it <= ' ' } + } else { + elementsRule = ruleStr + } + } + } + } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 008ddef45..644c11c3f 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -123,10 +123,11 @@ class AnalyzeRule(private var book: BaseBook? = null) { if (rule.rule.isNotEmpty()) { when (rule.mode) { Mode.Js -> result = evalJS(rule.rule, result) - Mode.JSon -> result = getAnalyzeByJSonPath(it).getStringList(rule.rule) - Mode.XPath -> result = getAnalyzeByXPath(it).getStringList(rule.rule) - Mode.Css -> result = getAnalyzeByJSoup(it).getStringList(rule.rule) - else -> result = rule.rule + Mode.JSon -> result = + getAnalyzeByJSonPath(it).getStringList(rule.rule) + Mode.XPath -> result = + getAnalyzeByXPath(it).getStringList(rule.rule) + else -> result = getAnalyzeByJSoup(it).getStringList(rule.rule) } } if (rule.replaceRegex.isNotEmpty() && result is List<*>) { @@ -191,12 +192,11 @@ class AnalyzeRule(private var book: BaseBook? = null) { Mode.Js -> result = evalJS(rule.rule, it) Mode.JSon -> result = getAnalyzeByJSonPath(it).getString(rule.rule) Mode.XPath -> result = getAnalyzeByXPath(it).getString(rule.rule) - Mode.Css -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) { + Mode.Default -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) { getAnalyzeByJSoup(it).getString0(rule.rule) } else { getAnalyzeByJSoup(it).getString(rule.rule) } - else -> result = rule.rule } } if (rule.replaceRegex.isNotEmpty()) { @@ -230,8 +230,7 @@ class AnalyzeRule(private var book: BaseBook? = null) { Mode.Js -> result = evalJS(rule.rule, it) Mode.JSon -> result = getAnalyzeByJSonPath(it).getObject(rule.rule) Mode.XPath -> result = getAnalyzeByXPath(it).getElements(rule.rule) - Mode.Css -> result = getAnalyzeByJSoup(it).getElements(rule.rule) - else -> result = rule.rule + else -> result = getAnalyzeByJSoup(it).getElements(rule.rule) } if (rule.replaceRegex.isNotEmpty()) { result = replaceRegex(result.toString(), rule) @@ -261,8 +260,7 @@ class AnalyzeRule(private var book: BaseBook? = null) { } Mode.JSon -> result = getAnalyzeByJSonPath(it).getList(rule.rule) Mode.XPath -> result = getAnalyzeByXPath(it).getElements(rule.rule) - Mode.Css -> result = getAnalyzeByJSoup(it).getElements(rule.rule) - else -> result = rule.rule + else -> result = getAnalyzeByJSoup(it).getElements(rule.rule) } if (rule.replaceRegex.isNotEmpty()) { result = replaceRegex(result.toString(), rule) @@ -479,7 +477,7 @@ class AnalyzeRule(private var book: BaseBook? = null) { } enum class Mode { - XPath, JSon, Default, Js, Regex, Css + XPath, JSon, Default, Js } fun put(key: String, value: String): String {