From 66fe4b017bcd4bb68975746315865512cb6b5752 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 23 Mar 2021 22:00:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=AE=E5=BD=95=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E8=AE=BF=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/model/webBook/BookChapterList.kt | 206 ++++++------------ 1 file changed, 67 insertions(+), 139 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt index 4b03eb4a4..4ff934735 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt @@ -6,16 +6,16 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookSource 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.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeUrl import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.async import kotlinx.coroutines.ensureActive -import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withContext + import splitties.init.appCtx -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException object BookChapterList { @@ -26,153 +26,81 @@ object BookChapterList { bookSource: BookSource, baseUrl: String, redirectUrl: String - ): List = suspendCancellableCoroutine { block -> - kotlin.runCatching { - val chapterList = ArrayList() - body ?: throw Exception( - appCtx.getString(R.string.error_get_web_content, baseUrl) - ) - Debug.log(bookSource.bookSourceUrl, "≡获取成功:${baseUrl}") + ): List { + val chapterList = ArrayList() + body ?: throw Exception( + appCtx.getString(R.string.error_get_web_content, baseUrl) + ) + Debug.log(bookSource.bookSourceUrl, "≡获取成功:${baseUrl}") - val tocRule = bookSource.getTocRule() - val nextUrlList = arrayListOf(baseUrl) - var reverse = false - var listRule = tocRule.chapterList ?: "" - if (listRule.startsWith("-")) { - reverse = true - listRule = listRule.substring(1) - } - if (listRule.startsWith("+")) { - listRule = listRule.substring(1) - } - var chapterData = - analyzeChapterList( - scope, book, baseUrl, redirectUrl, body, - tocRule, listRule, bookSource, log = true - ) - chapterData.chapterList?.let { - chapterList.addAll(it) - } - when (chapterData.nextUrl.size) { - 0 -> { - block.resume(finish(book, chapterList, reverse)) - } - 1 -> { - Coroutine.async(scope = scope) { - var nextUrl = chapterData.nextUrl[0] - while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { - nextUrlList.add(nextUrl) - AnalyzeUrl( - ruleUrl = nextUrl, - book = book, - headerMapF = bookSource.getHeaderMap() - ).getStrResponse(bookSource.bookSourceUrl).body?.let { nextBody -> - chapterData = analyzeChapterList( - this, book, nextUrl, nextUrl, - nextBody, tocRule, listRule, bookSource - ) - nextUrl = chapterData.nextUrl.firstOrNull() ?: "" - chapterData.chapterList?.let { - chapterList.addAll(it) - } - } + val tocRule = bookSource.getTocRule() + val nextUrlList = arrayListOf(baseUrl) + var reverse = false + var listRule = tocRule.chapterList ?: "" + if (listRule.startsWith("-")) { + reverse = true + listRule = listRule.substring(1) + } + if (listRule.startsWith("+")) { + listRule = listRule.substring(1) + } + var chapterData = + analyzeChapterList( + scope, book, baseUrl, redirectUrl, body, + tocRule, listRule, bookSource, log = true + ) + chapterData.chapterList?.let { + chapterList.addAll(it) + } + when (chapterData.nextUrl.size) { + 0 -> Unit + 1 -> { + var nextUrl = chapterData.nextUrl[0] + while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { + nextUrlList.add(nextUrl) + AnalyzeUrl( + ruleUrl = nextUrl, + book = book, + headerMapF = bookSource.getHeaderMap() + ).getStrResponse(bookSource.bookSourceUrl).body?.let { nextBody -> + chapterData = analyzeChapterList( + scope, book, nextUrl, nextUrl, + nextBody, tocRule, listRule, bookSource + ) + nextUrl = chapterData.nextUrl.firstOrNull() ?: "" + chapterData.chapterList?.let { + chapterList.addAll(it) } - Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") - block.resume(finish(book, chapterList, reverse)) - }.onError { - block.resumeWithException(it) } } - else -> { - val chapterDataList = arrayListOf>() - for (item in chapterData.nextUrl) { - if (!nextUrlList.contains(item)) { - val data = ChapterData(nextUrl = item) - chapterDataList.add(data) - nextUrlList.add(item) - } - } - Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") - for (item in chapterDataList) { - downloadToc( - scope, item, book, bookSource, - tocRule, listRule, chapterList, chapterDataList, - { - block.resume(finish(book, chapterList, reverse)) - } - ) { - block.cancel(it) + Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") + } + else -> { + Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") + withContext(IO) { + val asyncArray = Array(chapterData.nextUrl.size) { + async { + val urlStr = chapterData.nextUrl[it] + val analyzeUrl = AnalyzeUrl( + ruleUrl = urlStr, + book = book, + headerMapF = bookSource.getHeaderMap() + ) + val res = analyzeUrl.getStrResponse(bookSource.bookSourceUrl) + analyzeChapterList( + this, book, urlStr, res.url, + res.body!!, tocRule, listRule, bookSource, false + ).chapterList } } - } - } - }.onFailure { - block.cancel(it) - } - } - - private fun downloadToc( - scope: CoroutineScope, - chapterData: ChapterData, - book: Book, - bookSource: BookSource, - tocRule: TocRule, - listRule: String, - chapterList: ArrayList, - chapterDataList: ArrayList>, - onFinish: () -> Unit, - onError: (error: Throwable) -> Unit - ) { - Coroutine.async(scope = scope) { - val nextBody = AnalyzeUrl( - ruleUrl = chapterData.nextUrl, - book = book, - headerMapF = bookSource.getHeaderMap() - ).getStrResponse(bookSource.bookSourceUrl).body - ?: throw Exception("${chapterData.nextUrl}, 下载失败") - val nextChapterData = analyzeChapterList( - this, book, chapterData.nextUrl, chapterData.nextUrl, - nextBody, tocRule, listRule, bookSource, false - ) - synchronized(chapterDataList) { - val isFinished = addChapterListIsFinish( - chapterDataList, - chapterData, - nextChapterData.chapterList - ) - if (isFinished) { - chapterDataList.forEach { item -> - item.chapterList?.let { + asyncArray.forEach { coroutine -> + coroutine.await()?.let { chapterList.addAll(it) } } - onFinish() } } - }.onError { - onError.invoke(it) } - } - - private fun addChapterListIsFinish( - chapterDataList: ArrayList>, - chapterData: ChapterData, - chapterList: List? - ): Boolean { - chapterData.chapterList = chapterList - chapterDataList.forEach { - if (it.chapterList == null) { - return false - } - } - return true - } - - private fun finish( - book: Book, - chapterList: ArrayList, - reverse: Boolean - ): ArrayList { //去重 if (!reverse) { chapterList.reverse()