Adapt network implementation for TachiyomiX 1.6 (#3248)

This commit is contained in:
AntsyLich
2026-06-14 02:10:55 +06:00
committed by GitHub
parent c15f7bee85
commit 430b13bb81
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")
@@ -62,8 +62,6 @@ class NetworkHelper(
}
}
val nonCloudflareClient = clientBuilder.build()
val client = clientBuilder
.addInterceptor(
CloudflareInterceptor(context, cookieJar, scope, ::defaultUserAgentProvider),
@@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.network
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.json.Json
@@ -23,6 +22,7 @@ import kotlin.coroutines.resumeWithException
val jsonMime = "application/json; charset=utf-8".toMediaType()
@OptIn(ExperimentalAtomicApi::class)
@Deprecated("Use suspend APIs instead")
fun Call.asObservable(): Observable<Response> {
return Observable.unsafeCreate { 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> {
return asObservable().doOnNext { response ->
if (!response.isSuccessful) {
@@ -70,35 +71,31 @@ fun Call.asObservableSuccess(): Observable<Response> {
}
}
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
@OptIn(ExperimentalCoroutinesApi::class)
// Based on https://github.com/square/okhttp/blob/master/okhttp-coroutines/src/main/kotlin/okhttp3/coroutines/ExecuteAsync.kt
// and https://github.com/gildor/kotlin-coroutines-okhttp
private suspend fun Call.await(callStack: Array<StackTraceElement>): Response {
return suspendCancellableCoroutine { continuation ->
val callback =
object : Callback {
override fun onResponse(call: Call, response: Response) {
continuation.resume(response) { _, _, _ ->
response.body.close()
continuation.invokeOnCancellation {
try {
this.cancel()
} catch (_: Throwable) {
// ignore
}
}
this.enqueue(object : Callback {
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 {
try {
cancel()
} catch (ex: Throwable) {
// Ignore cancel 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 {
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
@@ -148,12 +145,3 @@ fun <T> decodeFromJsonResponse(
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")
@@ -108,6 +108,7 @@ abstract class HttpSource : CatalogueSource {
*
* @param page the page number to retrieve.
*/
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga"))
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
return client.newCall(popularMangaRequest(page))
@@ -139,6 +140,7 @@ abstract class HttpSource : CatalogueSource {
* @param query the search query.
* @param filters the list of filters to apply.
*/
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga"))
override fun fetchSearchManga(
page: Int,
@@ -184,6 +186,7 @@ abstract class HttpSource : CatalogueSource {
*
* @param page the page number to retrieve.
*/
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates"))
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
return client.newCall(latestUpdatesRequest(page))
@@ -219,6 +222,7 @@ abstract class HttpSource : CatalogueSource {
return fetchMangaDetails(manga).awaitSingle()
}
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return client.newCall(mangaDetailsRequest(manga))
@@ -257,6 +261,7 @@ abstract class HttpSource : CatalogueSource {
return fetchChapterList(manga).awaitSingle()
}
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return client.newCall(chapterListRequest(manga))
@@ -302,6 +307,7 @@ abstract class HttpSource : CatalogueSource {
return fetchPageList(chapter).awaitSingle()
}
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return client.newCall(pageListRequest(chapter))
@@ -340,6 +346,7 @@ abstract class HttpSource : CatalogueSource {
return fetchImageUrl(page).awaitSingle()
}
@Suppress("DEPRECATION")
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl"))
open fun fetchImageUrl(page: Page): Observable<String> {
return client.newCall(imageUrlRequest(page))