pull/1282/head
gedoor 3 years ago
parent 7c08da40ba
commit ea3259be2e
  1. 30
      app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt
  2. 24
      app/src/main/java/io/legado/app/model/webBook/BookContent.kt
  3. 8
      app/src/main/java/io/legado/app/model/webBook/ChapterData.kt
  4. 6
      app/src/main/java/io/legado/app/model/webBook/ContentData.kt
  5. 37
      app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt
  6. 27
      app/src/main/java/io/legado/app/model/webBook/WebBook.kt
  7. 3
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  8. 4
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt

@ -49,13 +49,11 @@ object BookChapterList {
scope, book, baseUrl, redirectUrl, body, scope, book, baseUrl, redirectUrl, body,
tocRule, listRule, bookSource, log = true tocRule, listRule, bookSource, log = true
) )
chapterData.chapterList?.let { chapterList.addAll(chapterData.first)
chapterList.addAll(it) when (chapterData.second.size) {
}
when (chapterData.nextUrl.size) {
0 -> Unit 0 -> Unit
1 -> { 1 -> {
var nextUrl = chapterData.nextUrl[0] var nextUrl = chapterData.second[0]
while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) {
nextUrlList.add(nextUrl) nextUrlList.add(nextUrl)
AnalyzeUrl( AnalyzeUrl(
@ -68,20 +66,18 @@ object BookChapterList {
scope, book, nextUrl, nextUrl, scope, book, nextUrl, nextUrl,
nextBody, tocRule, listRule, bookSource nextBody, tocRule, listRule, bookSource
) )
nextUrl = chapterData.nextUrl.firstOrNull() ?: "" nextUrl = chapterData.second.firstOrNull() ?: ""
chapterData.chapterList?.let { chapterList.addAll(chapterData.first)
chapterList.addAll(it)
}
} }
} }
Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}")
} }
else -> { else -> {
Debug.log(bookSource.bookSourceUrl, "◇并发解析目录,总页数:${chapterData.nextUrl.size}") Debug.log(bookSource.bookSourceUrl, "◇并发解析目录,总页数:${chapterData.second.size}")
withContext(IO) { withContext(IO) {
val asyncArray = Array(chapterData.nextUrl.size) { val asyncArray = Array(chapterData.second.size) {
async(IO) { async(IO) {
val urlStr = chapterData.nextUrl[it] val urlStr = chapterData.second[it]
val analyzeUrl = AnalyzeUrl( val analyzeUrl = AnalyzeUrl(
ruleUrl = urlStr, ruleUrl = urlStr,
book = book, book = book,
@ -92,13 +88,11 @@ object BookChapterList {
analyzeChapterList( analyzeChapterList(
this, book, urlStr, res.url, this, book, urlStr, res.url,
res.body!!, tocRule, listRule, bookSource, false res.body!!, tocRule, listRule, bookSource, false
).chapterList ).first
} }
} }
asyncArray.forEach { coroutine -> asyncArray.forEach { coroutine ->
coroutine.await()?.let { chapterList.addAll(coroutine.await())
chapterList.addAll(it)
}
} }
} }
} }
@ -139,7 +133,7 @@ object BookChapterList {
bookSource: BookSource, bookSource: BookSource,
getNextUrl: Boolean = true, getNextUrl: Boolean = true,
log: Boolean = false log: Boolean = false
): ChapterData<List<String>> { ): Pair<List<BookChapter>, List<String>> {
val analyzeRule = AnalyzeRule(book, bookSource) val analyzeRule = AnalyzeRule(book, bookSource)
analyzeRule.setContent(body).setBaseUrl(baseUrl) analyzeRule.setContent(body).setBaseUrl(baseUrl)
analyzeRule.setRedirectUrl(redirectUrl) analyzeRule.setRedirectUrl(redirectUrl)
@ -201,7 +195,7 @@ object BookChapterList {
Debug.log(bookSource.bookSourceUrl, "┌获取首章信息", log) Debug.log(bookSource.bookSourceUrl, "┌获取首章信息", log)
Debug.log(bookSource.bookSourceUrl, "${chapterList[0].tag}", log) Debug.log(bookSource.bookSourceUrl, "${chapterList[0].tag}", log)
} }
return ChapterData(chapterList, nextUrlList) return Pair(chapterList, nextUrlList)
} }
} }

@ -53,9 +53,9 @@ object BookContent {
var contentData = analyzeContent( var contentData = analyzeContent(
book, baseUrl, redirectUrl, body, contentRule, bookChapter, bookSource, mNextChapterUrl book, baseUrl, redirectUrl, body, contentRule, bookChapter, bookSource, mNextChapterUrl
) )
content.append(contentData.content) content.append(contentData.first)
if (contentData.nextUrl.size == 1) { if (contentData.second.size == 1) {
var nextUrl = contentData.nextUrl[0] var nextUrl = contentData.second[0]
while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) {
if (!mNextChapterUrl.isNullOrEmpty() if (!mNextChapterUrl.isNullOrEmpty()
&& NetworkUtils.getAbsoluteURL(baseUrl, nextUrl) && NetworkUtils.getAbsoluteURL(baseUrl, nextUrl)
@ -75,17 +75,17 @@ object BookContent {
bookChapter, bookSource, mNextChapterUrl, false bookChapter, bookSource, mNextChapterUrl, false
) )
nextUrl = nextUrl =
if (contentData.nextUrl.isNotEmpty()) contentData.nextUrl[0] else "" if (contentData.second.isNotEmpty()) contentData.second[0] else ""
content.append("\n").append(contentData.content) content.append("\n").append(contentData.first)
} }
} }
Debug.log(bookSource.bookSourceUrl, "◇本章总页数:${nextUrlList.size}") Debug.log(bookSource.bookSourceUrl, "◇本章总页数:${nextUrlList.size}")
} else if (contentData.nextUrl.size > 1) { } else if (contentData.second.size > 1) {
Debug.log(bookSource.bookSourceUrl, "◇并发解析目录,总页数:${contentData.nextUrl.size}") Debug.log(bookSource.bookSourceUrl, "◇并发解析目录,总页数:${contentData.second.size}")
withContext(IO) { withContext(IO) {
val asyncArray = Array(contentData.nextUrl.size) { val asyncArray = Array(contentData.second.size) {
async(IO) { async(IO) {
val urlStr = contentData.nextUrl[it] val urlStr = contentData.second[it]
val analyzeUrl = AnalyzeUrl( val analyzeUrl = AnalyzeUrl(
ruleUrl = urlStr, ruleUrl = urlStr,
book = book, book = book,
@ -96,7 +96,7 @@ object BookContent {
analyzeContent( analyzeContent(
book, urlStr, res.url, res.body!!, contentRule, book, urlStr, res.url, res.body!!, contentRule,
bookChapter, bookSource, mNextChapterUrl, false bookChapter, bookSource, mNextChapterUrl, false
).content ).first
} }
} }
asyncArray.forEach { coroutine -> asyncArray.forEach { coroutine ->
@ -131,7 +131,7 @@ object BookContent {
bookSource: BookSource, bookSource: BookSource,
nextChapterUrl: String?, nextChapterUrl: String?,
printLog: Boolean = true printLog: Boolean = true
): ContentData<List<String>> { ): Pair<String, List<String>> {
val analyzeRule = AnalyzeRule(book, bookSource) val analyzeRule = AnalyzeRule(book, bookSource)
analyzeRule.setContent(body, baseUrl) analyzeRule.setContent(body, baseUrl)
val rUrl = analyzeRule.setRedirectUrl(redirectUrl) val rUrl = analyzeRule.setRedirectUrl(redirectUrl)
@ -150,6 +150,6 @@ object BookContent {
} }
Debug.log(bookSource.bookSourceUrl, "" + nextUrlList.joinToString(""), printLog) Debug.log(bookSource.bookSourceUrl, "" + nextUrlList.joinToString(""), printLog)
} }
return ContentData(content, nextUrlList) return Pair(content, nextUrlList)
} }
} }

@ -1,8 +0,0 @@
package io.legado.app.model.webBook
import io.legado.app.data.entities.BookChapter
data class ChapterData<T>(
var chapterList: List<BookChapter>? = null,
var nextUrl: T
)

@ -1,6 +0,0 @@
package io.legado.app.model.webBook
data class ContentData<T>(
var content: String = "",
var nextUrl: T
)

@ -1,37 +0,0 @@
package io.legado.app.model.webBook
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.isActive
/**
* 精准搜索
*/
object PreciseSearch {
suspend fun searchFirstBook(
scope: CoroutineScope,
bookSources: List<BookSource>,
name: String,
author: String
): Book? {
bookSources.forEach { bookSource ->
kotlin.runCatching {
if (!scope.isActive) return null
WebBook.searchBookAwait(scope, bookSource, name).firstOrNull {
it.name == name && it.author == author
}?.let {
return if (it.tocUrl.isBlank()) {
if (!scope.isActive) return null
WebBook.getBookInfoAwait(scope, bookSource, it.toBook())
} else {
it.toBook()
}
}
}
}
return null
}
}

@ -10,10 +10,37 @@ import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
object WebBook { object WebBook {
/**
* 精准搜索
*/
suspend fun preciseSearch(
scope: CoroutineScope,
bookSources: List<BookSource>,
name: String,
author: String
): Book? {
bookSources.forEach { bookSource ->
kotlin.runCatching {
if (!scope.isActive) return null
searchBookAwait(scope, bookSource, name).firstOrNull {
it.name == name && it.author == author
}?.let {
return if (it.tocUrl.isBlank()) {
if (!scope.isActive) return null
getBookInfoAwait(scope, bookSource, it.toBook())
} else {
it.toBook()
}
}
}
}
return null
}
/** /**
* 搜索 * 搜索

@ -16,7 +16,6 @@ import io.legado.app.help.ContentProcessor
import io.legado.app.help.storage.AppWebDav import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.model.webBook.PreciseSearch
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
@ -221,7 +220,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
if (!AppConfig.autoChangeSource) return if (!AppConfig.autoChangeSource) return
execute { execute {
val sources = appDb.bookSourceDao.allTextEnabled val sources = appDb.bookSourceDao.allTextEnabled
val book = PreciseSearch.searchFirstBook(this, sources, name, author) val book = WebBook.preciseSearch(this, sources, name, author)
if (book != null) { if (book != null) {
book.upInfoFromOld(ReadBook.book) book.upInfoFromOld(ReadBook.book)
changeTo(book) changeTo(book)

@ -10,7 +10,6 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.help.http.newCall import io.legado.app.help.http.newCall
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.help.http.text import io.legado.app.help.http.text
import io.legado.app.model.webBook.PreciseSearch
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
@ -114,8 +113,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application)
val name = it["name"] ?: "" val name = it["name"] ?: ""
val author = it["author"] ?: "" val author = it["author"] ?: ""
if (name.isNotEmpty() && appDb.bookDao.getBook(name, author) == null) { if (name.isNotEmpty() && appDb.bookDao.getBook(name, author) == null) {
val book = PreciseSearch val book = WebBook.preciseSearch(this, bookSources, name, author)
.searchFirstBook(this, bookSources, name, author)
book?.let { book?.let {
if (groupId > 0) { if (groupId > 0) {
book.group = groupId book.group = groupId

Loading…
Cancel
Save