修复发现页书源互相污染的问题

This commit is contained in:
HapeLee
2026-05-24 01:16:08 +08:00
parent d2853244be
commit 5b59b5a743
5 changed files with 36 additions and 24 deletions
@@ -5,8 +5,10 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
import io.legado.app.data.entities.SearchBook
import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.domain.gateway.ExploreBooksGateway
import io.legado.app.help.source.SourceHelp
import io.legado.app.help.source.exploreKinds
import io.legado.app.model.webBook.WebBook
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
@@ -16,7 +18,7 @@ interface ExploreRepository {
fun getBookshelfItems(): Flow<List<SearchBook>>
fun getExploreGroups(): Flow<List<String>>
fun getExploreSources(query: String, selectedGroup: String): Flow<List<BookSourcePart>>
suspend fun getBookSource(url: String): BookSource?
suspend fun getBookSource(sourceUrl: String): BookSource?
suspend fun saveSearchBooks(books: List<SearchBook>)
suspend fun getSourceExploreKinds(sourceUrl: String): List<ExploreKind>
suspend fun topSource(bookSource: BookSourcePart)
@@ -25,7 +27,7 @@ interface ExploreRepository {
class ExploreRepositoryImpl(
private val appDb: AppDatabase
) : ExploreRepository {
) : ExploreRepository, ExploreBooksGateway {
override fun getBookshelfItems(): Flow<List<SearchBook>> {
return appDb.bookDao.flowBookShelf().map { books ->
@@ -71,8 +73,16 @@ class ExploreRepositoryImpl(
}
}
override suspend fun getBookSource(url: String): BookSource? {
return appDb.bookSourceDao.getBookSource(url)
override suspend fun getBookSource(sourceUrl: String): BookSource? {
return appDb.bookSourceDao.getBookSource(sourceUrl)
}
override suspend fun exploreBooks(
bookSource: BookSource,
url: String,
page: Int
): List<SearchBook> {
return WebBook.exploreBookSuspend(bookSource, url, page)
}
override suspend fun getSourceExploreKinds(sourceUrl: String): List<ExploreKind> = withContext(IO) {
@@ -39,6 +39,7 @@ import io.legado.app.domain.gateway.BookCacheDownloadGateway
import io.legado.app.domain.gateway.BookSearchGateway
import io.legado.app.domain.gateway.BookSourceCallbackGateway
import io.legado.app.domain.gateway.DatabaseMaintenanceGateway
import io.legado.app.domain.gateway.ExploreBooksGateway
import io.legado.app.domain.gateway.HomepageModulesGateway
import io.legado.app.domain.gateway.LocalBookGateway
import io.legado.app.domain.gateway.ReadingProgressGateway
@@ -173,7 +174,9 @@ val appModule = module {
single<ReadingProgressGateway> { WebDavReadingProgressRepository() }
single<HomepageModulesGateway> { HomepageModulesRepository(get(), get()) }
single<BookDomainRepository> { BookDomainRepositoryImpl(get(), get()) }
single<ExploreRepository> { ExploreRepositoryImpl(get()) }
single { ExploreRepositoryImpl(get()) }
single<ExploreRepository> { get<ExploreRepositoryImpl>() }
single<ExploreBooksGateway> { get<ExploreRepositoryImpl>() }
singleOf(::RssRepository)
single {
SearchRepositoryImpl(get())
@@ -0,0 +1,9 @@
package io.legado.app.domain.gateway
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
interface ExploreBooksGateway {
suspend fun getBookSource(sourceUrl: String): BookSource?
suspend fun exploreBooks(bookSource: BookSource, url: String, page: Int): List<SearchBook>
}
@@ -1,13 +1,12 @@
package io.legado.app.domain.usecase
import io.legado.app.data.entities.SearchBook
import io.legado.app.data.repository.BookSourceRepository
import io.legado.app.model.webBook.WebBook
import io.legado.app.domain.gateway.ExploreBooksGateway
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class ExploreBooksUseCase(
private val bookSourceRepository: BookSourceRepository,
private val gateway: ExploreBooksGateway,
) {
companion object {
/** 排名类模块自动加载的最大书本数 */
@@ -23,18 +22,12 @@ class ExploreBooksUseCase(
args: String?,
page: Int = 1
): ExploreResult = withContext(Dispatchers.IO) {
val base = bookSourceRepository.getBookSource(sourceUrl)
val base = gateway.getBookSource(sourceUrl)
?: throw SourceNotFound(sourceUrl)
val source = args?.let { base.copy().also { s -> s.setVariable(it) } } ?: base
val resolvedUrl = moduleUrl ?: source.exploreUrl
?: throw NoExploreUrl(sourceUrl)
if (!resolvedUrl.startsWith("http", ignoreCase = true)
&& !resolvedUrl.startsWith("data:", ignoreCase = true)
&& !resolvedUrl.startsWith("{{")
) {
throw InvalidUrl(resolvedUrl)
}
val books = WebBook.exploreBookSuspend(source, resolvedUrl, page)
val books = gateway.exploreBooks(source, resolvedUrl, page)
ExploreResult(resolvedUrl, books)
}
@@ -49,13 +42,10 @@ class ExploreBooksUseCase(
while (books.size < MAX_RANKING_BOOKS && page < MAX_RANKING_PAGES) {
page++
val next = try {
WebBook.exploreBookSuspend(
bookSourceRepository.getBookSource(sourceUrl)
?.let { s -> args?.let { s.copy().also { x -> x.setVariable(it) } } ?: s }
?: return@withContext books.take(MAX_RANKING_BOOKS),
result.resolvedUrl,
page,
)
val source = gateway.getBookSource(sourceUrl)
?.let { s -> args?.let { s.copy().also { x -> x.setVariable(it) } } ?: s }
?: return@withContext books.take(MAX_RANKING_BOOKS)
gateway.exploreBooks(source, result.resolvedUrl, page)
} catch (_: Exception) {
emptyList()
}
@@ -69,5 +59,4 @@ class ExploreBooksUseCase(
class SourceNotFound(url: String) : Exception("Source not found: ${url.take(60)}")
class NoExploreUrl(url: String) : Exception("No explore URL for source: ${url.take(60)}")
class InvalidUrl(url: String) : Exception("Invalid explore URL: ${url.take(80)}")
}
@@ -136,6 +136,7 @@ class ExploreShowViewModel(
sourceUrl = incomingSourceUrl
exploreUrl = incomingExploreUrl
page = 1
bookSource = null
_rawBooks.value = emptyList()
_isEndStateFlow.value = false
_errorMsg.value = null