pull/1127/head
bushixuanqi 3 years ago
parent f0e5fa94c0
commit ef24a4d036
  1. 6
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  2. 3
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  3. 10
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt
  4. 2
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  5. 74
      app/src/main/java/io/legado/app/utils/HtmlFormatter.kt

@ -5,6 +5,7 @@ import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Ignore
import androidx.room.Index
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.GSON
import io.legado.app.utils.MD5Utils
import io.legado.app.utils.NetworkUtils
@ -62,9 +63,10 @@ data class BookChapter(
}
fun getAbsoluteURL():String{
val urlBefore = url.substringBefore(',')
val urlMatcher = AnalyzeUrl.paramPattern.matcher(url)
val urlBefore = if(urlMatcher.find())url.substring(0,urlMatcher.start()) else url
val urlAbsoluteBefore = NetworkUtils.getAbsoluteURL(baseUrl,urlBefore)
return if(urlBefore.length == url.length) urlAbsoluteBefore else urlAbsoluteBefore + url.substring(urlBefore.length)
return if(urlBefore.length == url.length) urlAbsoluteBefore else urlAbsoluteBefore + url.substring(urlMatcher.end())
}
fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title))

@ -65,7 +65,8 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
fun setRedirectUrl(url: String): URL? {
kotlin.runCatching {
redirectUrl = URL(url.substringBefore(','))
val urlMatcher = AnalyzeUrl.paramPattern.matcher(url)
redirectUrl = URL( if(urlMatcher.find())url.substring(0,urlMatcher.start()) else url)
}
return redirectUrl
}

@ -39,6 +39,7 @@ class AnalyzeUrl(
headerMapF: Map<String, String>? = null
) : JsExtensions {
companion object {
val paramPattern = Pattern.compile("\\s*,\\s*(?=\\{)")
private val pagePattern = Pattern.compile("<(.*?)>")
}
@ -55,7 +56,8 @@ class AnalyzeUrl(
private var retry: Int = 0
init {
baseUrl = baseUrl.substringBefore(',')
val urlMatcher = paramPattern.matcher(baseUrl)
if(urlMatcher.find())baseUrl = baseUrl.substring(0,urlMatcher.start())
headerMapF?.let {
headerMap.putAll(it)
if (it.containsKey("proxy")) {
@ -142,14 +144,14 @@ class AnalyzeUrl(
*/
private fun initUrl() { //replaceKeyPageJs已经替换掉额外内容,此处url是基础形式,可以直接切首个‘,’之前字符串。
urlHasQuery = ruleUrl.substringBefore(',')
val urlMatcher = paramPattern.matcher(ruleUrl)
urlHasQuery = if(urlMatcher.find())ruleUrl.substring(0,urlMatcher.start()) else ruleUrl
url = NetworkUtils.getAbsoluteURL(baseUrl,urlHasQuery )
NetworkUtils.getBaseUrl(url)?.let {
baseUrl = it
}
if(urlHasQuery.length != ruleUrl.length ) {
GSON.fromJsonObject<UrlOption>(ruleUrl.substring(urlHasQuery.length + 1).trim{ it < '!'})?.let { option ->
GSON.fromJsonObject<UrlOption>(ruleUrl.substring(urlMatcher.end()))?.let { option ->
option.method?.let {
if (it.equals("POST", true)) method = RequestMethod.POST

@ -146,7 +146,7 @@ object ChapterProvider {
return TextChapter(
bookChapter.index, bookChapter.title,
bookChapter.getAbsoluteURL().substringBefore(','),
bookChapter.getAbsoluteURL().substringBefore(",{"), //getAbsoluteURL已经格式过
textPages, chapterSize
)
}

@ -1,5 +1,6 @@
package io.legado.app.utils
import io.legado.app.model.analyzeRule.AnalyzeUrl
import java.net.URL
import java.util.regex.Pattern
@ -26,35 +27,68 @@ object HtmlFormatter {
.replace("[\\n\\s]+\$|^[\\n\\s]+".toRegex(), "")
.replace("\\s*\\n+\\s*".toRegex(), "\n")
val sb = StringBuffer()
var str = ""
var endPos = 0
for(pattern in listOf("<img[^>]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>","<img[^>]*data-[^=]*= *\"([^\"])\"[^>]*>")){
var hasMatch = true //普通图片标签是否还未处理过
var hasMatchX = false //是否存在带参数或带数据属性的图片标签
var pos = -1
val list = listOf("<img[^>]*src *= *\"([^\"{]+\\{(?:[^{}]|\\{[^}]+})+})\"[^>]*>","<img[^>]*data-[^=]*= *\"([^\"]+)\"[^>]*>","<img[^>]*src *= *\"([^\"]+)\"[^>]*>") //优先匹配用户处理过所以带参数的图片标签,其次匹配带数据属性的图片标签
while(++pos<3){
if(pos == 2) {
if(hasMatchX)break //普通图片标签只在不存在存在带参数或带数据属性的图片标签的时候匹配
else hasMatch = false //匹配带参数或带数据属性的图片标签同时也会格式化普通图片标签
}
var appendPos = 0
val matcher = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(keepImgHtml)
while (matcher.find()) {
val url = matcher.group(1)!!
val urlBefore = url.substringBefore(',')
val strBefore = keepImgHtml.substring(appendPos, matcher.start())
val matcher =
Pattern.compile(list[pos], Pattern.CASE_INSENSITIVE).matcher(keepImgHtml)
val sb = StringBuffer()
if (matcher.find()) {
do {
var strBefore = keepImgHtml.substring(appendPos, matcher.start())
if (hasMatch) { //格式化不带参数和数据属性的普通图片标签
var appendPos0 = 0
val matcher0 = Pattern.compile("<img[^>]*src *= *\"([^\"]+)\"[^>]*>", Pattern.CASE_INSENSITIVE).matcher(strBefore) //格式化普通图片标签
while (matcher0.find()) {
val strBefore0 = strBefore.substring(appendPos, matcher.start())
sb.append( if (strBefore0.isBlank()) strBefore0 else strBefore0.replace("\n","\n  "))
sb.append("<img src=\"${NetworkUtils.getAbsoluteURL(redirectUrl,matcher.group(1)!!)}\">")
appendPos0 = matcher.end()
}
strBefore = if (appendPos0 < strBefore.length) {
strBefore.substring(appendPos0, strBefore.length).replace("\n", "\n  ") //缩进图片之后的非空白段落
} else ""
}
sb.append(
if (strBefore.isBlank()) strBefore else strBefore.replace("\n","\n  ") //缩进图片之间的非空白段落
)
sb.append(
"<img src=\"${
NetworkUtils.getAbsoluteURL(
redirectUrl,
urlBefore
) + url.substring(urlBefore.length)
}\">"
)
if (pos == 0) {
val url = matcher.group(1)!!
val urlMatcher = AnalyzeUrl.paramPattern.matcher(url)
val find = urlMatcher.find()
sb.append("<img src=\"${
if(find) NetworkUtils.getAbsoluteURL(redirectUrl,url.substring(0,urlMatcher.start())) + url.substring(urlMatcher.end())
else url
}\">")
} else sb.append("<img src=\"${NetworkUtils.getAbsoluteURL(redirectUrl,matcher.group(1)!!)}\">")
appendPos = matcher.end()
}
if(appendPos != 0)endPos = appendPos
} while (matcher.find())
hasMatch = false //普通图片标签已经处理过
}
if (endPos < keepImgHtml.length) {
sb.append( keepImgHtml.substring( endPos, keepImgHtml.length ).replace("\n","\n  ") ) //缩进图片之后的非空白段落
if (appendPos != 0) {
hasMatchX = true //存在带参数或带数据属性的图片标签
endPos = appendPos //存在匹配,更新位置
str = sb.toString() //存在匹配,更新字符串
}
return sb.toString()
}
return if (endPos < keepImgHtml.length) {
str + keepImgHtml.substring( endPos, keepImgHtml.length ).replace("\n","\n  ") //缩进图片之后的非空白段落
}else str
}
}

Loading…
Cancel
Save