2018-02-24 17:13:43 +01:00
|
|
|
package eu.kanade.tachiyomi.source
|
|
|
|
|
|
|
|
|
|
import android.content.Context
|
2018-07-08 21:51:26 +02:00
|
|
|
import eu.kanade.tachiyomi.R
|
|
|
|
|
import eu.kanade.tachiyomi.source.model.Page
|
|
|
|
|
import eu.kanade.tachiyomi.source.model.SChapter
|
|
|
|
|
import eu.kanade.tachiyomi.source.model.SManga
|
2018-02-24 17:13:43 +01:00
|
|
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
|
|
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.all.EHentai
|
2018-04-14 21:50:05 +02:00
|
|
|
import eu.kanade.tachiyomi.source.online.all.Hitomi
|
2018-02-24 17:13:43 +01:00
|
|
|
import eu.kanade.tachiyomi.source.online.all.NHentai
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.all.PervEden
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.english.*
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.german.WieManga
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.russian.Mangachan
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.russian.Mintmanga
|
|
|
|
|
import eu.kanade.tachiyomi.source.online.russian.Readmanga
|
2018-07-08 21:51:26 +02:00
|
|
|
import rx.Observable
|
2018-02-24 17:13:43 +01:00
|
|
|
import exh.EH_SOURCE_ID
|
|
|
|
|
import exh.EXH_SOURCE_ID
|
|
|
|
|
import exh.PERV_EDEN_EN_SOURCE_ID
|
|
|
|
|
import exh.PERV_EDEN_IT_SOURCE_ID
|
2019-04-06 13:35:36 +02:00
|
|
|
import exh.metadata.metadata.PervEdenLang
|
|
|
|
|
import exh.source.DelegatedHttpSource
|
|
|
|
|
import exh.source.EnhancedHttpSource
|
|
|
|
|
import timber.log.Timber
|
2018-02-24 17:13:43 +01:00
|
|
|
import uy.kohesive.injekt.injectLazy
|
2019-04-06 13:35:36 +02:00
|
|
|
import kotlin.reflect.KClass
|
2018-02-24 17:13:43 +01:00
|
|
|
|
|
|
|
|
open class SourceManager(private val context: Context) {
|
|
|
|
|
|
|
|
|
|
private val prefs: PreferencesHelper by injectLazy()
|
|
|
|
|
|
|
|
|
|
private val sourcesMap = mutableMapOf<Long, Source>()
|
|
|
|
|
|
2018-07-08 21:51:26 +02:00
|
|
|
private val stubSourcesMap = mutableMapOf<Long, StubSource>()
|
|
|
|
|
|
2018-02-24 17:13:43 +01:00
|
|
|
init {
|
|
|
|
|
createInternalSources().forEach { registerSource(it) }
|
2018-02-25 21:34:19 +01:00
|
|
|
|
2018-02-24 17:13:43 +01:00
|
|
|
//Recreate sources when they change
|
|
|
|
|
val prefEntries = arrayOf(
|
|
|
|
|
prefs.enableExhentai(),
|
|
|
|
|
prefs.imageQuality(),
|
|
|
|
|
prefs.useHentaiAtHome(),
|
|
|
|
|
prefs.useJapaneseTitle(),
|
|
|
|
|
prefs.ehSearchSize(),
|
|
|
|
|
prefs.thumbnailRows()
|
|
|
|
|
).map { it.asObservable() }
|
|
|
|
|
|
|
|
|
|
Observable.merge(prefEntries).skip(prefEntries.size - 1).subscribe {
|
2018-02-25 21:34:19 +01:00
|
|
|
createEHSources().forEach { registerSource(it) }
|
2018-02-24 17:13:43 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
open fun get(sourceKey: Long): Source? {
|
|
|
|
|
return sourcesMap[sourceKey]
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-08 21:51:26 +02:00
|
|
|
fun getOrStub(sourceKey: Long): Source {
|
|
|
|
|
return sourcesMap[sourceKey] ?: stubSourcesMap.getOrPut(sourceKey) {
|
|
|
|
|
StubSource(sourceKey)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-24 17:13:43 +01:00
|
|
|
fun getOnlineSources() = sourcesMap.values.filterIsInstance<HttpSource>()
|
|
|
|
|
|
|
|
|
|
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
|
|
|
|
|
|
|
|
|
internal fun registerSource(source: Source, overwrite: Boolean = false) {
|
2019-04-06 13:35:36 +02:00
|
|
|
val sourceQName = source::class.qualifiedName
|
|
|
|
|
val delegate = DELEGATED_SOURCES[sourceQName]
|
|
|
|
|
val newSource = if(source is HttpSource && delegate != null) {
|
|
|
|
|
Timber.d("[EXH] Delegating source: %s -> %s!", sourceQName, delegate.newSourceClass.qualifiedName)
|
|
|
|
|
EnhancedHttpSource(
|
|
|
|
|
source,
|
|
|
|
|
delegate.newSourceClass.constructors.find { it.parameters.size == 1 }!!.call(source)
|
|
|
|
|
)
|
|
|
|
|
} else source
|
2018-02-24 17:13:43 +01:00
|
|
|
if (overwrite || !sourcesMap.containsKey(source.id)) {
|
2019-04-06 13:35:36 +02:00
|
|
|
sourcesMap[source.id] = newSource
|
2018-02-24 17:13:43 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal fun unregisterSource(source: Source) {
|
|
|
|
|
sourcesMap.remove(source.id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun createInternalSources(): List<Source> = listOf(
|
|
|
|
|
LocalSource(context),
|
|
|
|
|
Batoto(),
|
|
|
|
|
Mangahere(),
|
|
|
|
|
Mangafox(),
|
|
|
|
|
Kissmanga(),
|
|
|
|
|
Readmanga(),
|
|
|
|
|
Mintmanga(),
|
|
|
|
|
Mangachan(),
|
|
|
|
|
Readmangatoday(),
|
|
|
|
|
Mangasee(),
|
|
|
|
|
WieManga()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
private fun createEHSources(): List<Source> {
|
|
|
|
|
val exSrcs = mutableListOf<HttpSource>(
|
|
|
|
|
EHentai(EH_SOURCE_ID, false, context)
|
|
|
|
|
)
|
|
|
|
|
if(prefs.enableExhentai().getOrDefault()) {
|
|
|
|
|
exSrcs += EHentai(EXH_SOURCE_ID, true, context)
|
|
|
|
|
}
|
|
|
|
|
exSrcs += PervEden(PERV_EDEN_EN_SOURCE_ID, PervEdenLang.en)
|
|
|
|
|
exSrcs += PervEden(PERV_EDEN_IT_SOURCE_ID, PervEdenLang.it)
|
|
|
|
|
exSrcs += NHentai(context)
|
2018-02-25 21:34:19 +01:00
|
|
|
exSrcs += Tsumino(context)
|
2019-04-06 13:35:36 +02:00
|
|
|
exSrcs += Hitomi()
|
2018-02-24 17:13:43 +01:00
|
|
|
return exSrcs
|
|
|
|
|
}
|
2018-07-08 21:51:26 +02:00
|
|
|
|
|
|
|
|
private inner class StubSource(override val id: Long) : Source {
|
|
|
|
|
|
|
|
|
|
override val name: String
|
|
|
|
|
get() = id.toString()
|
|
|
|
|
|
|
|
|
|
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
|
|
|
|
return Observable.error(getSourceNotInstalledException())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
|
|
|
|
return Observable.error(getSourceNotInstalledException())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
|
|
|
|
return Observable.error(getSourceNotInstalledException())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun toString(): String {
|
|
|
|
|
return name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun getSourceNotInstalledException(): Exception {
|
|
|
|
|
return Exception(context.getString(R.string.source_not_installed, id.toString()))
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-06 13:35:36 +02:00
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
val DELEGATED_SOURCES = listOf(
|
|
|
|
|
DelegatedSource(
|
|
|
|
|
"Hentai Cafe",
|
|
|
|
|
260868874183818481,
|
|
|
|
|
"eu.kanade.tachiyomi.extension.all.foolslide.HentaiCafe",
|
|
|
|
|
HentaiCafe::class
|
|
|
|
|
)
|
|
|
|
|
).associateBy { it.originalSourcePackageName }
|
|
|
|
|
|
|
|
|
|
data class DelegatedSource(val sourceName: String,
|
|
|
|
|
val sourceId: Long,
|
|
|
|
|
val originalSourcePackageName: String,
|
|
|
|
|
val newSourceClass: KClass<out DelegatedHttpSource>)
|
|
|
|
|
}
|
2018-02-24 17:13:43 +01:00
|
|
|
}
|