From e385ab3ef3505796a5fac0aea3565571d1d55dce Mon Sep 17 00:00:00 2001 From: Horis <8674809+821938089@users.noreply.github.com> Date: Mon, 7 Apr 2025 16:26:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/model/analyzeRule/AnalyzeRule.kt | 124 +++++++++--------- .../changesource/ChangeBookSourceDialog.kt | 18 +-- .../changesource/ChangeBookSourceViewModel.kt | 16 +-- .../changesource/ChangeChapterSourceDialog.kt | 11 +- 4 files changed, 85 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 4d8ab6ac9..433be384d 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -64,6 +64,7 @@ class AnalyzeRule( private var analyzeByJSonPath: AnalyzeByJSonPath? = null private val stringRuleCache = hashMapOf>() + private val regexCache = hashMapOf() private var coroutineContext: CoroutineContext = EmptyCoroutineContext @@ -189,37 +190,37 @@ class AnalyzeRule( for (sourceRule in ruleList) { putRule(sourceRule.putMap) sourceRule.makeUpRule(result) - result?.let { - if (sourceRule.rule.isNotEmpty()) { - result = when (sourceRule.mode) { - Mode.Js -> evalJS(sourceRule.rule, result) - Mode.Json -> getAnalyzeByJSonPath(it).getStringList(sourceRule.rule) - Mode.XPath -> getAnalyzeByXPath(it).getStringList(sourceRule.rule) - Mode.Default -> getAnalyzeByJSoup(it).getStringList(sourceRule.rule) - else -> sourceRule.rule - } + result ?: continue + val rule = sourceRule.rule + if (rule.isNotEmpty()) { + result = when (sourceRule.mode) { + Mode.Js -> evalJS(rule, result) + Mode.Json -> getAnalyzeByJSonPath(result).getStringList(rule) + Mode.XPath -> getAnalyzeByXPath(result).getStringList(rule) + Mode.Default -> getAnalyzeByJSoup(result).getStringList(rule) + else -> rule } - if (sourceRule.replaceRegex.isNotEmpty() && result is List<*>) { - val newList = ArrayList() - for (item in result as List<*>) { - newList.add(replaceRegex(item.toString(), sourceRule)) - } - result = newList - } else if (sourceRule.replaceRegex.isNotEmpty()) { - result = replaceRegex(result.toString(), sourceRule) + } + if (sourceRule.replaceRegex.isNotEmpty() && result is List<*>) { + val newList = ArrayList() + for (item in result) { + newList.add(replaceRegex(item.toString(), sourceRule)) } + result = newList + } else if (sourceRule.replaceRegex.isNotEmpty()) { + result = replaceRegex(result.toString(), sourceRule) } } } } if (result == null) return null if (result is String) { - result = (result as String).split("\n") + result = result.split("\n") } if (isUrl) { val urlList = ArrayList() if (result is List<*>) { - for (url in result as List<*>) { + for (url in result) { val absoluteURL = NetworkUtils.getAbsoluteURL(redirectUrl, url.toString()) if (absoluteURL.isNotEmpty() && !urlList.contains(absoluteURL)) { urlList.add(absoluteURL) @@ -276,24 +277,24 @@ class AnalyzeRule( for (sourceRule in ruleList) { putRule(sourceRule.putMap) sourceRule.makeUpRule(result) - result?.let { - if (sourceRule.rule.isNotBlank() || sourceRule.replaceRegex.isEmpty()) { - result = when (sourceRule.mode) { - Mode.Js -> evalJS(sourceRule.rule, it) - Mode.Json -> getAnalyzeByJSonPath(it).getString(sourceRule.rule) - Mode.XPath -> getAnalyzeByXPath(it).getString(sourceRule.rule) - Mode.Default -> if (isUrl) { - getAnalyzeByJSoup(it).getString0(sourceRule.rule) - } else { - getAnalyzeByJSoup(it).getString(sourceRule.rule) - } - - else -> sourceRule.rule + result ?: continue + val rule = sourceRule.rule + if (rule.isNotBlank() || sourceRule.replaceRegex.isEmpty()) { + result = when (sourceRule.mode) { + Mode.Js -> evalJS(rule, result) + Mode.Json -> getAnalyzeByJSonPath(result).getString(rule) + Mode.XPath -> getAnalyzeByXPath(result).getString(rule) + Mode.Default -> if (isUrl) { + getAnalyzeByJSoup(result).getString0(rule) + } else { + getAnalyzeByJSoup(result).getString(rule) } + + else -> rule } - if ((result != null) && sourceRule.replaceRegex.isNotEmpty()) { - result = replaceRegex(result.toString(), sourceRule) - } + } + if (result != null && sourceRule.replaceRegex.isNotEmpty()) { + result = replaceRegex(result.toString(), sourceRule) } } } @@ -328,21 +329,21 @@ class AnalyzeRule( for (sourceRule in ruleList) { putRule(sourceRule.putMap) sourceRule.makeUpRule(result) - result?.let { - result = when (sourceRule.mode) { - Mode.Regex -> AnalyzeByRegex.getElement( - result.toString(), - sourceRule.rule.splitNotBlank("&&") - ) + result ?: continue + val rule = sourceRule.rule + result = when (sourceRule.mode) { + Mode.Regex -> AnalyzeByRegex.getElement( + result.toString(), + rule.splitNotBlank("&&") + ) - Mode.Js -> evalJS(sourceRule.rule, it) - Mode.Json -> getAnalyzeByJSonPath(it).getObject(sourceRule.rule) - Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule) - else -> getAnalyzeByJSoup(it).getElements(sourceRule.rule) - } - if (sourceRule.replaceRegex.isNotEmpty()) { - result = replaceRegex(result.toString(), sourceRule) - } + Mode.Js -> evalJS(rule, result) + Mode.Json -> getAnalyzeByJSonPath(result).getObject(rule) + Mode.XPath -> getAnalyzeByXPath(result).getElements(rule) + else -> getAnalyzeByJSoup(result).getElements(rule) + } + if (sourceRule.replaceRegex.isNotEmpty()) { + result = replaceRegex(result.toString(), sourceRule) } } } @@ -361,21 +362,18 @@ class AnalyzeRule( result = content for (sourceRule in ruleList) { putRule(sourceRule.putMap) - result?.let { - result = when (sourceRule.mode) { - Mode.Regex -> AnalyzeByRegex.getElements( - result.toString(), - sourceRule.rule.splitNotBlank("&&") - ) + result ?: continue + val rule = sourceRule.rule + result = when (sourceRule.mode) { + Mode.Regex -> AnalyzeByRegex.getElements( + result.toString(), + rule.splitNotBlank("&&") + ) - Mode.Js -> evalJS(sourceRule.rule, result) - Mode.Json -> getAnalyzeByJSonPath(it).getList(sourceRule.rule) - Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule) - else -> getAnalyzeByJSoup(it).getElements(sourceRule.rule) - } -// if (sourceRule.replaceRegex.isNotEmpty()) { -// result = replaceRegex(result.toString(), sourceRule) -// } + Mode.Js -> evalJS(rule, result) + Mode.Json -> getAnalyzeByJSonPath(result).getList(rule) + Mode.XPath -> getAnalyzeByXPath(result).getElements(rule) + else -> getAnalyzeByJSoup(result).getElements(rule) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt index 11ceaa66e..636a650cf 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.base.BaseDialogFragment +import io.legado.app.constant.AppLog import io.legado.app.constant.EventBus import io.legado.app.data.appDb import io.legado.app.data.entities.Book @@ -43,7 +44,6 @@ import io.legado.app.utils.getCompatDrawable import io.legado.app.utils.observeEvent import io.legado.app.utils.setLayout import io.legado.app.utils.startActivity -import io.legado.app.utils.toastOnUi import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.delay @@ -185,7 +185,9 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_ private fun initNavigationView() { binding.toolBar.navigationIcon = getCompatDrawable(androidx.appcompat.R.drawable.abc_ic_ab_back_material) - binding.toolBar.setNavigationContentDescription(androidx.appcompat.R.string.abc_action_bar_up_description) + binding.toolBar.setNavigationContentDescription( + androidx.appcompat.R.string.abc_action_bar_up_description + ) binding.toolBar.setNavigationOnClickListener { dismissAllowingStateLoss() } @@ -239,7 +241,7 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_ lifecycleScope.launch { repeatOnLifecycle(STARTED) { - viewModel.finishedChangeSourceResult + viewModel.changeSourceProgress .drop(1) .collect { (count, name) -> binding.tvDur.text = @@ -387,14 +389,14 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_ waitDialog.setText(R.string.load_toc) waitDialog.show() val book = viewModel.bookMap[searchBook.primaryStr()] ?: searchBook.toBook() - val coroutine = viewModel.getToc(book, { - waitDialog.dismiss() - toastOnUi(it) - }) { toc, source -> + val coroutine = viewModel.getToc(book, { toc, source -> waitDialog.dismiss() callBack?.changeTo(source, book, toc) onSuccess?.invoke() - } + }, { + waitDialog.dismiss() + AppLog.put("换源获取目录出错\n$it", it, true) + }) waitDialog.setOnCancelListener { coroutine.cancel() } diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt index d3f778f6d..89e2aa883 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt @@ -68,13 +68,13 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a private var oldBook: Book? = null private var screenKey: String = "" private var bookSourceParts = arrayListOf() - val totalSourceCount:Int + val totalSourceCount: Int get() = bookSourceParts.size private var searchBookList = arrayListOf() private val searchBooks = Collections.synchronizedList(arrayListOf()) private val tocMap = ConcurrentHashMap>() - private val _finishedChangeSourceResult = MutableStateFlow(0 to "") - val finishedChangeSourceResult= _finishedChangeSourceResult.asStateFlow() + private val _changeSourceProgress = MutableStateFlow(0 to "") + val changeSourceProgress = _changeSourceProgress.asStateFlow() private var tocMapChapterCount = 0 private val contentProcessor by lazy { ContentProcessor.get(oldBook!!) @@ -191,7 +191,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a tocMap.clear() bookMap.clear() tocMapChapterCount = 0 - _finishedChangeSourceResult.value = 0 to "" + _changeSourceProgress.value = 0 to "" val searchGroup = AppConfig.searchGroup if (searchGroup.isBlank()) { bookSourceParts.addAll(appDb.bookSourceDao.allEnabledPart) @@ -243,7 +243,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a } it }.onEachIndexed { index, value -> - _finishedChangeSourceResult.update { _ -> + _changeSourceProgress.update { _ -> index + 1 to value.bookSourceName } }.onCompletion { @@ -446,8 +446,8 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a fun getToc( book: Book, - onError: (msg: String) -> Unit, - onSuccess: (toc: List, source: BookSource) -> Unit + onSuccess: (toc: List, source: BookSource) -> Unit, + onError: (e: Throwable) -> Unit ): Coroutine, BookSource>> { return execute { val toc = tocMap[book.primaryStr()] @@ -461,7 +461,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a }.onSuccess { onSuccess.invoke(it.first, it.second) }.onError { - onError.invoke(it.localizedMessage ?: "获取目录出错") + onError.invoke(it) } } diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt index bb7215d31..4bfae56ac 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt @@ -18,6 +18,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.base.BaseDialogFragment +import io.legado.app.constant.AppLog import io.legado.app.constant.EventBus import io.legado.app.data.appDb import io.legado.app.data.entities.Book @@ -310,16 +311,16 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c binding.clToc.visible() binding.loadingToc.visible() val book = searchBook.toBook() - viewModel.getToc(book, { - binding.clToc.gone() - toastOnUi(it) - }) { toc: List, _: BookSource -> + viewModel.getToc(book, { toc: List, _: BookSource -> tocAdapter.durChapterIndex = BookHelp.getDurChapter(viewModel.chapterIndex, viewModel.chapterTitle, toc) binding.loadingToc.gone() tocAdapter.setItems(toc) binding.recyclerViewToc.scrollToPosition(tocAdapter.durChapterIndex - 5) - } + }, { + binding.clToc.gone() + AppLog.put("单章换源获取目录出错\n$it", it, true) + }) } override val oldBookUrl: String?