Merge pull request #1128 from bushixuanqi/master

修正
pull/1132/head
kunfei 3 years ago committed by GitHub
commit 7e71811aab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      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. 17
      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. 82
      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
@ -61,12 +62,11 @@ data class BookChapter(
return false
}
fun getAbsoluteURL(): String {
val urlBefore = url.substringBefore(',')
val urlAbsoluteBefore = NetworkUtils.getAbsoluteURL(baseUrl, urlBefore)
return if (urlBefore.length == url.length) urlAbsoluteBefore else urlAbsoluteBefore + url.substring(
urlBefore.length
)
fun getAbsoluteURL():String{
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(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")) {
@ -141,17 +143,14 @@ class AnalyzeUrl(
* 处理URL
*/
private fun initUrl() { //replaceKeyPageJs已经替换掉额外内容,此处url是基础形式,可以直接切首个‘,’之前字符串。
urlHasQuery = ruleUrl.substringBefore(',')
url = NetworkUtils.getAbsoluteURL(baseUrl, urlHasQuery)
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 ->
if(urlHasQuery.length != ruleUrl.length ) {
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,43 +27,66 @@ 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[^>]*data-[^=]*= *\"([^\"])\"[^>]*>",
"<img[^>]*src *= *\"([^\"{]+(?:\\{(?:[^{}]|\\{[^{}]*\\})*\\})?)\"[^>]*>"
)) {
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())
sb.append(
if (strBefore.isBlank()) strBefore else strBefore.replace(
"\n",
"\n  "
) //缩进图片之间的非空白段落
)
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(appendPos0, 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) else ""
}
sb.append(
"<img src=\"${
NetworkUtils.getAbsoluteURL(
redirectUrl,
urlBefore
) + url.substring(urlBefore.length)
}\">"
if (strBefore.isBlank()) strBefore else strBefore.replace("\n","\n  ") //缩进图片之间的非空白段落
)
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