diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt index 43274d8a2..4cad68bf1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/MetadataSource.kt @@ -7,11 +7,13 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.model.toMangaInfo import eu.kanade.tachiyomi.ui.manga.MangaController +import eu.kanade.tachiyomi.util.lang.awaitSingle +import eu.kanade.tachiyomi.util.lang.runAsObservable import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.getFlatMetadataForManga import exh.metadata.metadata.base.insertFlatMetadata -import exh.metadata.metadata.base.insertFlatMetadataCompletable import exh.util.executeOnIO import rx.Completable import rx.Single @@ -34,9 +36,7 @@ interface MetadataSource : CatalogueSource { /** * Parse the supplied input into the supplied metadata object */ - fun parseIntoMetadata(metadata: M, input: I) - - suspend fun parseInfoIntoMetadata(metadata: M, input: I) = parseIntoMetadata(metadata, input) + suspend fun parseIntoMetadata(metadata: M, input: I) /** * Use reflection to create a new instance of metadata @@ -51,31 +51,11 @@ interface MetadataSource : CatalogueSource { * * Will also save the metadata to the DB if possible */ + @Suppress("DeprecatedCallableAddReplaceWith") @Deprecated("Use the MangaInfo variant") - fun parseToManga(manga: SManga, input: I): Completable { - val mangaId = manga.id - val metaObservable = if (mangaId != null) { - // We have to use fromCallable because StorIO messes up the thread scheduling if we use their rx functions - Single.fromCallable { - db.getFlatMetadataForManga(mangaId).executeAsBlocking() - }.map { - it?.raise(metaClass) ?: newMetaInstance() - } - } else { - Single.just(newMetaInstance()) - } - - return metaObservable.map { - parseIntoMetadata(it, input) - it.copyTo(manga) - it - }.flatMapCompletable { - if (mangaId != null) { - it.mangaId = mangaId - db.insertFlatMetadataCompletable(it.flatten()) - } else Completable.complete() - } - } + fun parseToManga(manga: SManga, input: I): Completable = runAsObservable({ + parseToManga(manga.toMangaInfo(), input) + }).toCompletable() suspend fun parseToManga(manga: MangaInfo, input: I): MangaInfo { val mangaId = manga.id() @@ -84,7 +64,7 @@ interface MetadataSource : CatalogueSource { flatMetadata?.raise(metaClass) ?: newMetaInstance() } else newMetaInstance() - parseInfoIntoMetadata(metadata, input) + parseIntoMetadata(metadata, input) if (mangaId != null) { metadata.mangaId = mangaId db.insertFlatMetadata(metadata.flatten()) @@ -100,31 +80,12 @@ interface MetadataSource : CatalogueSource { * If the metadata needs to be parsed from the input producer, the resulting parsed metadata will * also be saved to the DB. */ + @Suppress("DeprecatedCallableAddReplaceWith") @Deprecated("use fetchOrLoadMetadata made for MangaInfo") - fun getOrLoadMetadata(mangaId: Long?, inputProducer: () -> Single): Single { - val metaObservable = if (mangaId != null) { - // We have to use fromCallable because StorIO messes up the thread scheduling if we use their rx functions - Single.fromCallable { - db.getFlatMetadataForManga(mangaId).executeAsBlocking() - }.map { - it?.raise(metaClass) - } - } else Single.just(null) - - return metaObservable.flatMap { existingMeta -> - if (existingMeta == null) { - inputProducer().flatMap { input -> - val newMeta = newMetaInstance() - parseIntoMetadata(newMeta, input) - val newMetaSingle = Single.just(newMeta) - if (mangaId != null) { - newMeta.mangaId = mangaId - db.insertFlatMetadataCompletable(newMeta.flatten()).andThen(newMetaSingle) - } else newMetaSingle - } - } else Single.just(existingMeta) - } - } + fun getOrLoadMetadata(mangaId: Long?, inputProducer: () -> Single): Single = + runAsObservable({ + fetchOrLoadMetadata(mangaId) { inputProducer().toObservable().awaitSingle() } + }).toSingle() /** * Try to first get the metadata from the DB. If the metadata is not in the DB, calls the input @@ -143,7 +104,7 @@ interface MetadataSource : CatalogueSource { return meta ?: inputProducer().let { input -> val newMeta = newMetaInstance() - parseInfoIntoMetadata(newMeta, input) + parseIntoMetadata(newMeta, input) if (mangaId != null) { newMeta.mangaId = mangaId db.insertFlatMetadata(newMeta.flatten()).let { newMeta } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt index 97bafb75b..61c3e98e5 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt @@ -551,7 +551,7 @@ class EHentai( */ override fun mangaDetailsParse(response: Response) = throw UnsupportedOperationException() - override fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) { with(metadata) { with(input) { val url = location() diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt index c79a257bc..4342b5d59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/Hitomi.kt @@ -3,11 +3,8 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.net.Uri import android.os.Build -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -22,7 +19,6 @@ import exh.source.DelegatedHttpSource import exh.ui.metadata.adapters.HitomiDescriptionAdapter import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document -import rx.Observable import tachiyomi.source.model.MangaInfo import java.text.SimpleDateFormat import java.util.Locale @@ -36,25 +32,17 @@ class Hitomi(delegate: HttpSource, val context: Context) : override val lang = if (id == otherId) "all" else delegate.lang // Support direct URL importing - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { super.fetchSearchManga(page, query, filters) } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it.asJsoup()).andThen(Observable.just(manga)) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response.asJsoup()) } - override fun parseIntoMetadata(metadata: HitomiSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: HitomiSearchMetadata, input: Document) { with(metadata) { url = input.location() diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt index a625978d8..e4eaef64d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt @@ -162,7 +162,7 @@ class MangaDex(delegate: HttpSource, val context: Context) : return MangaDexDescriptionAdapter(controller) } - override fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Response) { + override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Response) { ApiMangaParser(baseHttpClient, mdLang.lang).parseIntoMetadata(metadata, input, emptyList()) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt index bc648e94f..4705be925 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/NHentai.kt @@ -3,11 +3,8 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.content.SharedPreferences import android.net.Uri -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -26,7 +23,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import okhttp3.Response -import rx.Observable import tachiyomi.source.model.MangaInfo class NHentai(delegate: HttpSource, val context: Context) : @@ -48,31 +44,17 @@ class NHentai(delegate: HttpSource, val context: Context) : } // Support direct URL importing - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { super.fetchSearchManga(page, query, filters) } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it).andThen( - Observable.just( - manga.apply { - initialized = true - } - ) - ) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response) } - override fun parseIntoMetadata(metadata: NHentaiSearchMetadata, input: Response) { + override suspend fun parseIntoMetadata(metadata: NHentaiSearchMetadata, input: Response) { val json = GALLERY_JSON_REGEX.find(input.body!!.string())!!.groupValues[1].replace( UNICODE_ESCAPE_REGEX ) { it.groupValues[1].toInt(radix = 16).toChar().toString() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt index 97991acea..16ebdf403 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/PervEden.kt @@ -3,11 +3,8 @@ package eu.kanade.tachiyomi.source.online.all import android.content.Context import android.net.Uri import androidx.core.net.toUri -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -23,7 +20,6 @@ import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import org.jsoup.nodes.Element import org.jsoup.nodes.TextNode -import rx.Observable import tachiyomi.source.model.MangaInfo class PervEden(delegate: HttpSource, val context: Context) : @@ -34,25 +30,17 @@ class PervEden(delegate: HttpSource, val context: Context) : override val lang = delegate.lang // Support direct URL importing - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { super.fetchSearchManga(page, query, filters) } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it.asJsoup()).andThen(Observable.just(manga)) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response.asJsoup()) } - override fun parseIntoMetadata(metadata: PervEdenSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: PervEdenSearchMetadata, input: Document) { with(metadata) { url = input.location().toUri().path diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt index 871db5a4d..a4ccc897a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/EightMuses.kt @@ -3,11 +3,8 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri import androidx.core.net.toUri -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -22,7 +19,6 @@ import exh.ui.metadata.adapters.EightMusesDescriptionAdapter import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import rx.Observable import tachiyomi.source.model.MangaInfo class EightMuses(delegate: HttpSource, val context: Context) : @@ -34,19 +30,11 @@ class EightMuses(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { super.fetchSearchManga(page, query, filters) } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it.asJsoup()).andThen(Observable.just(manga)) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response.asJsoup()) @@ -65,7 +53,7 @@ class EightMuses(delegate: HttpSource, val context: Context) : return SelfContents(selfAlbums, selfImages) } - override fun parseIntoMetadata(metadata: EightMusesSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: EightMusesSearchMetadata, input: Document) { with(metadata) { path = input.location().toUri().pathSegments diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt index 090bf7f66..ad5883eb8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/HBrowse.kt @@ -2,11 +2,8 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -21,7 +18,6 @@ import exh.ui.metadata.adapters.HBrowseDescriptionAdapter import exh.util.urlImportFetchSearchManga import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import rx.Observable import tachiyomi.source.model.MangaInfo class HBrowse(delegate: HttpSource, val context: Context) : @@ -33,25 +29,17 @@ class HBrowse(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { super.fetchSearchManga(page, query, filters) } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it.asJsoup()).andThen(Observable.just(manga)) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response.asJsoup()) } - override fun parseIntoMetadata(metadata: HBrowseSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: HBrowseSearchMetadata, input: Document) { val tables = parseIntoTables(input) with(metadata) { hbUrl = input.location().removePrefix("$baseUrl/thumbnails") diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt index d933705c0..11af91ca3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Pururin.kt @@ -3,11 +3,9 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri import androidx.core.net.toUri -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -54,21 +52,12 @@ class Pururin(delegate: HttpSource, val context: Context) : } } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it.asJsoup()) - .andThen(Observable.just(manga)) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response.asJsoup()) } - override fun parseIntoMetadata(metadata: PururinSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: PururinSearchMetadata, input: Document) { val selfLink = input.select("[itemprop=name]").last().parent() val parsedSelfLink = selfLink.attr("href").toUri().pathSegments diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt index 545be7a6c..56343314b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/english/Tsumino.kt @@ -2,11 +2,9 @@ package eu.kanade.tachiyomi.source.online.english import android.content.Context import android.net.Uri -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -51,20 +49,12 @@ class Tsumino(delegate: HttpSource, val context: Context) : return "https://tsumino.com/Book/Info/${uri.lastPathSegment}" } - override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(mangaDetailsRequest(manga)) - .asObservableSuccess() - .flatMap { - parseToManga(manga, it.asJsoup()).andThen(Observable.just(manga)) - } - } - override suspend fun getMangaDetails(manga: MangaInfo): MangaInfo { val response = client.newCall(mangaDetailsRequest(manga.toSManga())).await() return parseToManga(manga, response.asJsoup()) } - override fun parseIntoMetadata(metadata: TsuminoSearchMetadata, input: Document) { + override suspend fun parseIntoMetadata(metadata: TsuminoSearchMetadata, input: Document) { with(metadata) { tmId = TsuminoSearchMetadata.tmIdFromUrl(input.location())!!.toInt() tags.clear()