图片url在解析正文时就拼接成绝对url

pull/898/head
gedoor 4 years ago
parent 2332302e7e
commit 6cd2ba86b0
  1. 2
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  2. 4
      app/src/main/java/io/legado/app/model/Debug.kt
  3. 4
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  4. 2
      app/src/main/java/io/legado/app/model/localBook/EPUBFile.kt
  5. 45
      app/src/main/java/io/legado/app/model/webBook/BookContent.kt
  6. 4
      app/src/main/java/io/legado/app/model/webBook/BookInfo.kt
  7. 4
      app/src/main/java/io/legado/app/model/webBook/BookList.kt
  8. 2
      app/src/main/java/io/legado/app/model/webBook/WebBook.kt
  9. 11
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  10. 21
      app/src/main/java/io/legado/app/utils/HtmlFormatter.kt

@ -227,7 +227,7 @@ interface JsExtensions {
} }
fun htmlFormat(str: String): String { fun htmlFormat(str: String): String {
return HtmlFormat.formatKeepImg(str) return HtmlFormatter.formatKeepImg(str)
} }
/** /**

@ -8,7 +8,7 @@ import io.legado.app.data.entities.RssSource
import io.legado.app.help.coroutine.CompositeCoroutine import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.model.rss.Rss import io.legado.app.model.rss.Rss
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.HtmlFormat import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.msg import io.legado.app.utils.msg
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -36,7 +36,7 @@ object Debug {
if (debugSource != sourceUrl || callback == null || !print) return if (debugSource != sourceUrl || callback == null || !print) return
var printMsg = msg ?: "" var printMsg = msg ?: ""
if (isHtml) { if (isHtml) {
printMsg = HtmlFormat.format(msg) printMsg = HtmlFormatter.format(msg)
} }
if (showTime) { if (showTime) {
printMsg = printMsg =

@ -67,11 +67,11 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions {
return this return this
} }
fun setRedirectUrl(url: String): AnalyzeRule { fun setRedirectUrl(url: String): URL? {
kotlin.runCatching { kotlin.runCatching {
redirectUrl = URL(url.split(AnalyzeUrl.splitUrlRegex, 1)[0]) redirectUrl = URL(url.split(AnalyzeUrl.splitUrlRegex, 1)[0])
} }
return this return redirectUrl
} }
/** /**

@ -181,7 +181,7 @@ class EPUBFile(var book: io.legado.app.data.entities.Book) {
if (book.getDelTag(tag)) { if (book.getDelTag(tag)) {
html = html.replace("<ruby>\\s?([\\u4e00-\\u9fa5])\\s?.*?</ruby>".toRegex(), "$1") html = html.replace("<ruby>\\s?([\\u4e00-\\u9fa5])\\s?.*?</ruby>".toRegex(), "$1")
} }
return HtmlFormat.formatKeepImg(html) return HtmlFormatter.formatKeepImg(html)
} }
return null return null
} }

@ -10,7 +10,7 @@ import io.legado.app.help.BookHelp
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.HtmlFormat import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -26,6 +26,7 @@ object BookContent {
bookChapter: BookChapter, bookChapter: BookChapter,
bookSource: BookSource, bookSource: BookSource,
baseUrl: String, baseUrl: String,
redirectUrl: String,
nextChapterUrl: String? = null nextChapterUrl: String? = null
): String { ): String {
body ?: throw Exception( body ?: throw Exception(
@ -44,7 +45,7 @@ object BookContent {
analyzeRule.setRedirectUrl(baseUrl) analyzeRule.setRedirectUrl(baseUrl)
analyzeRule.nextChapterUrl = mNextChapterUrl analyzeRule.nextChapterUrl = mNextChapterUrl
var contentData = analyzeContent( var contentData = analyzeContent(
book, baseUrl, body, contentRule, bookChapter, bookSource, mNextChapterUrl book, baseUrl, redirectUrl, body, contentRule, bookChapter, bookSource, mNextChapterUrl
) )
content.append(contentData.content).append("\n") content.append(contentData.content).append("\n")
@ -56,20 +57,15 @@ object BookContent {
== NetworkUtils.getAbsoluteURL(baseUrl, mNextChapterUrl) == NetworkUtils.getAbsoluteURL(baseUrl, mNextChapterUrl)
) break ) break
nextUrlList.add(nextUrl) nextUrlList.add(nextUrl)
AnalyzeUrl( val res = AnalyzeUrl(
ruleUrl = nextUrl, ruleUrl = nextUrl,
book = book, book = book,
headerMapF = bookSource.getHeaderMap() headerMapF = bookSource.getHeaderMap()
).getStrResponse(bookSource.bookSourceUrl).body?.let { nextBody -> ).getStrResponse(bookSource.bookSourceUrl)
res.body?.let { nextBody ->
contentData = analyzeContent( contentData = analyzeContent(
book, book, nextUrl, res.url, nextBody, contentRule,
nextUrl, bookChapter, bookSource, mNextChapterUrl, false
nextBody,
contentRule,
bookChapter,
bookSource,
mNextChapterUrl,
false
) )
nextUrl = nextUrl =
if (contentData.nextUrl.isNotEmpty()) contentData.nextUrl[0] else "" if (contentData.nextUrl.isNotEmpty()) contentData.nextUrl[0] else ""
@ -85,20 +81,15 @@ object BookContent {
} }
for (item in contentDataList) { for (item in contentDataList) {
withContext(scope.coroutineContext) { withContext(scope.coroutineContext) {
AnalyzeUrl( val res = AnalyzeUrl(
ruleUrl = item.nextUrl, ruleUrl = item.nextUrl,
book = book, book = book,
headerMapF = bookSource.getHeaderMap() headerMapF = bookSource.getHeaderMap()
).getStrResponse(bookSource.bookSourceUrl).body?.let { ).getStrResponse(bookSource.bookSourceUrl)
res.body?.let { nextBody ->
contentData = analyzeContent( contentData = analyzeContent(
book, book, item.nextUrl, res.url, nextBody, contentRule,
item.nextUrl, bookChapter, bookSource, mNextChapterUrl, false
it,
contentRule,
bookChapter,
bookSource,
mNextChapterUrl,
false
) )
item.content = contentData.content item.content = contentData.content
} }
@ -109,7 +100,7 @@ object BookContent {
} }
} }
content.deleteCharAt(content.length - 1) content.deleteCharAt(content.length - 1)
var contentStr = HtmlFormat.formatKeepImg(content.toString()) var contentStr = content.toString()
val replaceRegex = contentRule.replaceRegex val replaceRegex = contentRule.replaceRegex
if (!replaceRegex.isNullOrEmpty()) { if (!replaceRegex.isNullOrEmpty()) {
contentStr = analyzeRule.getString(replaceRegex, value = contentStr) contentStr = analyzeRule.getString(replaceRegex, value = contentStr)
@ -128,6 +119,7 @@ object BookContent {
private fun analyzeContent( private fun analyzeContent(
book: Book, book: Book,
baseUrl: String, baseUrl: String,
redirectUrl: String,
body: String, body: String,
contentRule: ContentRule, contentRule: ContentRule,
chapter: BookChapter, chapter: BookChapter,
@ -136,13 +128,14 @@ object BookContent {
printLog: Boolean = true printLog: Boolean = true
): ContentData<List<String>> { ): ContentData<List<String>> {
val analyzeRule = AnalyzeRule(book) val analyzeRule = AnalyzeRule(book)
analyzeRule.setContent(body).setBaseUrl(baseUrl) analyzeRule.setContent(body, baseUrl)
analyzeRule.setRedirectUrl(baseUrl) val rUrl = analyzeRule.setRedirectUrl(redirectUrl)
analyzeRule.nextChapterUrl = nextChapterUrl analyzeRule.nextChapterUrl = nextChapterUrl
val nextUrlList = arrayListOf<String>() val nextUrlList = arrayListOf<String>()
analyzeRule.chapter = chapter analyzeRule.chapter = chapter
//获取正文 //获取正文
val content = analyzeRule.getString(contentRule.content) var content = analyzeRule.getString(contentRule.content)
content = HtmlFormatter.formatKeepImg(content, rUrl)
//获取下一页链接 //获取下一页链接
val nextUrlRule = contentRule.nextContentUrl val nextUrlRule = contentRule.nextContentUrl
if (!nextUrlRule.isNullOrEmpty()) { if (!nextUrlRule.isNullOrEmpty()) {

@ -6,7 +6,7 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.utils.HtmlFormat import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
import io.legado.app.utils.StringUtils.wordCountFormat import io.legado.app.utils.StringUtils.wordCountFormat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -93,7 +93,7 @@ object BookInfo {
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取简介") Debug.log(bookSource.bookSourceUrl, "┌获取简介")
analyzeRule.getString(infoRule.intro).let { analyzeRule.getString(infoRule.intro).let {
if (it.isNotEmpty()) book.intro = HtmlFormat.format(it) if (it.isNotEmpty()) book.intro = HtmlFormatter.format(it)
} }
Debug.log(bookSource.bookSourceUrl, "${book.intro}") Debug.log(bookSource.bookSourceUrl, "${book.intro}")
scope.ensureActive() scope.ensureActive()

@ -9,7 +9,7 @@ import io.legado.app.help.BookHelp
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.HtmlFormat import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
import io.legado.app.utils.StringUtils.wordCountFormat import io.legado.app.utils.StringUtils.wordCountFormat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -197,7 +197,7 @@ object BookList {
Debug.log(bookSource.bookSourceUrl, "${searchBook.latestChapterTitle}", log) Debug.log(bookSource.bookSourceUrl, "${searchBook.latestChapterTitle}", log)
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取简介", log) Debug.log(bookSource.bookSourceUrl, "┌获取简介", log)
searchBook.intro = HtmlFormat.format(analyzeRule.getString(ruleIntro)) searchBook.intro = HtmlFormatter.format(analyzeRule.getString(ruleIntro))
Debug.log(bookSource.bookSourceUrl, "${searchBook.intro}", log) Debug.log(bookSource.bookSourceUrl, "${searchBook.intro}", log)
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取封面链接", log) Debug.log(bookSource.bookSourceUrl, "┌获取封面链接", log)

@ -228,6 +228,7 @@ class WebBook(val bookSource: BookSource) {
bookChapter, bookChapter,
bookSource, bookSource,
bookChapter.getAbsoluteURL(), bookChapter.getAbsoluteURL(),
bookChapter.getAbsoluteURL(),
nextChapterUrl nextChapterUrl
) )
} else { } else {
@ -249,6 +250,7 @@ class WebBook(val bookSource: BookSource) {
bookChapter, bookChapter,
bookSource, bookSource,
bookChapter.getAbsoluteURL(), bookChapter.getAbsoluteURL(),
res.url,
nextChapterUrl nextChapterUrl
) )
} }

@ -90,13 +90,12 @@ object ChapterProvider {
textPages.add(TextPage()) textPages.add(TextPage())
contents.forEachIndexed { index, content -> contents.forEachIndexed { index, content ->
if (book.getImageStyle() == Book.imgStyleText) { if (book.getImageStyle() == Book.imgStyleText) {
var text = content.replace(srcReplaceChar, "") var text = content.replace(srcReplaceChar, "")
val srcList = LinkedList<String>() val srcList = LinkedList<String>()
val sb = StringBuffer() val sb = StringBuffer()
val matcher = AppPattern.imgPattern.matcher(text) val matcher = AppPattern.imgPattern.matcher(text)
while (matcher.find()) { while (matcher.find()) {
matcher.group(1)?.let { it -> matcher.group(1)?.let { src ->
val src = NetworkUtils.getAbsoluteURL(bookChapter.getAbsoluteURL(), it)
srcList.add(src) srcList.add(src)
ImageProvider.getImage(book, bookChapter.index, src) ImageProvider.getImage(book, bookChapter.index, src)
matcher.appendReplacement(sb, srcReplaceChar) matcher.appendReplacement(sb, srcReplaceChar)
@ -118,12 +117,8 @@ object ChapterProvider {
if (text.isNotBlank()) { if (text.isNotBlank()) {
val matcher = AppPattern.imgPattern.matcher(text) val matcher = AppPattern.imgPattern.matcher(text)
if (matcher.find()) { if (matcher.find()) {
matcher.group(1)?.let { it -> matcher.group(1)?.let { src ->
if (!book.isEpub()) { if (!book.isEpub()) {
val src = NetworkUtils.getAbsoluteURL(
bookChapter.getAbsoluteURL(),
it
)
durY = setTypeImage( durY = setTypeImage(
book, bookChapter, src, book, bookChapter, src,
durY, textPages, book.getImageStyle() durY, textPages, book.getImageStyle()

@ -1,9 +1,13 @@
package io.legado.app.utils package io.legado.app.utils
object HtmlFormat { import java.net.URL
import java.util.regex.Pattern
object HtmlFormatter {
private val wrapHtmlRegex = "</?(?:div|p|br|hr|h\\d|article|dd|dl)[^>]*>".toRegex() private val wrapHtmlRegex = "</?(?:div|p|br|hr|h\\d|article|dd|dl)[^>]*>".toRegex()
private val notImgHtmlRegex = "</?(?!img)[a-zA-Z]+(?=[ >])[^<>]*>".toRegex() private val notImgHtmlRegex = "</?(?!img)[a-zA-Z]+(?=[ >])[^<>]*>".toRegex()
private val otherHtmlRegex = "</?[a-zA-Z]+(?=[ >])[^<>]*>".toRegex() private val otherHtmlRegex = "</?[a-zA-Z]+(?=[ >])[^<>]*>".toRegex()
private val imgPattern = Pattern.compile("(<img )[^>]*src=\"([^\"]+)\"[^>]*(>)")
fun format(html: String?): String { fun format(html: String?): String {
html ?: return "" html ?: return ""
@ -23,5 +27,20 @@ object HtmlFormat {
.replace("[\\n\\s]+$".toRegex(), "") .replace("[\\n\\s]+$".toRegex(), "")
} }
fun formatKeepImg(html: String?, redirectUrl: URL?): String {
html ?: return ""
val sb = StringBuffer()
val matcher = imgPattern.matcher(html)
while (matcher.find()) {
val url = NetworkUtils.getAbsoluteURL(redirectUrl, matcher.group(2)!!)
matcher.appendReplacement(sb, "${matcher.group(1)} src=\"$url\"${matcher.group(3)}")
}
matcher.appendTail(sb)
return sb.replace(wrapHtmlRegex, "\n")
.replace(notImgHtmlRegex, "")
.replace("\\s*\\n+\\s*".toRegex(), "\n  ")
.replace("^[\\n\\s]+".toRegex(), "  ")
.replace("[\\n\\s]+$".toRegex(), "")
}
} }
Loading…
Cancel
Save