Merge remote-tracking branch 'origin/master'

pull/32/head
Administrator 6 years ago
commit 9dd651e36a
  1. 23
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt
  2. 184
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  3. 7
      app/src/main/java/io/legado/app/model/book/BookList.kt
  4. 6
      app/src/main/java/io/legado/app/utils/FileUtils.kt

@ -133,16 +133,6 @@ class AnalyzeByJSoup {
} }
} }
} }
if (!isEmpty(sourceRule.replaceRegex)) {
val tempList = ArrayList(textS)
textS.clear()
for (text in tempList) {
val tmpText = text.replace(sourceRule.replaceRegex.toRegex(), sourceRule.replacement)
if (tmpText.isNotEmpty()) {
textS.add(tmpText)
}
}
}
return textS return textS
} }
@ -409,24 +399,13 @@ class AnalyzeByJSoup {
internal inner class SourceRule(ruleStr: String) { internal inner class SourceRule(ruleStr: String) {
var isCss = false var isCss = false
var elementsRule: String var elementsRule: String
var replaceRegex = ""
var replacement = ""
init { init {
if (ruleStr.startsWith("@CSS:", true)) { if (ruleStr.startsWith("@CSS:", true)) {
isCss = true isCss = true
elementsRule = ruleStr.substring(5).trim { it <= ' ' } elementsRule = ruleStr.substring(5).trim { it <= ' ' }
} else { } else {
val ruleStrS: Array<String> = elementsRule = ruleStr
ruleStr.trim { it <= ' ' }.split("#".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
//分离正则表达式
elementsRule = ruleStrS[0]
if (ruleStrS.size > 1) {
replaceRegex = ruleStrS[1]
}
if (ruleStrS.size > 2) {
replacement = ruleStrS[2]
}
} }
} }
} }

@ -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
@ -36,7 +36,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
} }
@JvmOverloads @JvmOverloads
fun setContent(body: Any?, baseUrl: String? = null): AnalyzeRule { fun setContent(body: Any?, baseUrl: String? = this.baseUrl): AnalyzeRule {
if (body == null) throw AssertionError("Content cannot be null") if (body == null) throw AssertionError("Content cannot be null")
isJSON = body.toString().isJson() isJSON = body.toString().isJson()
`object` = body `object` = body
@ -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,34 +116,53 @@ 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()
if (result is String) { if (result is String) {
result = Arrays.asList((result as String?)?.htmlFormat()?.split("\n")) result = listOf((result as String?)?.htmlFormat()?.split("\n"))
} }
baseUrl?.let { baseUrl?.let {
if (isUrl && !TextUtils.isEmpty(it)) { if (isUrl && !TextUtils.isEmpty(it)) {
val urlList = ArrayList<String>() val urlList = ArrayList<String>()
for (url in (result as List<String>?)!!) { if (result is List<*>) {
val absoluteURL = NetworkUtils.getAbsoluteURL(it, url) for (url in result) {
if (!urlList.contains(absoluteURL)) { val absoluteURL = NetworkUtils.getAbsoluteURL(it, url.toString())
urlList.add(absoluteURL) if (!urlList.contains(absoluteURL)) {
urlList.add(absoluteURL)
}
} }
} }
return urlList return urlList
} }
} }
return result as List<String>? return result as? List<String>
} }
/** /**
@ -165,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)
} }
} }
} }
@ -199,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
@ -221,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 {
@ -238,6 +275,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
return ArrayList() return ArrayList()
} }
/** /**
* 保存变量 * 保存变量
*/ */
@ -281,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
*/ */
@ -327,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
@ -368,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 {
@ -398,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
}
} }
} }

@ -1,5 +1,12 @@
package io.legado.app.model.book package io.legado.app.model.book
import io.legado.app.data.entities.SearchBook
class BookList { class BookList {
fun analyzeBookList(): ArrayList<SearchBook> {
var bookList = ArrayList<SearchBook>()
return bookList
}
} }

@ -1,10 +1,8 @@
package io.legado.app.utils package io.legado.app.utils
import android.annotation.TargetApi
import android.content.ContentUris import android.content.ContentUris
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Environment import android.os.Environment
import android.os.storage.StorageManager import android.os.storage.StorageManager
import android.provider.DocumentsContract import android.provider.DocumentsContract
@ -171,8 +169,8 @@ object FileUtils {
selection, selection,
selectionArgs, selectionArgs,
null null
)!!.use { cursor -> )?.use { cursor ->
if (cursor != null && cursor.moveToFirst()) { if (cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(column) val index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(index) return cursor.getString(index)
} }

Loading…
Cancel
Save