feat: 多页目录同时获取

pull/95/head
kunfei 5 years ago
parent 7a01d76440
commit 25dc9e62df
  1. 97
      app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt

@ -7,11 +7,14 @@ 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.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.rule.TocRule import io.legado.app.data.entities.rule.TocRule
import io.legado.app.help.coroutine.Coroutine
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 kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.withContext import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
object BookChapterList { object BookChapterList {
@ -21,8 +24,9 @@ object BookChapterList {
body: String?, body: String?,
bookSource: BookSource, bookSource: BookSource,
baseUrl: String baseUrl: String
): List<BookChapter> { ): List<BookChapter> = suspendCoroutine { block ->
var chapterList = ArrayList<BookChapter>() try {
val chapterList = ArrayList<BookChapter>()
body ?: throw Exception( body ?: throw Exception(
App.INSTANCE.getString(R.string.error_get_web_content, baseUrl) App.INSTANCE.getString(R.string.error_get_web_content, baseUrl)
) )
@ -43,35 +47,47 @@ object BookChapterList {
chapterData.chapterList?.let { chapterData.chapterList?.let {
chapterList.addAll(it) chapterList.addAll(it)
} }
if (chapterData.nextUrl.size == 1) { when (chapterData.nextUrl.size) {
0 -> {
block.resume(finish(book, chapterList, reverse))
}
1 -> {
Coroutine.async(scope = coroutineScope) {
var nextUrl = chapterData.nextUrl[0] var nextUrl = chapterData.nextUrl[0]
while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) {
nextUrlList.add(nextUrl) nextUrlList.add(nextUrl)
AnalyzeUrl( AnalyzeUrl(
ruleUrl = nextUrl, book = book, headerMapF = bookSource.getHeaderMap() ruleUrl = nextUrl,
book = book,
headerMapF = bookSource.getHeaderMap()
).getResponseAwait() ).getResponseAwait()
.body?.let { nextBody -> .body?.let { nextBody ->
chapterData = analyzeChapterList( chapterData = analyzeChapterList(
nextBody, nextUrl, tocRule, listRule, nextBody, nextUrl, tocRule, listRule,
book, bookSource, log = false book, bookSource, log = false
) )
nextUrl = if (chapterData.nextUrl.isNotEmpty()) nextUrl = if (chapterData.nextUrl.isNotEmpty()) {
chapterData.nextUrl[0] chapterData.nextUrl[0]
else "" } else ""
chapterData.chapterList?.let { chapterData.chapterList?.let {
chapterList.addAll(it) chapterList.addAll(it)
} }
} }
} }
Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}")
} else if (chapterData.nextUrl.size > 1) { block.resume(finish(book, chapterList, reverse))
}.onError {
block.resumeWithException(it)
}
}
else -> {
val chapterDataList = arrayListOf<ChapterData<String>>() val chapterDataList = arrayListOf<ChapterData<String>>()
for (item in chapterData.nextUrl) { for (item in chapterData.nextUrl) {
val data = ChapterData(nextUrl = item) val data = ChapterData(nextUrl = item)
chapterDataList.add(data) chapterDataList.add(data)
} }
for (item in chapterDataList) { for (item in chapterDataList) {
withContext(coroutineScope.coroutineContext) { Coroutine.async(scope = coroutineScope) {
val nextBody = AnalyzeUrl( val nextBody = AnalyzeUrl(
ruleUrl = item.nextUrl, ruleUrl = item.nextUrl,
book = book, book = book,
@ -80,36 +96,71 @@ object BookChapterList {
val nextChapterData = analyzeChapterList( val nextChapterData = analyzeChapterList(
nextBody, item.nextUrl, tocRule, listRule, book, bookSource nextBody, item.nextUrl, tocRule, listRule, book, bookSource
) )
item.chapterList = nextChapterData.chapterList synchronized(chapterDataList) {
} val isFinished = addChapterListIsFinish(
} chapterDataList,
for (item in chapterDataList) { item,
nextChapterData.chapterList
)
if (isFinished) {
chapterDataList.forEach { item ->
item.chapterList?.let { item.chapterList?.let {
chapterList.addAll(it) chapterList.addAll(it)
} }
} }
block.resume(finish(book, chapterList, reverse))
}
}
}.onError {
block.resumeWithException(it)
}
} }
}
}
} catch (e: Exception) {
block.resumeWithException(e)
}
}
private fun addChapterListIsFinish(
chapterDataList: ArrayList<ChapterData<String>>,
chapterData: ChapterData<String>,
chapterList: List<BookChapter>?
): Boolean {
chapterData.chapterList = chapterList
chapterDataList.forEach {
if (it.chapterList == null) {
return false
}
}
return true
}
private fun finish(
book: Book,
chapterList: ArrayList<BookChapter>,
reverse: Boolean
): ArrayList<BookChapter> {
//去重 //去重
if (!reverse) { if (!reverse) {
chapterList.reverse() chapterList.reverse()
} }
val lh = LinkedHashSet(chapterList) val lh = LinkedHashSet(chapterList)
chapterList = ArrayList(lh) val list = ArrayList(lh)
chapterList.reverse() list.reverse()
for ((index, item) in chapterList.withIndex()) { for ((index, item) in list.withIndex()) {
item.index = index item.index = index
} }
book.latestChapterTitle = chapterList.last().title book.latestChapterTitle = list.last().title
book.durChapterTitle = book.durChapterTitle =
chapterList.getOrNull(book.durChapterIndex)?.title ?: book.latestChapterTitle list.getOrNull(book.durChapterIndex)?.title ?: book.latestChapterTitle
if (book.totalChapterNum < chapterList.size) { if (book.totalChapterNum < list.size) {
book.lastCheckCount = chapterList.size - book.totalChapterNum book.lastCheckCount = list.size - book.totalChapterNum
} }
book.totalChapterNum = chapterList.size book.totalChapterNum = list.size
return chapterList return list
} }
private fun analyzeChapterList( private fun analyzeChapterList(
body: String?, body: String?,
baseUrl: String, baseUrl: String,

Loading…
Cancel
Save