pull/32/head
kunfei 5 years ago
parent 08867d1fa5
commit 55c5606f1b
  1. 168
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt

@ -20,7 +20,7 @@ import javax.script.SimpleBindings
@Keep @Keep
class AnalyzeRule(private var book: BaseBook? = null) { class AnalyzeRule(private var book: BaseBook? = null) {
private var `object`: Any? = null private var `object`: Any? = null
private var isJSON: Boolean? = false private var isJSON: Boolean = false
private var baseUrl: String? = null private var baseUrl: String? = null
private var analyzeByXPath: AnalyzeByXPath? = null private var analyzeByXPath: AnalyzeByXPath? = null
@ -50,8 +50,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
/** /**
* 获取XPath解析类 * 获取XPath解析类
*/ */
private fun getAnalyzeByXPath(o: Any?): AnalyzeByXPath { private fun getAnalyzeByXPath(o: Any): AnalyzeByXPath {
return if (o != null) { return if (o != `object`) {
AnalyzeByXPath().parse(o) AnalyzeByXPath().parse(o)
} else getAnalyzeByXPath() } else getAnalyzeByXPath()
} }
@ -68,8 +68,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
/** /**
* 获取JSOUP解析类 * 获取JSOUP解析类
*/ */
private fun getAnalyzeByJSoup(o: Any?): AnalyzeByJSoup { private fun getAnalyzeByJSoup(o: Any): AnalyzeByJSoup {
return if (o != null) { return if (o != `object`) {
AnalyzeByJSoup().parse(o) AnalyzeByJSoup().parse(o)
} else getAnalyzeByJSoup() } else getAnalyzeByJSoup()
} }
@ -86,8 +86,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
/** /**
* 获取JSON解析类 * 获取JSON解析类
*/ */
private fun getAnalyzeByJSonPath(o: Any?): AnalyzeByJSonPath { private fun getAnalyzeByJSonPath(o: Any): AnalyzeByJSonPath {
return if (o != null) { return if (o != `object`) {
AnalyzeByJSonPath().parse(o) AnalyzeByJSonPath().parse(o)
} else getAnalyzeByJSonPath() } else getAnalyzeByJSonPath()
} }
@ -116,15 +116,32 @@ class AnalyzeRule(private var book: BaseBook? = null) {
@Throws(Exception::class) @Throws(Exception::class)
fun getStringList(ruleList: List<SourceRule>, isUrl: Boolean): List<String>? { fun getStringList(ruleList: List<SourceRule>, isUrl: Boolean): List<String>? {
var result: Any? = null var result: Any? = null
for (rule in ruleList) { `object`?.let { o ->
when (rule.mode) { if (ruleList.isNotEmpty()) {
Mode.Js -> { if (ruleList.isNotEmpty()) result = o
if (result == null) result = `object` for (rule in ruleList) {
result = evalJS(rule.rule, result) result?.let {
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)
else -> result = getAnalyzeByJSoup(it).getStringList(rule.rule)
}
}
if (rule.replaceRegex.isNotEmpty() && result is List<*>) {
val newList = ArrayList<String>()
for (item in result as List<*>) {
newList.add(replaceRegex(item.toString(), rule))
}
result = newList
} else if (rule.replaceRegex.isNotEmpty()) {
result = replaceRegex(result.toString(), rule)
}
}
} }
Mode.JSon -> result = getAnalyzeByJSonPath(result).getStringList(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(result).getStringList(rule.rule)
else -> result = getAnalyzeByJSoup(result).getStringList(rule.rule)
} }
} }
if (result == null) return ArrayList() if (result == null) return ArrayList()
@ -167,19 +184,24 @@ class AnalyzeRule(private var book: BaseBook? = null) {
@JvmOverloads @JvmOverloads
fun getString(ruleList: List<SourceRule>, isUrl: Boolean = false): String { fun getString(ruleList: List<SourceRule>, isUrl: Boolean = false): String {
var result: Any? = null var result: Any? = null
for (rule in ruleList) { `object`?.let { o ->
if (rule.rule.isNotBlank()) { if (ruleList.isNotEmpty()) result = o
when (rule.mode) { for (rule in ruleList) {
Mode.Js -> { result?.let {
if (result == null) result = `object` if (rule.rule.isNotBlank()) {
result = evalJS(rule.rule, result) when (rule.mode) {
Mode.Js -> result = evalJS(rule.rule, it)
Mode.JSon -> result = getAnalyzeByJSonPath(it).getString(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(it).getString(rule.rule)
Mode.Default -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) {
getAnalyzeByJSoup(it).getString0(rule.rule)
} else {
getAnalyzeByJSoup(it).getString(rule.rule)
}
}
} }
Mode.JSon -> result = getAnalyzeByJSonPath(result).getString(rule.rule) if (rule.replaceRegex.isNotEmpty()) {
Mode.XPath -> result = getAnalyzeByXPath(result).getString(rule.rule) result = replaceRegex(result.toString(), rule)
Mode.Default -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) {
getAnalyzeByJSoup(result).getString0(rule.rule)
} else {
getAnalyzeByJSoup(result).getString(rule.rule)
} }
} }
} }
@ -201,15 +223,20 @@ class AnalyzeRule(private var book: BaseBook? = null) {
if (TextUtils.isEmpty(ruleStr)) return null if (TextUtils.isEmpty(ruleStr)) return null
var result: Any? = null var result: Any? = null
val ruleList = splitSourceRule(ruleStr) val ruleList = splitSourceRule(ruleStr)
for (rule in ruleList) { `object`?.let { o ->
when (rule.mode) { if (ruleList.isNotEmpty()) result = o
Mode.Js -> { for (rule in ruleList) {
if (result == null) result = `object` result?.let {
result = evalJS(rule.rule, result) when (rule.mode) {
Mode.Js -> result = evalJS(rule.rule, it)
Mode.JSon -> result = getAnalyzeByJSonPath(it).getObject(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(it).getElements(rule.rule)
else -> result = getAnalyzeByJSoup(it).getElements(rule.rule)
}
if (rule.replaceRegex.isNotEmpty()) {
result = replaceRegex(result.toString(), rule)
}
} }
Mode.JSon -> result = getAnalyzeByJSonPath(result).getObject(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(result).getElements(rule.rule)
else -> result = getAnalyzeByJSoup(result).getElements(rule.rule)
} }
} }
return result return result
@ -223,15 +250,23 @@ class AnalyzeRule(private var book: BaseBook? = null) {
fun getElements(ruleStr: String): List<Any> { fun getElements(ruleStr: String): List<Any> {
var result: Any? = null var result: Any? = null
val ruleList = splitSourceRule(ruleStr) val ruleList = splitSourceRule(ruleStr)
for (rule in ruleList) { `object`?.let { o ->
when (rule.mode) { if (ruleList.isNotEmpty()) result = o
Mode.Js -> { for (rule in ruleList) {
if (result == null) result = `object` result?.let {
result = evalJS(rule.rule, result) when (rule.mode) {
Mode.Js -> {
if (result == null) result = `object`
result = evalJS(rule.rule, result)
}
Mode.JSon -> result = getAnalyzeByJSonPath(it).getList(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(it).getElements(rule.rule)
else -> result = getAnalyzeByJSoup(it).getElements(rule.rule)
}
if (rule.replaceRegex.isNotEmpty()) {
result = replaceRegex(result.toString(), rule)
}
} }
Mode.JSon -> result = getAnalyzeByJSonPath(result).getList(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(result).getElements(rule.rule)
else -> result = getAnalyzeByJSoup(result).getElements(rule.rule)
} }
} }
result?.let { result?.let {
@ -240,6 +275,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
return ArrayList() return ArrayList()
} }
/** /**
* 保存变量 * 保存变量
*/ */
@ -283,6 +319,27 @@ class AnalyzeRule(private var book: BaseBook? = null) {
return vRuleStr return vRuleStr
} }
/**
* 正则替换
*/
private fun replaceRegex(result: String, rule: SourceRule): String {
var result = result
if (rule.replaceRegex.isNotEmpty()) {
result = if (rule.replaceFirst) {
val pattern = Pattern.compile(rule.replaceRegex)
val matcher = pattern.matcher(result)
if (matcher.find()) {
matcher.group(0).replaceFirst(rule.replaceRegex.toRegex(), rule.replacement)
} else {
""
}
} else {
result.replace(rule.replaceRegex.toRegex(), rule.replacement)
}
}
return result
}
/** /**
* 替换JS * 替换JS
*/ */
@ -329,7 +386,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
mode = Mode.JSon mode = Mode.JSon
vRuleStr = vRuleStr.substring(6) vRuleStr = vRuleStr.substring(6)
} }
else -> mode = if (isJSON!!) { else -> mode = if (isJSON) {
Mode.JSon Mode.JSon
} else { } else {
Mode.Default Mode.Default
@ -370,14 +427,17 @@ class AnalyzeRule(private var book: BaseBook? = null) {
inner class SourceRule internal constructor(ruleStr: String, mainMode: Mode) { inner class SourceRule internal constructor(ruleStr: String, mainMode: Mode) {
internal var mode: Mode internal var mode: Mode
internal var rule: String internal var rule: String
internal var replaceRegex = ""
internal var replacement = ""
internal var replaceFirst = false
init { init {
this.mode = mainMode this.mode = mainMode
if (mode == Mode.Js) { if (mode == Mode.Js) {
if (ruleStr.startsWith("<js>")) { rule = if (ruleStr.startsWith("<js>")) {
rule = ruleStr.substring(4, ruleStr.lastIndexOf("<")) ruleStr.substring(4, ruleStr.lastIndexOf("<"))
} else { } else {
rule = ruleStr.substring(4) ruleStr.substring(4)
} }
} else { } else {
when { when {
@ -400,6 +460,20 @@ class AnalyzeRule(private var book: BaseBook? = null) {
else -> rule = ruleStr else -> rule = ruleStr
} }
} }
//分离正则表达式
val ruleStrS =
rule.trim { it <= ' ' }.split("##".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()
rule = ruleStrS[0]
if (ruleStrS.size > 1) {
replaceRegex = ruleStrS[1]
}
if (ruleStrS.size > 2) {
replacement = ruleStrS[2]
}
if (ruleStrS.size > 3) {
replaceFirst = true
}
} }
} }

Loading…
Cancel
Save