Refactor SourceManager/StubSource to domain module
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package eu.kanade.tachiyomi.source
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import tachiyomi.domain.source.model.SourceData
|
||||
import tachiyomi.domain.source.model.StubSource
|
||||
import tachiyomi.domain.source.repository.SourceDataRepository
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
import tachiyomi.source.local.LocalSource
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class AndroidSourceManager(
|
||||
private val context: Context,
|
||||
private val extensionManager: ExtensionManager,
|
||||
private val sourceRepository: SourceDataRepository,
|
||||
) : SourceManager {
|
||||
private val downloadManager: DownloadManager by injectLazy()
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
|
||||
private val sourcesMapFlow = MutableStateFlow(ConcurrentHashMap<Long, Source>())
|
||||
|
||||
private val stubSourcesMap = ConcurrentHashMap<Long, StubSource>()
|
||||
|
||||
override val catalogueSources: Flow<List<CatalogueSource>> = sourcesMapFlow.map { it.values.filterIsInstance<CatalogueSource>() }
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
extensionManager.installedExtensionsFlow
|
||||
.collectLatest { extensions ->
|
||||
val mutableMap = ConcurrentHashMap<Long, Source>(
|
||||
mapOf(
|
||||
LocalSource.ID to LocalSource(
|
||||
context,
|
||||
Injekt.get(),
|
||||
Injekt.get(),
|
||||
),
|
||||
),
|
||||
)
|
||||
extensions.forEach { extension ->
|
||||
extension.sources.forEach {
|
||||
mutableMap[it.id] = it
|
||||
registerStubSource(it.toSourceData())
|
||||
}
|
||||
}
|
||||
sourcesMapFlow.value = mutableMap
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch {
|
||||
sourceRepository.subscribeAll()
|
||||
.collectLatest { sources ->
|
||||
val mutableMap = stubSourcesMap.toMutableMap()
|
||||
sources.forEach {
|
||||
mutableMap[it.id] = StubSource(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun get(sourceKey: Long): Source? {
|
||||
return sourcesMapFlow.value[sourceKey]
|
||||
}
|
||||
|
||||
override fun getOrStub(sourceKey: Long): Source {
|
||||
return sourcesMapFlow.value[sourceKey] ?: stubSourcesMap.getOrPut(sourceKey) {
|
||||
runBlocking { createStubSource(sourceKey) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getOnlineSources() = sourcesMapFlow.value.values.filterIsInstance<HttpSource>()
|
||||
|
||||
override fun getCatalogueSources() = sourcesMapFlow.value.values.filterIsInstance<CatalogueSource>()
|
||||
|
||||
override fun getStubSources(): List<StubSource> {
|
||||
val onlineSourceIds = getOnlineSources().map { it.id }
|
||||
return stubSourcesMap.values.filterNot { it.id in onlineSourceIds }
|
||||
}
|
||||
|
||||
private fun registerStubSource(sourceData: SourceData) {
|
||||
scope.launch {
|
||||
val (id, lang, name) = sourceData
|
||||
val dbSourceData = sourceRepository.getSourceData(id)
|
||||
if (dbSourceData == sourceData) return@launch
|
||||
sourceRepository.upsertSourceData(id, lang, name)
|
||||
if (dbSourceData != null) {
|
||||
downloadManager.renameSource(StubSource(dbSourceData), StubSource(sourceData))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createStubSource(id: Long): StubSource {
|
||||
sourceRepository.getSourceData(id)?.let {
|
||||
return StubSource(it)
|
||||
}
|
||||
extensionManager.getSourceData(id)?.let {
|
||||
registerStubSource(it)
|
||||
return StubSource(it)
|
||||
}
|
||||
return StubSource(SourceData(id, "", ""))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user