优化
This commit is contained in:
@@ -64,6 +64,7 @@ class AnalyzeRule(
|
|||||||
private var analyzeByJSonPath: AnalyzeByJSonPath? = null
|
private var analyzeByJSonPath: AnalyzeByJSonPath? = null
|
||||||
|
|
||||||
private val stringRuleCache = hashMapOf<String, List<SourceRule>>()
|
private val stringRuleCache = hashMapOf<String, List<SourceRule>>()
|
||||||
|
private val regexCache = hashMapOf<String, Regex?>()
|
||||||
|
|
||||||
private var coroutineContext: CoroutineContext = EmptyCoroutineContext
|
private var coroutineContext: CoroutineContext = EmptyCoroutineContext
|
||||||
|
|
||||||
@@ -189,19 +190,20 @@ class AnalyzeRule(
|
|||||||
for (sourceRule in ruleList) {
|
for (sourceRule in ruleList) {
|
||||||
putRule(sourceRule.putMap)
|
putRule(sourceRule.putMap)
|
||||||
sourceRule.makeUpRule(result)
|
sourceRule.makeUpRule(result)
|
||||||
result?.let {
|
result ?: continue
|
||||||
if (sourceRule.rule.isNotEmpty()) {
|
val rule = sourceRule.rule
|
||||||
|
if (rule.isNotEmpty()) {
|
||||||
result = when (sourceRule.mode) {
|
result = when (sourceRule.mode) {
|
||||||
Mode.Js -> evalJS(sourceRule.rule, result)
|
Mode.Js -> evalJS(rule, result)
|
||||||
Mode.Json -> getAnalyzeByJSonPath(it).getStringList(sourceRule.rule)
|
Mode.Json -> getAnalyzeByJSonPath(result).getStringList(rule)
|
||||||
Mode.XPath -> getAnalyzeByXPath(it).getStringList(sourceRule.rule)
|
Mode.XPath -> getAnalyzeByXPath(result).getStringList(rule)
|
||||||
Mode.Default -> getAnalyzeByJSoup(it).getStringList(sourceRule.rule)
|
Mode.Default -> getAnalyzeByJSoup(result).getStringList(rule)
|
||||||
else -> sourceRule.rule
|
else -> rule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sourceRule.replaceRegex.isNotEmpty() && result is List<*>) {
|
if (sourceRule.replaceRegex.isNotEmpty() && result is List<*>) {
|
||||||
val newList = ArrayList<String>()
|
val newList = ArrayList<String>()
|
||||||
for (item in result as List<*>) {
|
for (item in result) {
|
||||||
newList.add(replaceRegex(item.toString(), sourceRule))
|
newList.add(replaceRegex(item.toString(), sourceRule))
|
||||||
}
|
}
|
||||||
result = newList
|
result = newList
|
||||||
@@ -211,15 +213,14 @@ class AnalyzeRule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (result == null) return null
|
if (result == null) return null
|
||||||
if (result is String) {
|
if (result is String) {
|
||||||
result = (result as String).split("\n")
|
result = result.split("\n")
|
||||||
}
|
}
|
||||||
if (isUrl) {
|
if (isUrl) {
|
||||||
val urlList = ArrayList<String>()
|
val urlList = ArrayList<String>()
|
||||||
if (result is List<*>) {
|
if (result is List<*>) {
|
||||||
for (url in result as List<*>) {
|
for (url in result) {
|
||||||
val absoluteURL = NetworkUtils.getAbsoluteURL(redirectUrl, url.toString())
|
val absoluteURL = NetworkUtils.getAbsoluteURL(redirectUrl, url.toString())
|
||||||
if (absoluteURL.isNotEmpty() && !urlList.contains(absoluteURL)) {
|
if (absoluteURL.isNotEmpty() && !urlList.contains(absoluteURL)) {
|
||||||
urlList.add(absoluteURL)
|
urlList.add(absoluteURL)
|
||||||
@@ -276,28 +277,28 @@ class AnalyzeRule(
|
|||||||
for (sourceRule in ruleList) {
|
for (sourceRule in ruleList) {
|
||||||
putRule(sourceRule.putMap)
|
putRule(sourceRule.putMap)
|
||||||
sourceRule.makeUpRule(result)
|
sourceRule.makeUpRule(result)
|
||||||
result?.let {
|
result ?: continue
|
||||||
if (sourceRule.rule.isNotBlank() || sourceRule.replaceRegex.isEmpty()) {
|
val rule = sourceRule.rule
|
||||||
|
if (rule.isNotBlank() || sourceRule.replaceRegex.isEmpty()) {
|
||||||
result = when (sourceRule.mode) {
|
result = when (sourceRule.mode) {
|
||||||
Mode.Js -> evalJS(sourceRule.rule, it)
|
Mode.Js -> evalJS(rule, result)
|
||||||
Mode.Json -> getAnalyzeByJSonPath(it).getString(sourceRule.rule)
|
Mode.Json -> getAnalyzeByJSonPath(result).getString(rule)
|
||||||
Mode.XPath -> getAnalyzeByXPath(it).getString(sourceRule.rule)
|
Mode.XPath -> getAnalyzeByXPath(result).getString(rule)
|
||||||
Mode.Default -> if (isUrl) {
|
Mode.Default -> if (isUrl) {
|
||||||
getAnalyzeByJSoup(it).getString0(sourceRule.rule)
|
getAnalyzeByJSoup(result).getString0(rule)
|
||||||
} else {
|
} else {
|
||||||
getAnalyzeByJSoup(it).getString(sourceRule.rule)
|
getAnalyzeByJSoup(result).getString(rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> sourceRule.rule
|
else -> rule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((result != null) && sourceRule.replaceRegex.isNotEmpty()) {
|
if (result != null && sourceRule.replaceRegex.isNotEmpty()) {
|
||||||
result = replaceRegex(result.toString(), sourceRule)
|
result = replaceRegex(result.toString(), sourceRule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (result == null) result = ""
|
if (result == null) result = ""
|
||||||
val resultStr = result.toString()
|
val resultStr = result.toString()
|
||||||
val str = if (unescape && resultStr.indexOf('&') > -1) {
|
val str = if (unescape && resultStr.indexOf('&') > -1) {
|
||||||
@@ -328,24 +329,24 @@ class AnalyzeRule(
|
|||||||
for (sourceRule in ruleList) {
|
for (sourceRule in ruleList) {
|
||||||
putRule(sourceRule.putMap)
|
putRule(sourceRule.putMap)
|
||||||
sourceRule.makeUpRule(result)
|
sourceRule.makeUpRule(result)
|
||||||
result?.let {
|
result ?: continue
|
||||||
|
val rule = sourceRule.rule
|
||||||
result = when (sourceRule.mode) {
|
result = when (sourceRule.mode) {
|
||||||
Mode.Regex -> AnalyzeByRegex.getElement(
|
Mode.Regex -> AnalyzeByRegex.getElement(
|
||||||
result.toString(),
|
result.toString(),
|
||||||
sourceRule.rule.splitNotBlank("&&")
|
rule.splitNotBlank("&&")
|
||||||
)
|
)
|
||||||
|
|
||||||
Mode.Js -> evalJS(sourceRule.rule, it)
|
Mode.Js -> evalJS(rule, result)
|
||||||
Mode.Json -> getAnalyzeByJSonPath(it).getObject(sourceRule.rule)
|
Mode.Json -> getAnalyzeByJSonPath(result).getObject(rule)
|
||||||
Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule)
|
Mode.XPath -> getAnalyzeByXPath(result).getElements(rule)
|
||||||
else -> getAnalyzeByJSoup(it).getElements(sourceRule.rule)
|
else -> getAnalyzeByJSoup(result).getElements(rule)
|
||||||
}
|
}
|
||||||
if (sourceRule.replaceRegex.isNotEmpty()) {
|
if (sourceRule.replaceRegex.isNotEmpty()) {
|
||||||
result = replaceRegex(result.toString(), sourceRule)
|
result = replaceRegex(result.toString(), sourceRule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,21 +362,18 @@ class AnalyzeRule(
|
|||||||
result = content
|
result = content
|
||||||
for (sourceRule in ruleList) {
|
for (sourceRule in ruleList) {
|
||||||
putRule(sourceRule.putMap)
|
putRule(sourceRule.putMap)
|
||||||
result?.let {
|
result ?: continue
|
||||||
|
val rule = sourceRule.rule
|
||||||
result = when (sourceRule.mode) {
|
result = when (sourceRule.mode) {
|
||||||
Mode.Regex -> AnalyzeByRegex.getElements(
|
Mode.Regex -> AnalyzeByRegex.getElements(
|
||||||
result.toString(),
|
result.toString(),
|
||||||
sourceRule.rule.splitNotBlank("&&")
|
rule.splitNotBlank("&&")
|
||||||
)
|
)
|
||||||
|
|
||||||
Mode.Js -> evalJS(sourceRule.rule, result)
|
Mode.Js -> evalJS(rule, result)
|
||||||
Mode.Json -> getAnalyzeByJSonPath(it).getList(sourceRule.rule)
|
Mode.Json -> getAnalyzeByJSonPath(result).getList(rule)
|
||||||
Mode.XPath -> getAnalyzeByXPath(it).getElements(sourceRule.rule)
|
Mode.XPath -> getAnalyzeByXPath(result).getElements(rule)
|
||||||
else -> getAnalyzeByJSoup(it).getElements(sourceRule.rule)
|
else -> getAnalyzeByJSoup(result).getElements(rule)
|
||||||
}
|
|
||||||
// if (sourceRule.replaceRegex.isNotEmpty()) {
|
|
||||||
// result = replaceRegex(result.toString(), sourceRule)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.base.BaseDialogFragment
|
import io.legado.app.base.BaseDialogFragment
|
||||||
|
import io.legado.app.constant.AppLog
|
||||||
import io.legado.app.constant.EventBus
|
import io.legado.app.constant.EventBus
|
||||||
import io.legado.app.data.appDb
|
import io.legado.app.data.appDb
|
||||||
import io.legado.app.data.entities.Book
|
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.observeEvent
|
||||||
import io.legado.app.utils.setLayout
|
import io.legado.app.utils.setLayout
|
||||||
import io.legado.app.utils.startActivity
|
import io.legado.app.utils.startActivity
|
||||||
import io.legado.app.utils.toastOnUi
|
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -185,7 +185,9 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
|
|||||||
private fun initNavigationView() {
|
private fun initNavigationView() {
|
||||||
binding.toolBar.navigationIcon =
|
binding.toolBar.navigationIcon =
|
||||||
getCompatDrawable(androidx.appcompat.R.drawable.abc_ic_ab_back_material)
|
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 {
|
binding.toolBar.setNavigationOnClickListener {
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
}
|
}
|
||||||
@@ -239,7 +241,7 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
|
|||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(STARTED) {
|
repeatOnLifecycle(STARTED) {
|
||||||
viewModel.finishedChangeSourceResult
|
viewModel.changeSourceProgress
|
||||||
.drop(1)
|
.drop(1)
|
||||||
.collect { (count, name) ->
|
.collect { (count, name) ->
|
||||||
binding.tvDur.text =
|
binding.tvDur.text =
|
||||||
@@ -387,14 +389,14 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
|
|||||||
waitDialog.setText(R.string.load_toc)
|
waitDialog.setText(R.string.load_toc)
|
||||||
waitDialog.show()
|
waitDialog.show()
|
||||||
val book = viewModel.bookMap[searchBook.primaryStr()] ?: searchBook.toBook()
|
val book = viewModel.bookMap[searchBook.primaryStr()] ?: searchBook.toBook()
|
||||||
val coroutine = viewModel.getToc(book, {
|
val coroutine = viewModel.getToc(book, { toc, source ->
|
||||||
waitDialog.dismiss()
|
|
||||||
toastOnUi(it)
|
|
||||||
}) { toc, source ->
|
|
||||||
waitDialog.dismiss()
|
waitDialog.dismiss()
|
||||||
callBack?.changeTo(source, book, toc)
|
callBack?.changeTo(source, book, toc)
|
||||||
onSuccess?.invoke()
|
onSuccess?.invoke()
|
||||||
}
|
}, {
|
||||||
|
waitDialog.dismiss()
|
||||||
|
AppLog.put("换源获取目录出错\n$it", it, true)
|
||||||
|
})
|
||||||
waitDialog.setOnCancelListener {
|
waitDialog.setOnCancelListener {
|
||||||
coroutine.cancel()
|
coroutine.cancel()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
private var searchBookList = arrayListOf<SearchBook>()
|
private var searchBookList = arrayListOf<SearchBook>()
|
||||||
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
|
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
|
||||||
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
|
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
|
||||||
private val _finishedChangeSourceResult = MutableStateFlow(0 to "")
|
private val _changeSourceProgress = MutableStateFlow(0 to "")
|
||||||
val finishedChangeSourceResult= _finishedChangeSourceResult.asStateFlow()
|
val changeSourceProgress = _changeSourceProgress.asStateFlow()
|
||||||
private var tocMapChapterCount = 0
|
private var tocMapChapterCount = 0
|
||||||
private val contentProcessor by lazy {
|
private val contentProcessor by lazy {
|
||||||
ContentProcessor.get(oldBook!!)
|
ContentProcessor.get(oldBook!!)
|
||||||
@@ -191,7 +191,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
tocMap.clear()
|
tocMap.clear()
|
||||||
bookMap.clear()
|
bookMap.clear()
|
||||||
tocMapChapterCount = 0
|
tocMapChapterCount = 0
|
||||||
_finishedChangeSourceResult.value = 0 to ""
|
_changeSourceProgress.value = 0 to ""
|
||||||
val searchGroup = AppConfig.searchGroup
|
val searchGroup = AppConfig.searchGroup
|
||||||
if (searchGroup.isBlank()) {
|
if (searchGroup.isBlank()) {
|
||||||
bookSourceParts.addAll(appDb.bookSourceDao.allEnabledPart)
|
bookSourceParts.addAll(appDb.bookSourceDao.allEnabledPart)
|
||||||
@@ -243,7 +243,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
}
|
}
|
||||||
it
|
it
|
||||||
}.onEachIndexed { index, value ->
|
}.onEachIndexed { index, value ->
|
||||||
_finishedChangeSourceResult.update { _ ->
|
_changeSourceProgress.update { _ ->
|
||||||
index + 1 to value.bookSourceName
|
index + 1 to value.bookSourceName
|
||||||
}
|
}
|
||||||
}.onCompletion {
|
}.onCompletion {
|
||||||
@@ -446,8 +446,8 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
|
|
||||||
fun getToc(
|
fun getToc(
|
||||||
book: Book,
|
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>> {
|
): Coroutine<Pair<List<BookChapter>, BookSource>> {
|
||||||
return execute {
|
return execute {
|
||||||
val toc = tocMap[book.primaryStr()]
|
val toc = tocMap[book.primaryStr()]
|
||||||
@@ -461,7 +461,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
onSuccess.invoke(it.first, it.second)
|
onSuccess.invoke(it.first, it.second)
|
||||||
}.onError {
|
}.onError {
|
||||||
onError.invoke(it.localizedMessage ?: "获取目录出错")
|
onError.invoke(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.base.BaseDialogFragment
|
import io.legado.app.base.BaseDialogFragment
|
||||||
|
import io.legado.app.constant.AppLog
|
||||||
import io.legado.app.constant.EventBus
|
import io.legado.app.constant.EventBus
|
||||||
import io.legado.app.data.appDb
|
import io.legado.app.data.appDb
|
||||||
import io.legado.app.data.entities.Book
|
import io.legado.app.data.entities.Book
|
||||||
@@ -310,16 +311,16 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
|||||||
binding.clToc.visible()
|
binding.clToc.visible()
|
||||||
binding.loadingToc.visible()
|
binding.loadingToc.visible()
|
||||||
val book = searchBook.toBook()
|
val book = searchBook.toBook()
|
||||||
viewModel.getToc(book, {
|
viewModel.getToc(book, { toc: List<BookChapter>, _: BookSource ->
|
||||||
binding.clToc.gone()
|
|
||||||
toastOnUi(it)
|
|
||||||
}) { toc: List<BookChapter>, _: BookSource ->
|
|
||||||
tocAdapter.durChapterIndex =
|
tocAdapter.durChapterIndex =
|
||||||
BookHelp.getDurChapter(viewModel.chapterIndex, viewModel.chapterTitle, toc)
|
BookHelp.getDurChapter(viewModel.chapterIndex, viewModel.chapterTitle, toc)
|
||||||
binding.loadingToc.gone()
|
binding.loadingToc.gone()
|
||||||
tocAdapter.setItems(toc)
|
tocAdapter.setItems(toc)
|
||||||
binding.recyclerViewToc.scrollToPosition(tocAdapter.durChapterIndex - 5)
|
binding.recyclerViewToc.scrollToPosition(tocAdapter.durChapterIndex - 5)
|
||||||
}
|
}, {
|
||||||
|
binding.clToc.gone()
|
||||||
|
AppLog.put("单章换源获取目录出错\n$it", it, true)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override val oldBookUrl: String?
|
override val oldBookUrl: String?
|
||||||
|
|||||||
Reference in New Issue
Block a user