diff --git a/app/src/main/assets/help/SourceMBookHelp.md b/app/src/main/assets/help/SourceMBookHelp.md index 3f931e0c3..facca613f 100644 --- a/app/src/main/assets/help/SourceMBookHelp.md +++ b/app/src/main/assets/help/SourceMBookHelp.md @@ -24,6 +24,6 @@ * 校验所选 * 校验书源可批量校验书源,由于网络等原因结果仅限参考 * "校验成功"是指所选的校验项目全部通过 - * 可正常识别搜索为空、发现为空、目录为空、正文为空、校验超时导致的失效,其余原因导致的视为规则失效 + * 可正常识别搜索为空、发现为空、搜索(发现)目录为空、搜索(发现)正文为空、校验超时导致的失效,其余原因(网站异常、源码变动)导致的视为规则失效 * 校验搜索优先使用书源填写的校验关键词,不存在时使用用户输入的关键词 * 校验结束后会自动筛选"失效"书源 \ No newline at end of file diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index a81bcf3bc..29fadde60 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -13,6 +13,11 @@ **2022/02/11** +* 目录正文现在按照搜索发现分别校验 +* 书源校验的超时校验存在bug + +**2022/02/11** + * 可以单独给书籍设置朗读tts * 目录界面菜单添加替换开关,开启替换加载时间会长一些 * 书源校验添加规则失效分组,更新书源界面帮助文档 diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index 354089406..b75aceeb7 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -142,6 +142,13 @@ data class BookSource( return false } + + fun getInvalidGroupNames(): String? { + return bookSourceGroup?.splitNotBlank(AppPattern.splitGroupRegex)?.toHashSet()?.filter { + "失效" in it + }?.joinToString() + } + fun equal(source: BookSource) = equal(bookSourceName, source.bookSourceName) && equal(bookSourceUrl, source.bookSourceUrl) diff --git a/app/src/main/java/io/legado/app/service/CheckSourceService.kt b/app/src/main/java/io/legado/app/service/CheckSourceService.kt index 80ab69ba7..68ca8c211 100644 --- a/app/src/main/java/io/legado/app/service/CheckSourceService.kt +++ b/app/src/main/java/io/legado/app/service/CheckSourceService.kt @@ -9,6 +9,7 @@ import io.legado.app.constant.EventBus import io.legado.app.constant.IntentAction import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource +import io.legado.app.data.entities.Book import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig import io.legado.app.help.coroutine.CompositeCoroutine @@ -34,7 +35,6 @@ class CheckSourceService : BaseService() { private val checkedIds = ArrayList() private var processIndex = 0 private var notificationMsg = "" - private var books = ArrayList() private val notificationBuilder by lazy { NotificationCompat.Builder(this, AppConst.channelIdReadAloud) @@ -112,7 +112,10 @@ class CheckSourceService : BaseService() { } } - fun check(source: BookSource) { + /** + *校验书源 + */ + private fun check(source: BookSource) { execute(context = searchCoroutine) { Debug.startChecking(source) var searchWord = CheckSource.keyword @@ -126,7 +129,7 @@ class CheckSourceService : BaseService() { ?.filterNot { it.startsWith("Error: ") }?.joinToString("\n") - //校验搜索 用户设置校验搜索 并且 搜索链接不为空 + //校验搜索书籍 用户设置校验搜索 并且 搜索链接不为空 if (CheckSource.checkSearch && !source.searchUrl.isNullOrBlank()) { val searchBooks = WebBook.searchBookAwait(this, source, searchWord) if (searchBooks.isEmpty()) { @@ -136,10 +139,10 @@ class CheckSourceService : BaseService() { } } else { source.removeGroup("搜索失效") - books = searchBooks + checkBook(searchBooks.first().toBook(), source) } } - //校验发现 + //校验发现书籍 if (CheckSource.checkDiscovery) { val exs = source.exploreKinds var url: String? = null @@ -164,42 +167,15 @@ class CheckSourceService : BaseService() { } } else { source.removeGroup("发现失效") - if (books.isEmpty()) books = exploreBooks - } - } - } - //校验详情 - if (CheckSource.checkInfo) { - var book = books.first().toBook() - if (book.tocUrl.isBlank()) { - book = WebBook.getBookInfoAwait(this, source, book) - } - //校验目录 - if (CheckSource.checkCategory) { - val toc = WebBook.getChapterListAwait(this, source, book) - val nextChapterUrl = toc.getOrNull(1)?.url ?: toc.first().url - source.removeGroup("目录失效") - //校验正文 - if (CheckSource.checkContent) { - WebBook.getContentAwait( - this, - bookSource = source, - book = book, - bookChapter = toc.first(), - nextChapterUrl = nextChapterUrl, - needSave = false - ) - source.removeGroup("正文失效") + checkBook(exploreBooks.first().toBook(), source, false) } } } - if (source.hasGroup("搜索失效")) throw NoStackTraceException("搜索失效") - if (source.hasGroup("发现失效")) throw NoStackTraceException("发现失效") + val finalCheckMessage = source.getInvalidGroupNames() + if (!finalCheckMessage.isNullOrBlank()) throw NoStackTraceException(finalCheckMessage) }.timeout(CheckSource.timeout) .onError(searchCoroutine) { when(it) { - is ContentEmptyException -> source.addGroup("正文失效") - is TocEmptyException -> source.addGroup("目录失效") //校验超时不能正常实现 不能识别 is TimeoutCancellationException -> source.addGroup("校验超时") //NoStackTraceException 已经添加了分组,其余的视为规则失效 @@ -221,6 +197,49 @@ class CheckSourceService : BaseService() { } } + /** + *校验书源的详情目录正文 + */ + private suspend fun checkBook(book: Book, source: BookSource, isSearchBook: Boolean = true) { + kotlin.runCatching { + var mBook = book + //校验详情 + if (CheckSource.checkInfo) { + if (mBook.tocUrl.isBlank()) { + mBook = WebBook.getBookInfoAwait(this, source, mBook) + } + //校验目录 + if (CheckSource.checkCategory) { + val toc = WebBook.getChapterListAwait(this, source, mBook) + val nextChapterUrl = toc.getOrNull(1)?.url ?: toc.first().url + //校验正文 + if (CheckSource.checkContent) { + WebBook.getContentAwait( + this, + bookSource = source, + book = mBook, + bookChapter = toc.first(), + nextChapterUrl = nextChapterUrl, + needSave = false + ) + } + } + } + }.onFailure { + val bookType = if (isSearchBook) "搜索" else "发现" + when (it) { + is ContentEmptyException -> source.addGroup("${bookType}正文失效") + is TocEmptyException -> source.addGroup("${bookType}目录失效") + //超时??js错误 + else -> throw it + } + }.onSuccess { + val bookType = if (isSearchBook) "搜索" else "发现" + source.removeGroup("${bookType}目录失效") + source.removeGroup("${bookType}正文失效") + } + } + private fun onNext(sourceUrl: String, sourceName: String) { synchronized(this) { check() diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/HttpTtsEditViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/config/HttpTtsEditViewModel.kt index 0559b7ff9..5c5794714 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/HttpTtsEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/HttpTtsEditViewModel.kt @@ -37,6 +37,7 @@ class HttpTtsEditViewModel(app: Application) : BaseViewModel(app) { id = httpTTS.id execute { appDb.httpTTSDao.insert(httpTTS) + if (ReadAloud.ttsEngine == httpTTS.id.toString()) ReadAloud.upReadAloudClass() }.onSuccess { success?.invoke() } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt index 67d3200b6..c28b3efa5 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -26,6 +26,7 @@ import io.legado.app.lib.theme.primaryColor import io.legado.app.model.ReadAloud import io.legado.app.model.ReadBook import io.legado.app.ui.document.HandleFileContract +import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.launch @@ -217,7 +218,14 @@ class SpeakEngineDialog(val callBack: CallBack) : BaseDialogFragment(R.layout.di binding.run { cbName.setOnClickListener { getItemByLayoutPosition(holder.layoutPosition)?.let { httpTTS -> - upTts(httpTTS.id.toString()) + val id = httpTTS.id.toString() + upTts(id) + if (!httpTTS.loginUrl.isNullOrBlank()) { + startActivity { + putExtra("type", "httpTts") + putExtra("key", id) + } + } } } ivEdit.setOnClickListener {