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

@ -20,7 +20,7 @@ import javax.script.SimpleBindings
@Keep
class AnalyzeRule(private var book: BaseBook? = null) {
private var `object`: Any? = null
private var isJSON: Boolean? = false
private var isJSON: Boolean = false
private var baseUrl: String? = null
private var analyzeByXPath: AnalyzeByXPath? = null
@ -50,8 +50,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
/**
* 获取XPath解析类
*/
private fun getAnalyzeByXPath(o: Any?): AnalyzeByXPath {
return if (o != null) {
private fun getAnalyzeByXPath(o: Any): AnalyzeByXPath {
return if (o != `object`) {
AnalyzeByXPath().parse(o)
} else getAnalyzeByXPath()
}
@ -68,8 +68,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
/**
* 获取JSOUP解析类
*/
private fun getAnalyzeByJSoup(o: Any?): AnalyzeByJSoup {
return if (o != null) {
private fun getAnalyzeByJSoup(o: Any): AnalyzeByJSoup {
return if (o != `object`) {
AnalyzeByJSoup().parse(o)
} else getAnalyzeByJSoup()
}
@ -86,8 +86,8 @@ class AnalyzeRule(private var book: BaseBook? = null) {
/**
* 获取JSON解析类
*/
private fun getAnalyzeByJSonPath(o: Any?): AnalyzeByJSonPath {
return if (o != null) {
private fun getAnalyzeByJSonPath(o: Any): AnalyzeByJSonPath {
return if (o != `object`) {
AnalyzeByJSonPath().parse(o)
} else getAnalyzeByJSonPath()
}
@ -116,15 +116,32 @@ class AnalyzeRule(private var book: BaseBook? = null) {
@Throws(Exception::class)
fun getStringList(ruleList: List<SourceRule>, isUrl: Boolean): List<String>? {
var result: Any? = null
`object`?.let { o ->
if (ruleList.isNotEmpty()) {
if (ruleList.isNotEmpty()) result = o
for (rule in ruleList) {
result?.let {
if (rule.rule.isNotEmpty()) {
when (rule.mode) {
Mode.Js -> {
if (result == null) result = `object`
result = evalJS(rule.rule, result)
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()
@ -167,19 +184,24 @@ class AnalyzeRule(private var book: BaseBook? = null) {
@JvmOverloads
fun getString(ruleList: List<SourceRule>, isUrl: Boolean = false): String {
var result: Any? = null
`object`?.let { o ->
if (ruleList.isNotEmpty()) result = o
for (rule in ruleList) {
result?.let {
if (rule.rule.isNotBlank()) {
when (rule.mode) {
Mode.Js -> {
if (result == null) result = `object`
result = evalJS(rule.rule, result)
}
Mode.JSon -> result = getAnalyzeByJSonPath(result).getString(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(result).getString(rule.rule)
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(result).getString0(rule.rule)
getAnalyzeByJSoup(it).getString0(rule.rule)
} else {
getAnalyzeByJSoup(result).getString(rule.rule)
getAnalyzeByJSoup(it).getString(rule.rule)
}
}
}
if (rule.replaceRegex.isNotEmpty()) {
result = replaceRegex(result.toString(), rule)
}
}
}
@ -201,15 +223,20 @@ class AnalyzeRule(private var book: BaseBook? = null) {
if (TextUtils.isEmpty(ruleStr)) return null
var result: Any? = null
val ruleList = splitSourceRule(ruleStr)
`object`?.let { o ->
if (ruleList.isNotEmpty()) result = o
for (rule in ruleList) {
result?.let {
when (rule.mode) {
Mode.Js -> {
if (result == null) result = `object`
result = evalJS(rule.rule, result)
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
@ -223,15 +250,23 @@ class AnalyzeRule(private var book: BaseBook? = null) {
fun getElements(ruleStr: String): List<Any> {
var result: Any? = null
val ruleList = splitSourceRule(ruleStr)
`object`?.let { o ->
if (ruleList.isNotEmpty()) result = o
for (rule in ruleList) {
result?.let {
when (rule.mode) {
Mode.Js -> {
if (result == null) result = `object`
result = evalJS(rule.rule, result)
}
Mode.JSon -> result = getAnalyzeByJSonPath(result).getList(rule.rule)
Mode.XPath -> result = getAnalyzeByXPath(result).getElements(rule.rule)
else -> result = getAnalyzeByJSoup(result).getElements(rule.rule)
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)
}
}
}
}
result?.let {
@ -240,6 +275,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
return ArrayList()
}
/**
* 保存变量
*/
@ -283,6 +319,27 @@ class AnalyzeRule(private var book: BaseBook? = null) {
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
*/
@ -329,7 +386,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
mode = Mode.JSon
vRuleStr = vRuleStr.substring(6)
}
else -> mode = if (isJSON!!) {
else -> mode = if (isJSON) {
Mode.JSon
} else {
Mode.Default
@ -370,14 +427,17 @@ class AnalyzeRule(private var book: BaseBook? = null) {
inner class SourceRule internal constructor(ruleStr: String, mainMode: Mode) {
internal var mode: Mode
internal var rule: String
internal var replaceRegex = ""
internal var replacement = ""
internal var replaceFirst = false
init {
this.mode = mainMode
if (mode == Mode.Js) {
if (ruleStr.startsWith("<js>")) {
rule = ruleStr.substring(4, ruleStr.lastIndexOf("<"))
rule = if (ruleStr.startsWith("<js>")) {
ruleStr.substring(4, ruleStr.lastIndexOf("<"))
} else {
rule = ruleStr.substring(4)
ruleStr.substring(4)
}
} else {
when {
@ -400,6 +460,20 @@ class AnalyzeRule(private var book: BaseBook? = null) {
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