This commit is contained in:
Horis
2025-04-07 16:26:14 +08:00
parent d38a733ea0
commit e385ab3ef3
4 changed files with 85 additions and 84 deletions
@@ -64,6 +64,7 @@ class AnalyzeRule(
private var analyzeByJSonPath: AnalyzeByJSonPath? = null
private val stringRuleCache = hashMapOf<String, List<SourceRule>>()
private val regexCache = hashMapOf<String, Regex?>()
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<String>()
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<String>()
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<String>()
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)
}
}
}
@@ -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()
}
@@ -68,13 +68,13 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
private var oldBook: Book? = null
private var screenKey: String = ""
private var bookSourceParts = arrayListOf<BookSourcePart>()
val totalSourceCount:Int
val totalSourceCount: Int
get() = bookSourceParts.size
private var searchBookList = arrayListOf<SearchBook>()
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
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<BookChapter>, source: BookSource) -> Unit
onSuccess: (toc: List<BookChapter>, source: BookSource) -> Unit,
onError: (e: Throwable) -> Unit
): Coroutine<Pair<List<BookChapter>, 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)
}
}
@@ -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<BookChapter>, _: BookSource ->
viewModel.getToc(book, { toc: List<BookChapter>, _: 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?