优化链接分割规则,避免附加参数中存在 ,{ 时导致规则切错

修复<str0,str2,...{{js}}>这种页数列表写法中,js部分内含 < 或 > 会切割错误的问题

格式化图片和匹配图片规则不在使用同一个正则,加快图片处理速度。

优化一下不需要循环执行却被循环执行的操作
pull/1123/head
bushixuanqi 3 years ago
parent 3ad75d0443
commit 97ac253f5f
  1. 9
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  2. 25
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  3. 7
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt
  4. 7
      app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt
  5. 6
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  6. 6
      app/src/main/java/io/legado/app/utils/HtmlFormatter.kt

@ -62,12 +62,9 @@ data class BookChapter(
} }
fun getAbsoluteURL():String{ fun getAbsoluteURL():String{
val pos = url.indexOf(',') val urlBefore = url.substringBefore(",{")
return if(pos == -1) NetworkUtils.getAbsoluteURL(baseUrl,url) val urlAbsoluteBefore = NetworkUtils.getAbsoluteURL(baseUrl,urlBefore)
else NetworkUtils.getAbsoluteURL( return if(urlBefore.length == url.length) urlAbsoluteBefore else urlAbsoluteBefore + url.substring(urlBefore.length)
baseUrl,
url.substring(0, pos)
) + url.substring(pos)
} }
fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title)) fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title))

@ -48,6 +48,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
fun setContent(content: Any?, baseUrl: String? = null): AnalyzeRule { fun setContent(content: Any?, baseUrl: String? = null): AnalyzeRule {
if (content == null) throw AssertionError("内容不可空(Content cannot be null)") if (content == null) throw AssertionError("内容不可空(Content cannot be null)")
this.content = content this.content = content
isJSON = content.toString().isJson()
setBaseUrl(baseUrl) setBaseUrl(baseUrl)
objectChangedXP = true objectChangedXP = true
objectChangedJS = true objectChangedJS = true
@ -64,8 +65,7 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
fun setRedirectUrl(url: String): URL? { fun setRedirectUrl(url: String): URL? {
kotlin.runCatching { kotlin.runCatching {
val pos = url.indexOf(',') redirectUrl = URL(url.substringBefore(",{"))
redirectUrl = URL( if(pos == -1) url else url.substring(0,pos))
} }
return redirectUrl return redirectUrl
} }
@ -378,12 +378,12 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
mMode = Mode.Json mMode = Mode.Json
ruleStr0.substring(6) ruleStr0.substring(6)
} }
ruleStr0.startsWith(":") -> { //:与伪类选择器冲突,改成?更合理 ruleStr0.startsWith(":") -> { //:与伪类选择器冲突,建议改成?更合理
mMode = Mode.Regex mMode = Mode.Regex
isRegex = true isRegex = true
ruleStr0.substring(1) ruleStr0.substring(1)
} }
( ruleStr0[1] == '.' || ruleStr0[1] == '[') && ruleStr0[0] == '$' || content.toString().isJson() -> { ( ruleStr0[1] == '.' || ruleStr0[1] == '[') && ruleStr0[0] == '$' || isJSON -> {
mMode = Mode.Json mMode = Mode.Json
ruleStr0 ruleStr0
} }
@ -596,15 +596,14 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
} }
private fun isRule(ruleStr: String): Boolean { private fun isRule(ruleStr: String): Boolean {
return when { return ruleStr.startsWith('@') //js首个字符不可能是@,除非是装饰器,所以@开头规定为规则
ruleStr.startsWith("$.") -> true || ruleStr.startsWith('$') //js首个字符不可能是$,因为并未注入$变量,且$1之类的东西已被替换,不会影响此处判断
ruleStr.startsWith("@Json:", true) -> true || ruleStr.startsWith("//")
ruleStr.startsWith("//") -> true || ruleStr.startsWith("class")//js首个字符串不可能是class,因为并未注入相关字符串开头的变量
ruleStr.startsWith("@XPath:", true) -> true || ruleStr.startsWith("id")//js首个字符串不可能是id,因为并未注入相关字符串开头的变量
ruleStr.startsWith("@CSS:", true) -> true || ruleStr.startsWith("tag")//js首个字符串不可能是tag,因为并未注入相关字符串开头的变量
ruleStr.startsWith("@@") -> true || ruleStr.startsWith("text")//js首个字符串不可能是text,因为并未注入相关字符串开头的变量
else -> false || ruleStr.startsWith("children")//js首个字符串不可能是children,因为并未注入相关字符串开头的变量
}
} }
} }

@ -55,8 +55,7 @@ class AnalyzeUrl(
private var retry: Int = 0 private var retry: Int = 0
init { init {
val pos = baseUrl.indexOf(',') baseUrl = baseUrl.substringBefore(",{")
if(pos != -1)baseUrl = baseUrl.substring(0,pos)
headerMapF?.let { headerMapF?.let {
headerMap.putAll(it) headerMap.putAll(it)
if (it.containsKey("proxy")) { if (it.containsKey("proxy")) {
@ -141,11 +140,11 @@ class AnalyzeUrl(
/** /**
* 处理URL * 处理URL
*/ */
private fun initUrl() { private fun initUrl() { //前面已经替换掉所有额外内容,此处url是基础形式,可以直接切首个‘,’之前字符串
var pos = ruleUrl.indexOf(',') var pos = ruleUrl.indexOf(',')
urlHasQuery = if(pos == -1) ruleUrl else ruleUrl.substring(0,pos) urlHasQuery = ruleUrl.substringBefore(',')
url = NetworkUtils.getAbsoluteURL(baseUrl,urlHasQuery ) url = NetworkUtils.getAbsoluteURL(baseUrl,urlHasQuery )

@ -391,12 +391,15 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
}.toString() }.toString()
} }
//-----------此处向下的函数和变量都未被使用,但以后要用--------
val ruleTypeList = ArrayList<String>() val ruleTypeList = ArrayList<String>()
//设置平衡组函数,json或JavaScript时设置成chompCodeBalanced,否则为chompRuleBalanced //设置平衡组函数,json或JavaScript时设置成chompCodeBalanced,否则为chompRuleBalanced
val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced
enum class Mode { enum class Mode {
XPath, Json, Default, Js, Regex XPath, Json, Default, Js, Regex
} }
/** /**
* 不用正则,不到最后不切片也不用中间变量存储,只在序列中标记当前查找字段的开头结尾,到返回时才切片,高效快速准确切割规则 * 不用正则,不到最后不切片也不用中间变量存储,只在序列中标记当前查找字段的开头结尾,到返回时才切片,高效快速准确切割规则
* 解决jsonPath自带的"&&""||"与阅读的规则冲突,以及规则正则或字符串中包含"&&""||""%%""@"导致的冲突 * 解决jsonPath自带的"&&""||"与阅读的规则冲突,以及规则正则或字符串中包含"&&""||""%%""@"导致的冲突
@ -515,7 +518,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
isUrlList = true isUrlList = true
} }
else -> { else -> {
isJSON = queue.toString().isJson() isJSON = queue.isJson()
} }
} }
@ -553,7 +556,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
private val STARTSTR = arrayOf("@js:","<js>","</js>","##","@@","@" private val STARTSTR = arrayOf("@js:","<js>","</js>","##","@@","@"
,"{{@", "{{","}}" ,"{{@", "{{","}}"
,"}" ,"}"
, "{@", "{/", "{$", "{?" , "{@", "{/", "{$"
, "{class" , "{class"
, "{id" , "{id"
, "{tag" , "{tag"

@ -12,7 +12,6 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.ui.book.read.page.entities.TextChapter
import io.legado.app.ui.book.read.page.entities.TextChar import io.legado.app.ui.book.read.page.entities.TextChar
import io.legado.app.ui.book.read.page.entities.TextLine import io.legado.app.ui.book.read.page.entities.TextLine
@ -147,10 +146,7 @@ object ChapterProvider {
return TextChapter( return TextChapter(
bookChapter.index, bookChapter.title, bookChapter.index, bookChapter.title,
bookChapter.getAbsoluteURL().run{ bookChapter.getAbsoluteURL().substringBefore(",{"),
val pos = indexOf(',')
if(pos == -1) this else substring(0,pos)
},
textPages, chapterSize textPages, chapterSize
) )
} }

@ -13,7 +13,7 @@ object HtmlFormatter {
return html.replace(wrapHtmlRegex, "\n") return html.replace(wrapHtmlRegex, "\n")
.replace(otherRegex, "") .replace(otherRegex, "")
.replace("\\s*\\n+\\s*".toRegex(), "\n  ") .replace("\\s*\\n+\\s*".toRegex(), "\n  ")
.replace("^[\\n\\s]*".toRegex(), "  ") .replace("^[\\n\\s]+".toRegex(), "  ")
.replace("[\\n\\s]+$".toRegex(), "") .replace("[\\n\\s]+$".toRegex(), "")
} }
@ -26,7 +26,7 @@ object HtmlFormatter {
.replace("[\\n\\s]+\$|^[\\n\\s]*".toRegex(), "") .replace("[\\n\\s]+\$|^[\\n\\s]*".toRegex(), "")
.replace("\\s*\\n+\\s*".toRegex(), "\n") .replace("\\s*\\n+\\s*".toRegex(), "\n")
val sb = StringBuffer("  ") //前置缩减 val sb = StringBuffer()
val hasDataType:Boolean //是否有数据属性 val hasDataType:Boolean //是否有数据属性
//图片有data-开头的数据属性时优先用数据属性作为src,没有数据属性时匹配src //图片有data-开头的数据属性时优先用数据属性作为src,没有数据属性时匹配src
@ -48,7 +48,7 @@ object HtmlFormatter {
if(hasDataType || matcher.group(1)!!.indexOf(',') == -1) { //图片无参 if(hasDataType || matcher.group(1)!!.indexOf(',') == -1) { //图片无参
do{ do{
sb.append(keepImgHtml.substring(appendPos, matcher.start()).replace("\n","\n  ")) //非图片部分换行缩 sb.append(keepImgHtml.substring(appendPos, matcher.start()).replace("\n","\n  ")) //非图片部分换行缩
sb.append( "<img src=\"${ sb.append( "<img src=\"${
NetworkUtils.getAbsoluteURL(redirectUrl,matcher.group(1)!!) NetworkUtils.getAbsoluteURL(redirectUrl,matcher.group(1)!!)
}\">" ) }\">" )

Loading…
Cancel
Save