This commit is contained in:
Horis
2025-01-22 21:34:10 +08:00
parent 5caa3b876e
commit 36672b12da
5 changed files with 43 additions and 50 deletions
@@ -45,7 +45,7 @@ object Rss {
) )
val res = analyzeUrl.getStrResponseAwait() val res = analyzeUrl.getStrResponseAwait()
checkRedirect(rssSource, res) checkRedirect(rssSource, res)
return RssParserByRule.parseXML(sortName, sortUrl, res.body, rssSource, ruleData) return RssParserByRule.parseXML(sortName, sortUrl, res.url, res.body, rssSource, ruleData)
} }
fun getContent( fun getContent(
@@ -79,6 +79,7 @@ object Rss {
val analyzeRule = AnalyzeRule(rssArticle, rssSource) val analyzeRule = AnalyzeRule(rssArticle, rssSource)
analyzeRule.setContent(res.body) analyzeRule.setContent(res.body)
.setBaseUrl(NetworkUtils.getAbsoluteURL(rssArticle.origin, rssArticle.link)) .setBaseUrl(NetworkUtils.getAbsoluteURL(rssArticle.origin, rssArticle.link))
.setRedirectUrl(res.url)
return analyzeRule.getString(ruleContent) return analyzeRule.getString(ruleContent)
} }
@@ -10,7 +10,7 @@ import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.RuleData import io.legado.app.model.analyzeRule.RuleData
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
import splitties.init.appCtx import splitties.init.appCtx
import java.util.* import java.util.Locale
@Keep @Keep
object RssParserByRule { object RssParserByRule {
@@ -19,6 +19,7 @@ object RssParserByRule {
fun parseXML( fun parseXML(
sortName: String, sortName: String,
sortUrl: String, sortUrl: String,
redirectUrl: String,
body: String?, body: String?,
rssSource: RssSource, rssSource: RssSource,
ruleData: RuleData ruleData: RuleData
@@ -40,7 +41,7 @@ object RssParserByRule {
val articleList = mutableListOf<RssArticle>() val articleList = mutableListOf<RssArticle>()
val analyzeRule = AnalyzeRule(ruleData, rssSource) val analyzeRule = AnalyzeRule(ruleData, rssSource)
analyzeRule.setContent(body).setBaseUrl(sortUrl) analyzeRule.setContent(body).setBaseUrl(sortUrl)
analyzeRule.setRedirectUrl(sortUrl) analyzeRule.setRedirectUrl(redirectUrl)
var reverse = false var reverse = false
if (ruleArticles.startsWith("-")) { if (ruleArticles.startsWith("-")) {
reverse = true reverse = true
@@ -5,7 +5,7 @@ import io.legado.app.utils.FileDoc
data class ImportBook( data class ImportBook(
val file: FileDoc, val file: FileDoc,
var isOnBookShelf: Boolean = LocalBook.isOnBookShelf(file.name) var isOnBookShelf: Boolean = !file.isDir && LocalBook.isOnBookShelf(file.name)
) { ) {
val name get() = file.name val name get() = file.name
val isDir get() = file.isDir val isDir get() = file.isDir
@@ -253,10 +253,9 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
binding.refreshProgressBar.isAutoLoading = true binding.refreshProgressBar.isAutoLoading = true
scanDocJob?.cancel() scanDocJob?.cancel()
scanDocJob = lifecycleScope.launch(IO) { scanDocJob = lifecycleScope.launch(IO) {
viewModel.scanDoc(lastDoc, true) { viewModel.scanDoc(lastDoc)
withContext(Main) { withContext(Main) {
binding.refreshProgressBar.isAutoLoading = false binding.refreshProgressBar.isAutoLoading = false
}
} }
} }
} }
@@ -12,18 +12,23 @@ import io.legado.app.utils.FileDoc
import io.legado.app.utils.delete import io.legado.app.utils.delete
import io.legado.app.utils.getPrefInt import io.legado.app.utils.getPrefInt
import io.legado.app.utils.list import io.legado.app.utils.list
import io.legado.app.utils.mapParallel
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.Collections import java.util.Collections
import kotlin.coroutines.coroutineContext
class ImportBookViewModel(application: Application) : BaseViewModel(application) { class ImportBookViewModel(application: Application) : BaseViewModel(application) {
var rootDoc: FileDoc? = null var rootDoc: FileDoc? = null
@@ -98,6 +103,8 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
}.onError { }.onError {
context.toastOnUi("添加书架失败,请尝试重新选择文件夹") context.toastOnUi("添加书架失败,请尝试重新选择文件夹")
AppLog.put("添加书架失败\n${it.localizedMessage}", it) AppLog.put("添加书架失败\n${it.localizedMessage}", it)
}.onSuccess {
context.toastOnUi("添加书架成功")
}.onFinally { }.onFinally {
finally.invoke() finally.invoke()
} }
@@ -128,47 +135,32 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
} }
} }
suspend fun scanDoc( suspend fun scanDoc(fileDoc: FileDoc) {
fileDoc: FileDoc, dataCallback?.clear()
isRoot: Boolean, val channel = Channel<FileDoc>(UNLIMITED)
finally: (suspend () -> Unit)? = null var n = 1
) { channel.trySend(fileDoc)
if (isRoot) { val list = arrayListOf<FileDoc>()
dataCallback?.clear() channel.consumeAsFlow()
} .mapParallel(64) { fileDoc ->
if (!coroutineContext.isActive) { fileDoc.list()!!
finally?.invoke() }.onEach { fileDocs ->
return n--
} list.clear()
kotlin.runCatching { fileDocs.forEach {
val list = ArrayList<FileDoc>() if (it.isDir) {
fileDoc.list()!!.forEach { docItem -> n++
if (!coroutineContext.isActive) { channel.trySend(it)
finally?.invoke() } else {
return list.add(it)
}
} }
if (docItem.isDir) {
scanDoc(docItem, false)
} else if (docItem.name.matches(bookFileRegex) || docItem.name.matches(
archiveFileRegex
)
) {
list.add(docItem)
}
}
if (!coroutineContext.isActive) {
finally?.invoke()
return
}
if (list.isNotEmpty()) {
dataCallback?.addItems(list) dataCallback?.addItems(list)
} }.takeWhile {
}.onFailure { n > 0
context.toastOnUi("扫描文件夹出错\n${it.localizedMessage}") }.catch {
} context.toastOnUi("扫描文件夹出错\n${it.localizedMessage}")
if (isRoot) { }.collect()
finally?.invoke()
}
} }
fun updateCallBackFlow(filterKey: String?) { fun updateCallBackFlow(filterKey: String?) {