增强类型推断

增强类型推断
pull/1155/head
bushixuanqi 4 years ago committed by GitHub
parent 2eeba49b3d
commit 585d711b3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 120
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt

@ -415,25 +415,28 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
init { init {
rule = when { rule = when {
mode == Mode.Js || mode == Mode.Regex -> ruleStr mode == Mode.Js || mode == Mode.Regex -> ruleStr
ruleStr.startsWith("@CSS:", true) -> {
mode = Mode.Default
ruleStr
}
ruleStr.startsWith("@@") -> {
mode = Mode.Default
ruleStr.substring(2)
}
ruleStr.startsWith("@XPath:", true) -> { ruleStr.startsWith("@XPath:", true) -> {
mode = Mode.XPath mode = Mode.XPath
ruleStr.substring(7) ruleStr.substring(7)
} }
ruleStr.startsWith("@Json:", true) -> {
mode = Mode.Json
ruleStr.substring(6)
}
ruleStr.startsWith("@CSS:", true) -> {
ruleStr
}
ruleStr.startsWith("/") -> {//XPath特征很明显,无需配置单独的识别标头 ruleStr.startsWith("/") -> {//XPath特征很明显,无需配置单独的识别标头
mode = Mode.XPath mode = Mode.XPath
ruleStr ruleStr
} }
ruleStr.startsWith("@Json:", true) -> { ruleStr.length > 1 && ruleStr[0] in listOf('@','.',':','>','#','[') -> {
mode = Mode.Json //isJSON为真时,<js></js>之后可能不是jsonPath,故提前判断
ruleStr.substring(6) //XPath,Json,CSS三大前置已经提前判断了,故@开头即为默认规则,AnalyzeByJSoup会修剪开头的’@‘,故此处不必切片字符串
//#开头为根据id查元素,后续规则会切分##正则,故此处不必考虑##情况
//:开头为伪类,列表AllInOne已提前判断,此处是伪类无疑
mode = Mode.Default
ruleStr
} }
isJSON || ruleStr.startsWith("$.") || ruleStr.startsWith("$[") -> { isJSON || ruleStr.startsWith("$.") || ruleStr.startsWith("$[") -> {
mode = Mode.Json mode = Mode.Json
@ -441,6 +444,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
} }
else -> ruleStr else -> ruleStr
} }
//分离put //分离put
rule = splitPutRule(rule, putMap) rule = splitPutRule(rule, putMap)
//@get,{{ }}, 拆分 //@get,{{ }}, 拆分
@ -449,21 +453,14 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
val evalMatcher = evalPattern.matcher(rule) val evalMatcher = evalPattern.matcher(rule)
if (evalMatcher.find()) { if (evalMatcher.find()) {
if (mode != Mode.Js && mode != Mode.Regex val mMode = mode == Mode.Js || mode == Mode.Regex
&& evalMatcher.start() == 0 if(!mMode) { //首次匹配,start为0
) { if(evalMatcher.start() == 0 //仅首次匹配时evalMatcher.start()可能为0
mode = Mode.Regex ||!rule.substring(0, evalMatcher.start()).contains("##") //此处start为0
)mode = Mode.Regex
} }
do { do {
if (evalMatcher.start() > start) { if (evalMatcher.start() > start) splitRegex( rule.substring(start, evalMatcher.start()) )
tmp = rule.substring(start, evalMatcher.start())
if (mode != Mode.Js && mode != Mode.Regex
&& start == 0 && !tmp.contains("##")
) {
mode = Mode.Regex
}
splitRegex(tmp)
}
tmp = evalMatcher.group() tmp = evalMatcher.group()
when { when {
tmp.startsWith("@get:", true) -> { tmp.startsWith("@get:", true) -> {
@ -482,8 +479,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
} while (evalMatcher.find()) } while (evalMatcher.find())
} }
if (rule.length > start) { if (rule.length > start) {
tmp = rule.substring(start) splitRegex( rule.substring(start) )
splitRegex(tmp)
} }
} }
@ -522,48 +518,39 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
/** /**
* 替换@get,{{ }} * 替换@get,{{ }}
*/ */
fun makeUpRule(result: Any?) { fun makeUpRule(result: Any?) { //追加比插入快
val infoVal = StringBuilder() val infoVal = StringBuilder()
if (ruleParam.isNotEmpty()) { if (ruleParam.isNotEmpty()) {
var index = ruleParam.size for (index in 0 until ruleParam.size) {
while (index-- > 0) {
val regType = ruleType[index] val regType = ruleType[index]
when { when {
regType > defaultRuleType -> { regType > defaultRuleType -> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val resultList = result as? List<String?> (result as? List<String?>)?.run {
if (resultList != null) { if (this.size > regType) {
if (resultList.size > regType) { this[regType]?.let {
resultList[regType]?.let { infoVal.append(it)
infoVal.insert(0, resultList[regType])
} }
} }
} else { }?:infoVal.append(ruleParam[index])
infoVal.insert(0, ruleParam[index])
}
} }
regType == jsRuleType -> { regType == jsRuleType -> {
if (isRule(ruleParam[index])) { if (isRule(ruleParam[index])) {
getString(arrayListOf(SourceRule(ruleParam[index]))).let { infoVal.append( getString(arrayListOf(SourceRule(ruleParam[index]))) )
infoVal.insert(0, it)
}
} else { } else {
val jsEval: Any? = evalJS(ruleParam[index], result) evalJS(ruleParam[index], result)?.run{
when { infoVal.append(when(this){
jsEval == null -> Unit is String -> this
jsEval is String -> infoVal.insert(0, jsEval) this is Double && this % 1.0 == 0.0 -> String.format("%.0f", this)
jsEval is Double && jsEval % 1.0 == 0.0 -> infoVal.insert( else -> toString()
0, })
String.format("%.0f", jsEval)
)
else -> infoVal.insert(0, jsEval.toString())
} }
} }
} }
regType == getRuleType -> { regType == getRuleType -> {
infoVal.insert(0, get(ruleParam[index])) infoVal.append(get(ruleParam[index]))
} }
else -> infoVal.insert(0, ruleParam[index]) else -> infoVal.append(ruleParam[index])
} }
} }
rule = infoVal.toString() rule = infoVal.toString()
@ -620,18 +607,18 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
* 执行JS * 执行JS
*/ */
fun evalJS(jsStr: String, result: Any?): Any? { fun evalJS(jsStr: String, result: Any?): Any? {
val bindings = SimpleBindings() return SCRIPT_ENGINE.eval(jsStr, SimpleBindings().also{
bindings["java"] = this it["java"] = this
bindings["cookie"] = CookieStore it["cookie"] = CookieStore
bindings["cache"] = CacheManager it["cache"] = CacheManager
bindings["book"] = book it["book"] = book
bindings["result"] = result it["result"] = result
bindings["baseUrl"] = baseUrl it["baseUrl"] = baseUrl
bindings["chapter"] = chapter it["chapter"] = chapter
bindings["title"] = chapter?.title it["title"] = chapter?.title
bindings["src"] = content it["src"] = content
bindings["nextChapterUrl"] = nextChapterUrl it["nextChapterUrl"] = nextChapterUrl
return SCRIPT_ENGINE.eval(jsStr, bindings) })
} }
/** /**
@ -640,8 +627,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
override fun ajax(urlStr: String): String? { override fun ajax(urlStr: String): String? {
return runBlocking { return runBlocking {
kotlin.runCatching { kotlin.runCatching {
val analyzeUrl = AnalyzeUrl(urlStr, book = book) AnalyzeUrl(urlStr, book = book).getStrResponse(urlStr).body
analyzeUrl.getStrResponse(urlStr).body
}.onFailure { }.onFailure {
it.printStackTrace() it.printStackTrace()
}.getOrElse { }.getOrElse {
@ -657,7 +643,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
s ?: return null s ?: return null
val matcher = titleNumPattern.matcher(s) val matcher = titleNumPattern.matcher(s)
if (matcher.find()) { if (matcher.find()) {
return "${matcher.group(1)}${StringUtils.stringToInt(matcher.group(2))}${matcher.group(3)}" return "${StringUtils.stringToInt(matcher.group(1))}${matcher.group(2)}"
} }
return s return s
} }
@ -667,7 +653,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
private val evalPattern = private val evalPattern =
Pattern.compile("@get:\\{[^}]+?\\}|\\{\\{[\\w\\W]*?\\}\\}", Pattern.CASE_INSENSITIVE) Pattern.compile("@get:\\{[^}]+?\\}|\\{\\{[\\w\\W]*?\\}\\}", Pattern.CASE_INSENSITIVE)
private val regexPattern = Pattern.compile("\\$\\d{1,2}") private val regexPattern = Pattern.compile("\\$\\d{1,2}")
private val titleNumPattern = Pattern.compile("()(.+?)(章)") private val titleNumPattern = Pattern.compile("第(.+?)([节回话篇])")
} }
} }

Loading…
Cancel
Save