From f4e92e4a5637f41ecaa66c0f08f286a0f9717fdd Mon Sep 17 00:00:00 2001 From: arkon Date: Fri, 8 Sep 2023 17:28:04 -0400 Subject: [PATCH] Add more replacement suspend functions for source APIs These are basically 1-to-1 replacements for the existing RxJava APIs. This will make the initial migration off of RxJava simpler. We'll revisit the actual call flows in followup versions of the API. (cherry picked from commit 26c5d761da4ba577481f41e63f03952b8a6c323f) # Conflicts: # data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt # source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt # source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt --- .../tachiyomi/data/download/Downloader.kt | 3 +- .../tachiyomi/source/online/all/EHentai.kt | 35 ++++++--- .../tachiyomi/source/online/all/MangaDex.kt | 24 +++++-- .../source/online/all/MergedSource.kt | 7 +- .../tachiyomi/source/online/all/NHentai.kt | 11 ++- .../source/online/english/EightMuses.kt | 11 ++- .../source/online/english/HBrowse.kt | 11 ++- .../source/online/english/Pururin.kt | 16 ++++- .../source/online/english/Tsumino.kt | 10 ++- .../source/globalsearch/SearchScreenModel.kt | 3 +- .../ui/reader/loader/HttpPageLoader.kt | 3 +- .../java/exh/md/handlers/BilibiliHandler.kt | 13 ++-- .../main/java/exh/md/handlers/PageHandler.kt | 9 +++ app/src/main/java/exh/util/DataSaver.kt | 10 --- app/src/main/java/exh/util/SearchOverride.kt | 26 +++++++ .../tachiyomi/network/OkHttpExtensions.kt | 21 +++--- .../data/source/SourcePagingSource.kt | 7 +- .../domain/source/model/StubSource.kt | 31 ++------ .../tachiyomi/source/CatalogueSource.kt | 46 ++++++++++-- .../tachiyomi/source/ConfigurableSource.kt | 13 ++++ .../eu/kanade/tachiyomi/source/Source.kt | 35 +++------ .../tachiyomi/source/online/HttpSource.kt | 71 +++++++++++++------ .../source/online/HttpSourceFetcher.kt | 25 ------- .../kotlin/exh/source/DelegatedHttpSource.kt | 28 ++++++-- .../kotlin/exh/source/EnhancedHttpSource.kt | 18 +++-- .../tachiyomi/source/local/LocalSource.kt | 9 ++- 26 files changed, 316 insertions(+), 180 deletions(-) delete mode 100755 source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index b775fd1e8..f65ac8099 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -50,7 +50,6 @@ import nl.adaptivity.xmlutil.serialization.XML import okhttp3.Response import tachiyomi.core.metadata.comicinfo.COMIC_INFO_FILE import tachiyomi.core.metadata.comicinfo.ComicInfo -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.launchIO import tachiyomi.core.util.lang.launchNow import tachiyomi.core.util.lang.withIOContext @@ -380,7 +379,7 @@ class Downloader( if (page.imageUrl.isNullOrEmpty()) { page.status = Page.State.LOAD_PAGE try { - page.imageUrl = download.source.fetchImageUrl(page).awaitSingle() + page.imageUrl = download.source.getImageUrl(page) } catch (e: Throwable) { page.status = Page.State.ERROR } 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 6baabe493..c31c7401d 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 @@ -54,7 +54,7 @@ import exh.util.nullIfBlank import exh.util.trimAll import exh.util.trimOrNull import exh.util.urlImportFetchSearchManga -import kotlinx.serialization.decodeFromString +import exh.util.urlImportFetchSearchMangaSuspend import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.add @@ -456,27 +456,44 @@ class EHentai( } private fun Observable.checkValid(): Observable = map { - if (exh && it.mangas.isEmpty() && preferences.igneousVal().get().equals("mystery", true)) { - throw Exception("Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu") - } else { - it - } + it.checkValid() } + private fun T.checkValid(): MangasPage = + if (exh && mangas.isEmpty() && preferences.igneousVal().get().equals("mystery", true)) { + throw Exception("Invalid igneous cookie, try re-logging or finding a correct one to input in the login menu") + } else { + this + } + override fun fetchLatestUpdates(page: Int): Observable { - return super.fetchLatestUpdates(page).checkValid() + return super.fetchLatestUpdates(page).checkValid() + } + + override suspend fun getLatestUpdates(page: Int): MangasPage { + return super.getLatestUpdates(page).checkValid() } override fun fetchPopularManga(page: Int): Observable { - return super.fetchPopularManga(page).checkValid() + return super.fetchPopularManga(page).checkValid() + } + + override suspend fun getPopularManga(page: Int): MangasPage { + return super.getPopularManga(page).checkValid() } // Support direct URL importing override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters).checkValid() + super.fetchSearchManga(page, query, filters).checkValid() } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters).checkValid() + } + } + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val toplist = ToplistOption.values()[filters.firstNotNullOfOrNull { (it as? ToplistOptions)?.state } ?: 0] if (toplist != ToplistOption.NONE) { 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 b8988f648..92a3d1ca3 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 @@ -159,6 +159,7 @@ class MangaDex(delegate: HttpSource, val context: Context) : return mangaHandler.getMangaFromChapterId(id)?.let { MdUtil.buildMangaUrl(it) } } + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int): Observable { val request = delegate.latestUpdatesRequest(page) val url = request.url.newBuilder() @@ -171,6 +172,16 @@ class MangaDex(delegate: HttpSource, val context: Context) : } } + override suspend fun getLatestUpdates(page: Int): MangasPage { + val request = delegate.latestUpdatesRequest(page) + val url = request.url.newBuilder() + .removeAllQueryParameters("includeFutureUpdates") + .build() + + val response = client.newCall(request.newBuilder().url(url).build()).awaitSuccess() + return delegate.latestUpdatesParse(response) + } + @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails")) override fun fetchMangaDetails(manga: SManga): Observable { return mangaHandler.fetchMangaDetailsObservable(manga, id) @@ -198,22 +209,25 @@ class MangaDex(delegate: HttpSource, val context: Context) : return pageHandler.fetchPageList(chapter, usePort443Only(), dataSaver(), delegate) } - override fun fetchImage(page: Page): Observable { - val call = pageHandler.getImageCall(page) - return call?.asObservableSuccess() ?: super.fetchImage(page) - } - override suspend fun getImage(page: Page): Response { val call = pageHandler.getImageCall(page) return call?.awaitSuccess() ?: super.getImage(page) } + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page): Observable { return pageHandler.fetchImageUrl(page) { + @Suppress("DEPRECATION") super.fetchImageUrl(it) } } + override suspend fun getImageUrl(page: Page): String { + return pageHandler.getImageUrl(page) { + super.getImageUrl(page) + } + } + // MetadataSource methods override val metaClass: KClass = MangaDexSearchMetadata::class diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt index b197ecfd9..b2d073cc4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt @@ -61,15 +61,20 @@ class MergedSource : HttpSource() { @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList")) override fun fetchChapterList(manga: SManga) = throw UnsupportedOperationException() override suspend fun getChapterList(manga: SManga) = throw UnsupportedOperationException() - override fun fetchImage(page: Page) = throw UnsupportedOperationException() override suspend fun getImage(page: Page): Response = throw UnsupportedOperationException() + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page) = throw UnsupportedOperationException() + override suspend fun getImageUrl(page: Page) = throw UnsupportedOperationException() @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getPageList")) override fun fetchPageList(chapter: SChapter) = throw UnsupportedOperationException() override suspend fun getPageList(chapter: SChapter) = throw UnsupportedOperationException() + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int) = throw UnsupportedOperationException() + override suspend fun getLatestUpdates(page: Int) = throw UnsupportedOperationException() + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga")) override fun fetchPopularManga(page: Int) = throw UnsupportedOperationException() + override suspend fun getPopularManga(page: Int) = throw UnsupportedOperationException() override suspend fun getMangaDetails(manga: SManga): SManga { return withIOContext { 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 fa4633445..cbe4a7f97 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 @@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.source.PagePreviewInfo import eu.kanade.tachiyomi.source.PagePreviewPage import eu.kanade.tachiyomi.source.PagePreviewSource import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource @@ -22,9 +23,9 @@ import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource import exh.util.trimOrNull import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import okhttp3.CacheControl import okhttp3.Response @@ -52,9 +53,15 @@ class NHentai(delegate: HttpSource, val context: Context) : // Support direct URL importing override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun getMangaDetails(manga: SManga): SManga { val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess() return parseToManga(manga, response) 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 5c00c4443..98853c6f4 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 @@ -5,6 +5,7 @@ import android.net.Uri import androidx.core.net.toUri import eu.kanade.tachiyomi.network.awaitSuccess 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.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -15,6 +16,7 @@ import exh.metadata.metadata.EightMusesSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -28,11 +30,18 @@ class EightMuses(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun getMangaDetails(manga: SManga): SManga { val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess() return parseToManga(manga, response.asJsoup()) 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 2de327ecc..ce63b5fbf 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 @@ -4,6 +4,7 @@ import android.content.Context import android.net.Uri import eu.kanade.tachiyomi.network.awaitSuccess 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.online.HttpSource import eu.kanade.tachiyomi.source.online.MetadataSource @@ -14,6 +15,7 @@ import exh.metadata.metadata.HBrowseSearchMetadata import exh.metadata.metadata.base.RaisedTag import exh.source.DelegatedHttpSource import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -27,11 +29,18 @@ class HBrowse(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun getMangaDetails(manga: SManga): SManga { val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess() return parseToManga(manga, response.asJsoup()) 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 dc14a971b..f5b1eb48f 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 @@ -19,6 +19,7 @@ import exh.source.DelegatedHttpSource import exh.util.dropBlank import exh.util.trimAll import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import rx.Observable @@ -39,6 +40,7 @@ class Pururin(delegate: HttpSource, val context: Context) : override fun newMetaInstance() = PururinSearchMetadata() // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { val trimmedIdQuery = query.trim().removePrefix("id:") val newQuery = if ((trimmedIdQuery.toIntOrNull() ?: -1) >= 0) { @@ -48,7 +50,19 @@ class Pururin(delegate: HttpSource, val context: Context) : } return urlImportFetchSearchManga(context, newQuery) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) + } + } + + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + val trimmedIdQuery = query.trim().removePrefix("id:") + val newQuery = if ((trimmedIdQuery.toIntOrNull() ?: -1) >= 0) { + "$baseUrl/gallery/$trimmedIdQuery/-" + } else { + query + } + return urlImportFetchSearchMangaSuspend(context, newQuery) { + super.getSearchManga(page, query, filters,) } } 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 63c1f25bb..0babef369 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 @@ -19,6 +19,7 @@ import exh.source.DelegatedHttpSource import exh.util.dropBlank import exh.util.trimAll import exh.util.urlImportFetchSearchManga +import exh.util.urlImportFetchSearchMangaSuspend import org.jsoup.nodes.Document import rx.Observable import java.text.SimpleDateFormat @@ -34,11 +35,18 @@ class Tsumino(delegate: HttpSource, val context: Context) : override val lang = "en" // Support direct URL importing + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = urlImportFetchSearchManga(context, query) { - super.fetchSearchManga(page, query, filters) + super.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return urlImportFetchSearchMangaSuspend(context, query) { + super.getSearchManga(page, query, filters,) + } + } + override suspend fun mapUrlToMangaUrl(uri: Uri): String? { val lcFirstPathSegment = uri.pathSegments.firstOrNull()?.lowercase(Locale.ROOT) ?: return null if (lcFirstPathSegment != "read" && lcFirstPathSegment != "book" && lcFirstPathSegment != "entry") { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt index 898377f0e..66736f390 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt @@ -19,7 +19,6 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga @@ -143,7 +142,7 @@ abstract class SearchScreenModel( try { val page = withContext(coroutineDispatcher) { - source.fetchSearchManga(1, query, source.getFilterList()).awaitSingle() + source.getSearchManga(1, query, source.getFilterList()) } val titles = page.mangas.map { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index 54e359ba7..53a3bbb0e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flow import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.suspendCancellableCoroutine -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.launchIO import tachiyomi.core.util.lang.withIOContext import uy.kohesive.injekt.Injekt @@ -211,7 +210,7 @@ internal class HttpPageLoader( try { if (page.imageUrl.isNullOrEmpty()) { page.status = Page.State.LOAD_PAGE - page.imageUrl = source.fetchImageUrl(page).awaitSingle() + page.imageUrl = source.getImageUrl(page) } val imageUrl = page.imageUrl!! diff --git a/app/src/main/java/exh/md/handlers/BilibiliHandler.kt b/app/src/main/java/exh/md/handlers/BilibiliHandler.kt index 080d52d7b..86e245ef7 100644 --- a/app/src/main/java/exh/md/handlers/BilibiliHandler.kt +++ b/app/src/main/java/exh/md/handlers/BilibiliHandler.kt @@ -1,7 +1,6 @@ package exh.md.handlers import eu.kanade.tachiyomi.network.POST -import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.awaitSuccess import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.parseAs @@ -22,6 +21,7 @@ import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import rx.Observable +import tachiyomi.core.util.lang.runAsObservable import uy.kohesive.injekt.injectLazy import java.util.concurrent.TimeUnit @@ -154,12 +154,13 @@ class BilibiliHandler(currentClient: OkHttpClient) { .mapIndexed { i, page -> Page(i, page.path, "") } } + suspend fun getImageUrl(page: Page): String { + val response = client.newCall(imageUrlRequest(page)).awaitSuccess() + return imageUrlParse(response) + } + fun fetchImageUrl(page: Page): Observable { - return client.newCall(imageUrlRequest(page)) - .asObservableSuccess() - .map { - imageUrlParse(it) - } + return runAsObservable { getImageUrl(page) } } private fun imageUrlRequest(page: Page): Request { diff --git a/app/src/main/java/exh/md/handlers/PageHandler.kt b/app/src/main/java/exh/md/handlers/PageHandler.kt index cf5ddd5a0..14f06c412 100644 --- a/app/src/main/java/exh/md/handlers/PageHandler.kt +++ b/app/src/main/java/exh/md/handlers/PageHandler.kt @@ -134,4 +134,13 @@ class PageHandler( else -> superMethod(page) } } + + suspend fun getImageUrl(page: Page, superMethod: suspend (Page) -> String): String { + return when { + page.url.contains("/bfs/comic/") -> { + bilibiliHandler.getImageUrl(page) + } + else -> superMethod(page) + } + } } diff --git a/app/src/main/java/exh/util/DataSaver.kt b/app/src/main/java/exh/util/DataSaver.kt index e84626337..a9f4ab2c1 100644 --- a/app/src/main/java/exh/util/DataSaver.kt +++ b/app/src/main/java/exh/util/DataSaver.kt @@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.online.HttpSource import okhttp3.Response -import rx.Observable import tachiyomi.core.preference.Preference interface DataSaver { @@ -22,15 +21,6 @@ interface DataSaver { } } - fun HttpSource.fetchImage(page: Page, dataSaver: DataSaver): Observable { - val imageUrl = page.imageUrl ?: return fetchImage(page) - page.imageUrl = dataSaver.compress(imageUrl) - return fetchImage(page) - .doOnNext { - page.imageUrl = imageUrl - } - } - suspend fun HttpSource.getImage(page: Page, dataSaver: DataSaver): Response { val imageUrl = page.imageUrl ?: return getImage(page) page.imageUrl = dataSaver.compress(imageUrl) diff --git a/app/src/main/java/exh/util/SearchOverride.kt b/app/src/main/java/exh/util/SearchOverride.kt index d1647ba16..7a68f3751 100644 --- a/app/src/main/java/exh/util/SearchOverride.kt +++ b/app/src/main/java/exh/util/SearchOverride.kt @@ -35,3 +35,29 @@ fun UrlImportableSource.urlImportFetchSearchManga(context: Context, query: Strin } else -> fail() } + + +/** + * A version of fetchSearchManga that supports URL importing + */ +suspend fun UrlImportableSource.urlImportFetchSearchMangaSuspend(context: Context, query: String, fail: suspend () -> MangasPage): MangasPage = + when { + query.startsWith("http://") || query.startsWith("https://") -> { + val res = galleryAdder.addGallery( + context = context, + url = query, + fav = false, + forceSource = this + ) + + MangasPage( + if (res is GalleryAddEvent.Success) { + listOf(res.manga.toSManga()) + } else { + emptyList() + }, + false, + ) + } + else -> fail() + } diff --git a/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt b/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt index 4cbb34812..e6eec02f4 100755 --- a/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/OkHttpExtensions.kt @@ -58,6 +58,15 @@ fun Call.asObservable(): Observable { } } +fun Call.asObservableSuccess(): Observable { + return asObservable().doOnNext { response -> + if (!response.isSuccessful) { + response.close() + throw HttpException(response.code) + } + } +} + // Based on https://github.com/gildor/kotlin-coroutines-okhttp @OptIn(ExperimentalCoroutinesApi::class) private suspend fun Call.await(callStack: Array): Response { @@ -95,6 +104,9 @@ suspend fun Call.await(): Response { return await(callStack) } +/** + * @since extensions-lib 1.5 + */ suspend fun Call.awaitSuccess(): Response { val callStack = Exception().stackTrace.run { copyOfRange(1, size) } val response = await(callStack) @@ -105,15 +117,6 @@ suspend fun Call.awaitSuccess(): Response { return response } -fun Call.asObservableSuccess(): Observable { - return asObservable().doOnNext { response -> - if (!response.isSuccessful) { - response.close() - throw HttpException(response.code) - } - } -} - fun OkHttpClient.newCachelessCallWithProgress(request: Request, listener: ProgressListener): Call { val progressClient = newBuilder() .cache(null) diff --git a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt index 9b9c7d9a0..998c75f33 100644 --- a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt +++ b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt @@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MetadataMangasPage import eu.kanade.tachiyomi.source.model.SManga import exh.metadata.metadata.RaisedSearchMetadata -import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.withIOContext import tachiyomi.domain.source.repository.SourcePagingSourceType @@ -15,19 +14,19 @@ class SourceSearchPagingSource(source: CatalogueSource, val query: String, val f source, ) { override suspend fun requestNextPage(currentPage: Int): MangasPage { - return source.fetchSearchManga(currentPage, query, filters).awaitSingle() + return source.getSearchManga(currentPage, query, filters) } } class SourcePopularPagingSource(source: CatalogueSource) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { - return source.fetchPopularManga(currentPage).awaitSingle() + return source.getPopularManga(currentPage) } } class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { - return source.fetchLatestUpdates(currentPage).awaitSingle() + return source.getLatestUpdates(currentPage) } } diff --git a/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt b/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt index 38d38ef57..8b5f67ef5 100644 --- a/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt +++ b/domain/src/main/java/tachiyomi/domain/source/model/StubSource.kt @@ -4,7 +4,6 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga -import rx.Observable class StubSource( override val id: Long, @@ -14,36 +13,16 @@ class StubSource( private val isInvalid: Boolean = name.isBlank() || lang.isBlank() - override suspend fun getMangaDetails(manga: SManga): SManga { + override suspend fun getMangaDetails(manga: SManga): SManga = throw SourceNotInstalledException() - } - @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails")) - override fun fetchMangaDetails(manga: SManga): Observable { - return Observable.error(SourceNotInstalledException()) - } - - override suspend fun getChapterList(manga: SManga): List { + override suspend fun getChapterList(manga: SManga): List = throw SourceNotInstalledException() - } - - @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList")) - override fun fetchChapterList(manga: SManga): Observable> { - return Observable.error(SourceNotInstalledException()) - } - - override suspend fun getPageList(chapter: SChapter): List { + override suspend fun getPageList(chapter: SChapter): List = throw SourceNotInstalledException() - } - @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList")) - override fun fetchPageList(chapter: SChapter): Observable> { - return Observable.error(SourceNotInstalledException()) - } - - override fun toString(): String { - return if (isInvalid.not()) "$name (${lang.uppercase()})" else id.toString() - } + override fun toString(): String = + if (isInvalid.not()) "$name (${lang.uppercase()})" else id.toString() } class SourceNotInstalledException : Exception() diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt index f9e416def..937fa28a9 100755 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/CatalogueSource.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.source import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import rx.Observable +import tachiyomi.core.util.lang.awaitSingle interface CatalogueSource : Source { @@ -17,30 +18,63 @@ interface CatalogueSource : Source { val supportsLatest: Boolean /** - * Returns an observable containing a page with a list of manga. + * Get a page with a list of manga. * + * @since extensions-lib 1.5 * @param page the page number to retrieve. */ - fun fetchPopularManga(page: Int): Observable + @Suppress("DEPRECATION") + suspend fun getPopularManga(page: Int): MangasPage { + return fetchPopularManga(page).awaitSingle() + } /** - * Returns an observable containing a page with a list of manga. + * Get a page with a list of manga. * + * @since extensions-lib 1.5 * @param page the page number to retrieve. * @param query the search query. * @param filters the list of filters to apply. */ - fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable + @Suppress("DEPRECATION") + suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + return fetchSearchManga(page, query, filters).awaitSingle() + } /** - * Returns an observable containing a page with a list of latest manga updates. + * Get a page with a list of latest manga updates. * + * @since extensions-lib 1.5 * @param page the page number to retrieve. */ - fun fetchLatestUpdates(page: Int): Observable + @Suppress("DEPRECATION") + suspend fun getLatestUpdates(page: Int): MangasPage { + return fetchLatestUpdates(page).awaitSingle() + } /** * Returns the list of filters for the source. */ fun getFilterList(): FilterList + + @Deprecated( + "Use the non-RxJava API instead", + ReplaceWith("getPopularManga"), + ) + fun fetchPopularManga(page: Int): Observable = + throw IllegalStateException("Not used") + + @Deprecated( + "Use the non-RxJava API instead", + ReplaceWith("getSearchManga"), + ) + fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + throw IllegalStateException("Not used") + + @Deprecated( + "Use the non-RxJava API instead", + ReplaceWith("getLatestUpdates"), + ) + fun fetchLatestUpdates(page: Int): Observable = + throw IllegalStateException("Not used") } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt index d42885f80..e6a019ecc 100644 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt @@ -1,6 +1,19 @@ package eu.kanade.tachiyomi.source +import android.app.Application +import android.content.SharedPreferences +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + interface ConfigurableSource : Source { + /** + * Gets instance of [SharedPreferences] scoped to the specific source. + * + * @since extensions-lib 1.5 + */ + fun getPreferences(): SharedPreferences = + Injekt.get().getSharedPreferences("source_$id", 0x0000) + fun setupPreferenceScreen(screen: PreferenceScreen) } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt index f140eda74..83fcd7962 100755 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt @@ -27,7 +27,7 @@ interface Source { /** * Get the updated details for a manga. * - * @since extensions-lib 1.4 + * @since extensions-lib 1.5 * @param manga the manga to update. * @return the updated manga. */ @@ -39,7 +39,7 @@ interface Source { /** * Get all the available chapters for a manga. * - * @since extensions-lib 1.4 + * @since extensions-lib 1.5 * @param manga the manga to update. * @return the chapters for the manga. */ @@ -52,7 +52,7 @@ interface Source { * Get the list of pages a chapter has. Pages should be returned * in the expected order; the index is ignored. * - * @since extensions-lib 1.4 + * @since extensions-lib 1.5 * @param chapter the chapter. * @return the pages for the chapter. */ @@ -61,41 +61,24 @@ interface Source { return fetchPageList(chapter).awaitSingle() } - /** - * Returns an observable with the updated details for a manga. - * - * @param manga the manga to update. - */ @Deprecated( "Use the non-RxJava API instead", ReplaceWith("getMangaDetails"), ) - fun fetchMangaDetails(manga: SManga): Observable = throw IllegalStateException( - "Not used", - ) + fun fetchMangaDetails(manga: SManga): Observable = + throw IllegalStateException("Not used") - /** - * Returns an observable with all the available chapters for a manga. - * - * @param manga the manga to update. - */ @Deprecated( "Use the non-RxJava API instead", ReplaceWith("getChapterList"), ) - fun fetchChapterList(manga: SManga): Observable> = throw IllegalStateException( - "Not used", - ) + fun fetchChapterList(manga: SManga): Observable> = + throw IllegalStateException("Not used") - /** - * Returns an observable with the list of pages a chapter has. Pages should be returned - * in the expected order; the index is ignored. - * - * @param chapter the chapter. - */ @Deprecated( "Use the non-RxJava API instead", ReplaceWith("getPageList"), ) - fun fetchPageList(chapter: SChapter): Observable> = Observable.empty() + fun fetchPageList(chapter: SChapter): Observable> = + throw IllegalStateException("Not used") } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt index 10b741132..677516cb3 100755 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt @@ -21,6 +21,7 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response import rx.Observable +import tachiyomi.core.util.lang.awaitSingle import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.net.URI @@ -30,6 +31,7 @@ import java.security.MessageDigest /** * A simple implementation for sources from a website. */ +@Suppress("unused") abstract class HttpSource : CatalogueSource { /** @@ -108,6 +110,7 @@ abstract class HttpSource : CatalogueSource { * @param versionId [Int] the version ID of the source * @return a unique ID for the source */ + @Suppress("MemberVisibilityCanBePrivate") protected fun generateId(name: String, lang: String, versionId: Int): Long { val key = "${name.lowercase()}/$lang/$versionId" val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) @@ -231,11 +234,18 @@ abstract class HttpSource : CatalogueSource { abstract fun latestUpdatesParse(response: Response): MangasPage /** - * Returns an observable with the updated details for a manga. Normally it's not needed to - * override this method. + * Get the updated details for a manga. + * Normally it's not needed to override this method. * - * @param manga the manga to be updated. + * @param manga the manga to update. + * @return the updated manga. */ + @Suppress("DEPRECATION") + override suspend fun getMangaDetails(manga: SManga): SManga { + return fetchMangaDetails(manga).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails")) override fun fetchMangaDetails(manga: SManga): Observable { return client.newCall(mangaDetailsRequest(manga)) .asObservableSuccess() @@ -262,11 +272,23 @@ abstract class HttpSource : CatalogueSource { protected abstract fun mangaDetailsParse(response: Response): SManga /** - * Returns an observable with the updated chapter list for a manga. Normally it's not needed to - * override this method. If a manga is licensed an empty chapter list observable is returned + * Get all the available chapters for a manga. + * Normally it's not needed to override this method. * - * @param manga the manga to look for chapters. + * @param manga the manga to update. + * @return the chapters for the manga. + * @throws LicensedMangaChaptersException if a manga is licensed and therefore no chapters are available. */ + @Suppress("DEPRECATION") + override suspend fun getChapterList(manga: SManga): List { + if (manga.status == SManga.LICENSED) { + throw LicensedMangaChaptersException() + } + + return fetchChapterList(manga).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList")) override fun fetchChapterList(manga: SManga): Observable> { return if (manga.status != SManga.LICENSED) { client.newCall(chapterListRequest(manga)) @@ -297,10 +319,18 @@ abstract class HttpSource : CatalogueSource { protected abstract fun chapterListParse(response: Response): List /** - * Returns an observable with the page list for a chapter. + * Get the list of pages a chapter has. Pages should be returned + * in the expected order; the index is ignored. * - * @param chapter the chapter whose page list has to be fetched. + * @param chapter the chapter. + * @return the pages for the chapter. */ + @Suppress("DEPRECATION") + override suspend fun getPageList(chapter: SChapter): List { + return fetchPageList(chapter).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList")) override fun fetchPageList(chapter: SChapter): Observable> { return client.newCall(pageListRequest(chapter)) .asObservableSuccess() @@ -330,8 +360,15 @@ abstract class HttpSource : CatalogueSource { * Returns an observable with the page containing the source url of the image. If there's any * error, it will return null instead of throwing an exception. * + * @since extensions-lib 1.5 * @param page the page whose source image has to be fetched. */ + @Suppress("DEPRECATION") + open suspend fun getImageUrl(page: Page): String { + return fetchImageUrl(page).awaitSingle() + } + + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) open fun fetchImageUrl(page: Page): Observable { return client.newCall(imageUrlRequest(page)) .asObservableSuccess() @@ -355,26 +392,14 @@ abstract class HttpSource : CatalogueSource { */ protected abstract fun imageUrlParse(response: Response): String - /** - * Returns an observable with the response of the source image. - * - * @param page the page whose source image has to be downloaded. - */ - /* SY --> */ - open /* SY <-- */ fun fetchImage(page: Page): Observable { - // images will be cached or saved manually, so don't take up network cache - return client.newCachelessCallWithProgress(imageRequest(page), page) - .asObservableSuccess() - } - /** * Returns the response of the source image. + * Typically does not need to be overridden. * + * @since extensions-lib 1.5 * @param page the page whose source image has to be downloaded. */ - /* SY --> */ - open /* SY <-- */ suspend fun getImage(page: Page): Response { - // images will be cached or saved manually, so don't take up network cache + open suspend fun getImage(page: Page): Response { return client.newCachelessCallWithProgress(imageRequest(page), page) .awaitSuccess() } diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt deleted file mode 100755 index 76c68e882..000000000 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSourceFetcher.kt +++ /dev/null @@ -1,25 +0,0 @@ -package eu.kanade.tachiyomi.source.online - -import eu.kanade.tachiyomi.source.model.Page -import rx.Observable - -fun HttpSource.fetchAllImageUrlsFromPageList(pages: List): Observable { - return Observable.from(pages) - .filter { !it.imageUrl.isNullOrEmpty() } - .mergeWith(fetchRemainingImageUrlsFromPageList(pages)) -} - -private fun HttpSource.fetchRemainingImageUrlsFromPageList(pages: List): Observable { - return Observable.from(pages) - .filter { it.imageUrl.isNullOrEmpty() } - .concatMap { getImageUrl(it) } -} - -private fun HttpSource.getImageUrl(page: Page): Observable { - page.status = Page.State.LOAD_PAGE - return fetchImageUrl(page) - .doOnError { page.status = Page.State.ERROR } - .onErrorReturn { null } - .doOnNext { page.imageUrl = it } - .map { page } -} diff --git a/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt b/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt index ad105d248..1de09d68d 100644 --- a/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt +++ b/source-api/src/commonMain/kotlin/exh/source/DelegatedHttpSource.kt @@ -146,11 +146,17 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() { * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga")) override fun fetchPopularManga(page: Int): Observable { ensureDelegateCompatible() return delegate.fetchPopularManga(page) } + override suspend fun getPopularManga(page: Int): MangasPage { + ensureDelegateCompatible() + return delegate.getPopularManga(page) + } + /** * Returns an observable containing a page with a list of manga. Normally it's not needed to * override this method. @@ -159,21 +165,33 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() { * @param query the search query. * @param filters the list of filters to apply. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { ensureDelegateCompatible() return delegate.fetchSearchManga(page, query, filters) } + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { + ensureDelegateCompatible() + return delegate.getSearchManga(page, query, filters) + } + /** * Returns an observable containing a page with a list of latest manga updates. * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int): Observable { ensureDelegateCompatible() return delegate.fetchLatestUpdates(page) } + override suspend fun getLatestUpdates(page: Int): MangasPage { + ensureDelegateCompatible() + return delegate.getLatestUpdates(page) + } + /** * Returns an observable with the updated details for a manga. Normally it's not needed to * override this method. @@ -250,19 +268,15 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() { * * @param page the page whose source image has to be fetched. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page): Observable { ensureDelegateCompatible() return delegate.fetchImageUrl(page) } - /** - * Returns an observable with the response of the source image. - * - * @param page the page whose source image has to be downloaded. - */ - override fun fetchImage(page: Page): Observable { + override suspend fun getImageUrl(page: Page): String { ensureDelegateCompatible() - return delegate.fetchImage(page) + return delegate.getImageUrl(page) } /** diff --git a/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt b/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt index 43dc38dcf..5c8675a3d 100644 --- a/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt +++ b/source-api/src/commonMain/kotlin/exh/source/EnhancedHttpSource.kt @@ -149,8 +149,11 @@ class EnhancedHttpSource( * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga")) override fun fetchPopularManga(page: Int) = source().fetchPopularManga(page) + override suspend fun getPopularManga(page: Int) = source().getPopularManga(page) + /** * Returns an observable containing a page with a list of manga. Normally it's not needed to * override this method. @@ -159,16 +162,23 @@ class EnhancedHttpSource( * @param query the search query. * @param filters the list of filters to apply. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga")) override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = source().fetchSearchManga(page, query, filters) + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList) = + source().getSearchManga(page, query, filters) + /** * Returns an observable containing a page with a list of latest manga updates. * * @param page the page number to retrieve. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates")) override fun fetchLatestUpdates(page: Int) = source().fetchLatestUpdates(page) + override suspend fun getLatestUpdates(page: Int) = source().getLatestUpdates(page) + /** * Returns an observable with the updated details for a manga. Normally it's not needed to * override this method. @@ -224,14 +234,10 @@ class EnhancedHttpSource( * * @param page the page whose source image has to be fetched. */ + @Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl")) override fun fetchImageUrl(page: Page) = source().fetchImageUrl(page) - /** - * Returns an observable with the response of the source image. - * - * @param page the page whose source image has to be downloaded. - */ - override fun fetchImage(page: Page) = source().fetchImage(page) + override suspend fun getImageUrl(page: Page) = source().getImageUrl(page) /** * Returns the response of the source image. diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt index e1d9fbf8e..8dd747227 100755 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt @@ -20,7 +20,6 @@ import net.lingala.zip4j.ZipFile import net.lingala.zip4j.model.ZipParameters import nl.adaptivity.xmlutil.AndroidXmlReader import nl.adaptivity.xmlutil.serialization.XML -import rx.Observable import tachiyomi.core.metadata.comicinfo.COMIC_INFO_FILE import tachiyomi.core.metadata.comicinfo.ComicInfo import tachiyomi.core.metadata.comicinfo.copyFromComicInfo @@ -72,11 +71,11 @@ actual class LocalSource( override val supportsLatest: Boolean = true // Browse related - override fun fetchPopularManga(page: Int) = fetchSearchManga(page, "", POPULAR_FILTERS) + override suspend fun getPopularManga(page: Int) = getSearchManga(page, "", POPULAR_FILTERS) - override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS) + override suspend fun getLatestUpdates(page: Int) = getSearchManga(page, "", LATEST_FILTERS) - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { + override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage { val baseDirsFiles = fileSystem.getFilesInBaseDirectories() val lastModifiedLimit by lazy { if (filters === LATEST_FILTERS) System.currentTimeMillis() - LATEST_THRESHOLD else 0L } // SY --> @@ -153,7 +152,7 @@ actual class LocalSource( } } - return Observable.just(MangasPage(mangas.toList(), false)) + return MangasPage(mangas.toList(), false) } // SY -->