mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Maintain source info in the database. (#6389)
* Maintain Source Info in database * Review changes and cleanups * Review changes 2 * Review Changes 3
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.source
 | 
			
		||||
 | 
			
		||||
import android.graphics.drawable.Drawable
 | 
			
		||||
import eu.kanade.domain.source.model.SourceData
 | 
			
		||||
import eu.kanade.tachiyomi.extension.ExtensionManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.SChapter
 | 
			
		||||
@@ -102,3 +103,5 @@ interface Source : tachiyomi.source.Source {
 | 
			
		||||
fun Source.icon(): Drawable? = Injekt.get<ExtensionManager>().getAppIconForSource(this)
 | 
			
		||||
 | 
			
		||||
fun Source.getPreferenceKey(): String = "source_$id"
 | 
			
		||||
 | 
			
		||||
fun Source.toSourceData(): SourceData = SourceData(id = id, lang = lang, name = name)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,32 @@
 | 
			
		||||
package eu.kanade.tachiyomi.source
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import eu.kanade.domain.source.interactor.GetSourceData
 | 
			
		||||
import eu.kanade.domain.source.interactor.UpsertSourceData
 | 
			
		||||
import eu.kanade.domain.source.model.SourceData
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.extension.ExtensionManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.SChapter
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.SManga
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchIO
 | 
			
		||||
import kotlinx.coroutines.flow.Flow
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.map
 | 
			
		||||
import kotlinx.coroutines.flow.update
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import tachiyomi.source.model.ChapterInfo
 | 
			
		||||
import tachiyomi.source.model.MangaInfo
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
class SourceManager(private val context: Context) {
 | 
			
		||||
 | 
			
		||||
    private val extensionManager: ExtensionManager by injectLazy()
 | 
			
		||||
    private val getSourceData: GetSourceData by injectLazy()
 | 
			
		||||
    private val upsertSourceData: UpsertSourceData by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private val sourcesMap = mutableMapOf<Long, Source>()
 | 
			
		||||
    private val stubSourcesMap = mutableMapOf<Long, StubSource>()
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +45,7 @@ class SourceManager(private val context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun getOrStub(sourceKey: Long): Source {
 | 
			
		||||
        return sourcesMap[sourceKey] ?: stubSourcesMap.getOrPut(sourceKey) {
 | 
			
		||||
            StubSource(sourceKey)
 | 
			
		||||
            runBlocking { createStubSource(sourceKey) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -42,16 +53,32 @@ class SourceManager(private val context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
 | 
			
		||||
 | 
			
		||||
    fun getStubSources(): List<StubSource> {
 | 
			
		||||
        val onlineSourceIds = getOnlineSources().map { it.id }
 | 
			
		||||
        return stubSourcesMap.values.filterNot { it.id in onlineSourceIds }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal fun registerSource(source: Source) {
 | 
			
		||||
        if (!sourcesMap.containsKey(source.id)) {
 | 
			
		||||
            sourcesMap[source.id] = source
 | 
			
		||||
        }
 | 
			
		||||
        if (!stubSourcesMap.containsKey(source.id)) {
 | 
			
		||||
            stubSourcesMap[source.id] = StubSource(source.id)
 | 
			
		||||
        }
 | 
			
		||||
        registerStubSource(source.toSourceData())
 | 
			
		||||
        triggerCatalogueSources()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun registerStubSource(sourceData: SourceData) {
 | 
			
		||||
        launchIO {
 | 
			
		||||
            val dbSourceData = getSourceData.await(sourceData.id)
 | 
			
		||||
 | 
			
		||||
            if (dbSourceData != sourceData) {
 | 
			
		||||
                upsertSourceData.await(sourceData)
 | 
			
		||||
            }
 | 
			
		||||
            if (stubSourcesMap[sourceData.id]?.toSourceData() != sourceData) {
 | 
			
		||||
                stubSourcesMap[sourceData.id] = StubSource(sourceData)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal fun unregisterSource(source: Source) {
 | 
			
		||||
        sourcesMap.remove(source.id)
 | 
			
		||||
        triggerCatalogueSources()
 | 
			
		||||
@@ -67,11 +94,24 @@ class SourceManager(private val context: Context) {
 | 
			
		||||
        LocalSource(context),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private suspend fun createStubSource(id: Long): StubSource {
 | 
			
		||||
        getSourceData.await(id)?.let {
 | 
			
		||||
            return StubSource(it)
 | 
			
		||||
        }
 | 
			
		||||
        extensionManager.getSourceData(id)?.let {
 | 
			
		||||
            registerStubSource(it)
 | 
			
		||||
            return StubSource(it)
 | 
			
		||||
        }
 | 
			
		||||
        return StubSource(SourceData(id, "", ""))
 | 
			
		||||
    }
 | 
			
		||||
    @Suppress("OverridingDeprecatedMember")
 | 
			
		||||
    inner class StubSource(override val id: Long) : Source {
 | 
			
		||||
    open inner class StubSource(val sourceData: SourceData) : Source {
 | 
			
		||||
 | 
			
		||||
        override val name: String
 | 
			
		||||
            get() = id.toString()
 | 
			
		||||
        override val name: String = sourceData.name
 | 
			
		||||
 | 
			
		||||
        override val lang: String = sourceData.lang
 | 
			
		||||
 | 
			
		||||
        override val id: Long = sourceData.id
 | 
			
		||||
 | 
			
		||||
        override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo {
 | 
			
		||||
            throw getSourceNotInstalledException()
 | 
			
		||||
@@ -98,14 +138,17 @@ class SourceManager(private val context: Context) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        override fun toString(): String {
 | 
			
		||||
            return name
 | 
			
		||||
            if (name.isNotBlank() && lang.isNotBlank()) {
 | 
			
		||||
                return "$name (${lang.uppercase()})"
 | 
			
		||||
            }
 | 
			
		||||
            return id.toString()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private fun getSourceNotInstalledException(): SourceNotInstalledException {
 | 
			
		||||
            return SourceNotInstalledException(id)
 | 
			
		||||
        fun getSourceNotInstalledException(): SourceNotInstalledException {
 | 
			
		||||
            return SourceNotInstalledException(toString())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inner class SourceNotInstalledException(val id: Long) :
 | 
			
		||||
        Exception(context.getString(R.string.source_not_installed, id.toString()))
 | 
			
		||||
    inner class SourceNotInstalledException(val sourceString: String) :
 | 
			
		||||
        Exception(context.getString(R.string.source_not_installed, sourceString))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user