Adapt network implementation for TachiyomiX 1.6 (mihonapp/mihon#3248)
(cherry picked from commit 430b13bb81c8f51331109fa3ff35296f8bde9d27)
This commit is contained in:
parent
4ae732a17b
commit
87a173929b
4 changed files with 42 additions and 36 deletions
|
|
@ -0,0 +1,13 @@
|
||||||
|
package eu.kanade.tachiyomi.network
|
||||||
|
|
||||||
|
import okhttp3.Response
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception that handles HTTP codes considered not successful by OkHttp.
|
||||||
|
* Use it to have a standardized error message in the app across the extensions.
|
||||||
|
*
|
||||||
|
* @see Response.isSuccessful
|
||||||
|
* @since tachiyomix 1.6
|
||||||
|
* @param code [Int] the HTTP status code
|
||||||
|
*/
|
||||||
|
class HttpException(val code: Int) : IllegalStateException("HTTP error $code")
|
||||||
|
|
@ -82,8 +82,6 @@ import kotlin.random.Random
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val nonCloudflareClient /* KMK --> */ by lazy /* KMK <-- */ { clientBuilder().build() }
|
|
||||||
|
|
||||||
/* SY --> */ open /* SY <-- */ val client /* KMK --> */ by lazy /* KMK <-- */ {
|
/* SY --> */ open /* SY <-- */ val client /* KMK --> */ by lazy /* KMK <-- */ {
|
||||||
clientBuilder()
|
clientBuilder()
|
||||||
.addInterceptor(
|
.addInterceptor(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.network
|
package eu.kanade.tachiyomi.network
|
||||||
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
@ -23,6 +22,7 @@ import kotlin.coroutines.resumeWithException
|
||||||
val jsonMime = "application/json; charset=utf-8".toMediaType()
|
val jsonMime = "application/json; charset=utf-8".toMediaType()
|
||||||
|
|
||||||
@OptIn(ExperimentalAtomicApi::class)
|
@OptIn(ExperimentalAtomicApi::class)
|
||||||
|
@Deprecated("Use suspend APIs instead")
|
||||||
fun Call.asObservable(): Observable<Response> {
|
fun Call.asObservable(): Observable<Response> {
|
||||||
return Observable.unsafeCreate { subscriber ->
|
return Observable.unsafeCreate { subscriber ->
|
||||||
// Since Call is a one-shot type, clone it for each new subscriber.
|
// Since Call is a one-shot type, clone it for each new subscriber.
|
||||||
|
|
@ -61,6 +61,7 @@ fun Call.asObservable(): Observable<Response> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use suspend APIs instead")
|
||||||
fun Call.asObservableSuccess(): Observable<Response> {
|
fun Call.asObservableSuccess(): Observable<Response> {
|
||||||
return asObservable().doOnNext { response ->
|
return asObservable().doOnNext { response ->
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
|
|
@ -70,35 +71,31 @@ fun Call.asObservableSuccess(): Observable<Response> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
|
// Based on https://github.com/square/okhttp/blob/master/okhttp-coroutines/src/main/kotlin/okhttp3/coroutines/ExecuteAsync.kt
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
// and https://github.com/gildor/kotlin-coroutines-okhttp
|
||||||
private suspend fun Call.await(callStack: Array<StackTraceElement>): Response {
|
private suspend fun Call.await(callStack: Array<StackTraceElement>): Response {
|
||||||
return suspendCancellableCoroutine { continuation ->
|
return suspendCancellableCoroutine { continuation ->
|
||||||
val callback =
|
|
||||||
object : Callback {
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
continuation.resume(response) {
|
|
||||||
response.body.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
|
||||||
// Don't bother with resuming the continuation if it is already cancelled.
|
|
||||||
if (continuation.isCancelled) return
|
|
||||||
val exception = IOException(e.message, e).apply { stackTrace = callStack }
|
|
||||||
continuation.resumeWithException(exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enqueue(callback)
|
|
||||||
|
|
||||||
continuation.invokeOnCancellation {
|
continuation.invokeOnCancellation {
|
||||||
try {
|
try {
|
||||||
cancel()
|
this.cancel()
|
||||||
} catch (ex: Throwable) {
|
} catch (_: Throwable) {
|
||||||
// Ignore cancel exception
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.enqueue(object : Callback {
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
if (continuation.isCancelled) return
|
||||||
|
val exception = IOException(e.message, e).apply { stackTrace = callStack }
|
||||||
|
continuation.resumeWithException(exception)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
continuation.resume(response) { _, value, _ ->
|
||||||
|
value.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +105,7 @@ suspend fun Call.await(): Response {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since extensions-lib 1.5
|
* Similar to [await] but throws [HttpException] if [Response.isSuccessful] returns false
|
||||||
*/
|
*/
|
||||||
suspend fun Call.awaitSuccess(): Response {
|
suspend fun Call.awaitSuccess(): Response {
|
||||||
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
|
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
|
||||||
|
|
@ -148,12 +145,3 @@ fun <T> decodeFromJsonResponse(
|
||||||
json.decodeFromBufferedSource(deserializer, it)
|
json.decodeFromBufferedSource(deserializer, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception that handles HTTP codes considered not successful by OkHttp.
|
|
||||||
* Use it to have a standardized error message in the app across the extensions.
|
|
||||||
*
|
|
||||||
* @since extensions-lib 1.5
|
|
||||||
* @param code [Int] the HTTP status code
|
|
||||||
*/
|
|
||||||
class HttpException(val code: Int) : IllegalStateException("HTTP error $code")
|
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
*
|
*
|
||||||
* @param page the page number to retrieve.
|
* @param page the page number to retrieve.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga(page)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga(page)"))
|
||||||
open fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
open fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
||||||
return client.newCall(popularMangaRequest(page))
|
return client.newCall(popularMangaRequest(page))
|
||||||
|
|
@ -203,6 +204,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
* @param query the search query.
|
* @param query the search query.
|
||||||
* @param filters the list of filters to apply.
|
* @param filters the list of filters to apply.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga(page, query, filters)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga(page, query, filters)"))
|
||||||
open fun fetchSearchManga(
|
open fun fetchSearchManga(
|
||||||
page: Int,
|
page: Int,
|
||||||
|
|
@ -261,6 +263,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
*
|
*
|
||||||
* @param page the page number to retrieve.
|
* @param page the page number to retrieve.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates(page)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates(page)"))
|
||||||
open fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
|
open fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
|
||||||
return client.newCall(latestUpdatesRequest(page))
|
return client.newCall(latestUpdatesRequest(page))
|
||||||
|
|
@ -305,6 +308,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
*
|
*
|
||||||
* @param manga the manga to be updated.
|
* @param manga the manga to be updated.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails(manga)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails(manga)"))
|
||||||
open fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
open fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
||||||
return client.newCall(mangaDetailsRequest(manga))
|
return client.newCall(mangaDetailsRequest(manga))
|
||||||
|
|
@ -400,6 +404,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
*
|
*
|
||||||
* @param manga the manga to look for chapters.
|
* @param manga the manga to look for chapters.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList(manga)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList(manga)"))
|
||||||
open fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
open fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
||||||
return client.newCall(chapterListRequest(manga))
|
return client.newCall(chapterListRequest(manga))
|
||||||
|
|
@ -453,6 +458,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
*
|
*
|
||||||
* @param chapter the chapter whose page list has to be fetched.
|
* @param chapter the chapter whose page list has to be fetched.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList(chapter)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList(chapter)"))
|
||||||
open fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
open fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
||||||
return client.newCall(pageListRequest(chapter))
|
return client.newCall(pageListRequest(chapter))
|
||||||
|
|
@ -499,6 +505,7 @@ abstract class HttpSource : CatalogueSource {
|
||||||
*
|
*
|
||||||
* @param page the page whose source image has to be fetched.
|
* @param page the page whose source image has to be fetched.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl(page)"))
|
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl(page)"))
|
||||||
open fun fetchImageUrl(page: Page): Observable<String> {
|
open fun fetchImageUrl(page: Page): Observable<String> {
|
||||||
return client.newCall(imageUrlRequest(page))
|
return client.newCall(imageUrlRequest(page))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue