unhide and begin working on merged sources

This commit is contained in:
Rani Sargees 2020-01-11 05:04:23 -05:00 committed by Jobobby04
parent 5f94e230f9
commit 9ed7ee65c3

View File

@ -1,22 +1,31 @@
package eu.kanade.tachiyomi.source.online.all package eu.kanade.tachiyomi.source.online.all
import android.util.Log
import com.elvishew.xlog.XLog
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import com.lvla.rxjava.interopkt.toV1Observable
import com.lvla.rxjava.interopkt.toV1Single
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.FilterList
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.source.online.HttpSource
import exh.MERGED_SOURCE_ID import exh.MERGED_SOURCE_ID
import exh.util.await import exh.util.await
import hu.akarnokd.rxjava.interop.RxJavaInterop
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.rx2.asFlowable import kotlinx.coroutines.rx2.asFlowable
import kotlinx.coroutines.rx2.asSingle import kotlinx.coroutines.rx2.asSingle
import okhttp3.Response import okhttp3.Response
@ -43,63 +52,74 @@ class MergedSource : HttpSource() {
override fun latestUpdatesParse(response: Response) = throw UnsupportedOperationException() override fun latestUpdatesParse(response: Response) = throw UnsupportedOperationException()
override fun fetchMangaDetails(manga: SManga): Observable<SManga> { override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return readMangaConfig(manga).load(db, sourceManager).take(1).map { loaded -> return RxJavaInterop.toV1Observable(
SManga.create().apply { readMangaConfig(manga).load(db, sourceManager).take(1).map { loaded ->
this.copyFrom(loaded.manga) SManga.create().apply {
url = manga.url this.copyFrom(loaded.manga)
} url = manga.url
}.asFlowable().toV1Observable()
}
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return GlobalScope.async(Dispatchers.IO) {
val loadedMangas = readMangaConfig(manga).load(db, sourceManager).buffer()
loadedMangas.map { loadedManga ->
async(Dispatchers.IO) {
loadedManga.source.fetchChapterList(loadedManga.manga).map { chapterList ->
chapterList.map { chapter ->
chapter.apply {
url = writeUrlConfig(UrlConfig(loadedManga.source.id, url, loadedManga.manga.url))
}
}
}.toSingle().await(Schedulers.io())
} }
}.buffer().map { it.await() }.toList().flatten() }.asFlowable()
}.asSingle(Dispatchers.IO).toV1Single().toObservable() )
} }
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return RxJavaInterop.toV1Single(
GlobalScope.async(Dispatchers.IO) {
val loadedMangas = readMangaConfig(manga).load(db, sourceManager).buffer()
loadedMangas.map { loadedManga ->
async(Dispatchers.IO) {
loadedManga.source.fetchChapterList(loadedManga.manga).map { chapterList ->
chapterList.map { chapter ->
chapter.apply {
url = writeUrlConfig(UrlConfig(loadedManga.source.id, url, loadedManga.manga.url))
}
}
}.toSingle().await(Schedulers.io())
}
}.buffer().map { it.await() }.toList().flatten()
}.asSingle(Dispatchers.IO)
).toObservable()
}
override fun mangaDetailsParse(response: Response) = throw UnsupportedOperationException() override fun mangaDetailsParse(response: Response) = throw UnsupportedOperationException()
override fun chapterListParse(response: Response) = throw UnsupportedOperationException() override fun chapterListParse(response: Response) = throw UnsupportedOperationException()
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> { override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
val config = readUrlConfig(chapter.url) val config = readUrlConfig(chapter.url)
val source = sourceManager.getOrStub(config.source) val source = sourceManager.getOrStub(config.source)
return source.fetchPageList(SChapter.create().apply { return source.fetchPageList(
copyFrom(chapter) SChapter.create().apply {
url = config.url copyFrom(chapter)
}).map { pages -> url = config.url
}
).map { pages ->
pages.map { page -> pages.map { page ->
page.copyWithUrl(writeUrlConfig(UrlConfig(config.source, page.url, config.mangaUrl))) page.copyWithUrl(writeUrlConfig(UrlConfig(config.source, page.url, config.mangaUrl)))
} }
} }
} }
override fun fetchImageUrl(page: Page): Observable<String> { override fun fetchImageUrl(page: Page): Observable<String> {
val config = readUrlConfig(page.url) val config = readUrlConfig(page.url)
val source = sourceManager.getOrStub(config.source) as? HttpSource val source = sourceManager.getOrStub(config.source) as? HttpSource
?: throw UnsupportedOperationException("This source does not support this operation!") ?: throw UnsupportedOperationException("This source does not support this operation!")
return source.fetchImageUrl(page.copyWithUrl(config.url)) return source.fetchImageUrl(page.copyWithUrl(config.url))
} }
override fun pageListParse(response: Response) = throw UnsupportedOperationException() override fun pageListParse(response: Response) = throw UnsupportedOperationException()
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException() override fun imageUrlParse(response: Response) = throw UnsupportedOperationException()
override fun fetchImage(page: Page): Observable<Response> { override fun fetchImage(page: Page): Observable<Response> {
val config = readUrlConfig(page.url) val config = readUrlConfig(page.url)
val source = sourceManager.getOrStub(config.source) as? HttpSource val source = sourceManager.getOrStub(config.source) as? HttpSource
?: throw UnsupportedOperationException("This source does not support this operation!") ?: throw UnsupportedOperationException("This source does not support this operation!")
return source.fetchImage(page.copyWithUrl(config.url)) return source.fetchImage(page.copyWithUrl(config.url))
} }
override fun prepareNewChapter(chapter: SChapter, manga: SManga) { override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
val chapterConfig = readUrlConfig(chapter.url) val chapterConfig = readUrlConfig(chapter.url)
val source = sourceManager.getOrStub(chapterConfig.source) as? HttpSource val source = sourceManager.getOrStub(chapterConfig.source) as? HttpSource
?: throw UnsupportedOperationException("This source does not support this operation!") ?: throw UnsupportedOperationException("This source does not support this operation!")
val copiedManga = SManga.create().apply { val copiedManga = SManga.create().apply {
this.copyFrom(manga) this.copyFrom(manga)
url = chapterConfig.mangaUrl url = chapterConfig.mangaUrl
@ -107,40 +127,48 @@ class MergedSource : HttpSource() {
chapter.url = chapterConfig.url chapter.url = chapterConfig.url
source.prepareNewChapter(chapter, copiedManga) source.prepareNewChapter(chapter, copiedManga)
chapter.url = writeUrlConfig(UrlConfig(source.id, chapter.url, chapterConfig.mangaUrl)) chapter.url = writeUrlConfig(UrlConfig(source.id, chapter.url, chapterConfig.mangaUrl))
chapter.scanlator = if(chapter.scanlator.isNullOrBlank()) source.name chapter.scanlator = if (chapter.scanlator.isNullOrBlank()) source.name
else "$source: ${chapter.scanlator}" else "$source: ${chapter.scanlator}"
} }
fun readMangaConfig(manga: SManga): MangaConfig { fun readMangaConfig(manga: SManga): MangaConfig {
return MangaConfig.readFromUrl(gson, manga.url) return MangaConfig.readFromUrl(gson, manga.url)
} }
fun readUrlConfig(url: String): UrlConfig { fun readUrlConfig(url: String): UrlConfig {
return gson.fromJson(url) return gson.fromJson(url)
} }
fun writeUrlConfig(urlConfig: UrlConfig): String { fun writeUrlConfig(urlConfig: UrlConfig): String {
return gson.toJson(urlConfig) return gson.toJson(urlConfig)
} }
data class LoadedMangaSource(val source: Source, val manga: Manga) data class LoadedMangaSource(val source: Source, val manga: Manga)
data class MangaSource( data class MangaSource(
@SerializedName("s") @SerializedName("s")
val source: Long, val source: Long,
@SerializedName("u") @SerializedName("u")
val url: String val url: String
) { ) {
suspend fun load(db: DatabaseHelper, sourceManager: SourceManager): LoadedMangaSource? { suspend fun load(db: DatabaseHelper, sourceManager: SourceManager): LoadedMangaSource? {
val manga = db.getManga(url, source).await() ?: return null val manga = db.getManga(url, source).executeAsBlocking() ?: return null
val source = sourceManager.getOrStub(source) val source = sourceManager.getOrStub(source)
return LoadedMangaSource(source, manga) return LoadedMangaSource(source, manga)
} }
} }
data class MangaConfig( data class MangaConfig(
@SerializedName("c") @SerializedName("c")
val children: List<MangaSource> val children: List<MangaSource>
) { ) {
fun load(db: DatabaseHelper, sourceManager: SourceManager): Flow<LoadedMangaSource> { fun load(db: DatabaseHelper, sourceManager: SourceManager): Flow<LoadedMangaSource> {
return children.asFlow().map { mangaSource -> return children.asFlow().map { mangaSource ->
mangaSource.load(db, sourceManager) mangaSource.load(db, sourceManager)
?: throw IllegalStateException("Missing source manga: $mangaSource") ?: run {
XLog.w("> Missing source manga: $mangaSource")
Log.d("MERGED", "> Missing source manga: $mangaSource")
throw IllegalStateException("Missing source manga: $mangaSource")
}
} }
} }
@ -154,23 +182,24 @@ class MergedSource : HttpSource() {
} }
} }
} }
data class UrlConfig( data class UrlConfig(
@SerializedName("s") @SerializedName("s")
val source: Long, val source: Long,
@SerializedName("u") @SerializedName("u")
val url: String, val url: String,
@SerializedName("m") @SerializedName("m")
val mangaUrl: String val mangaUrl: String
) )
fun Page.copyWithUrl(newUrl: String) = Page( fun Page.copyWithUrl(newUrl: String) = Page(
index, index,
newUrl, newUrl,
imageUrl, imageUrl,
uri uri
) )
override val lang = "all" override val lang = "all"
override val supportsLatest = false override val supportsLatest = false
override val name = "MergedSource" override val name = "MergedSource"
} }