OkHttp Call: split await() and awaitSuccess() (#8980)

(cherry picked from commit 448702e5beedcd0918c504da34a0feda20ee2817)
This commit is contained in:
stevenyomi 2023-01-25 11:34:31 +08:00 committed by Jobobby04
parent 1948545983
commit a0497d079d
30 changed files with 158 additions and 184 deletions

View File

@ -5,7 +5,7 @@ import androidx.core.net.toUri
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.network.jsonMime import eu.kanade.tachiyomi.network.jsonMime
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
@ -59,7 +59,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime), body = payload.toString().toRequestBody(jsonMime),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
track.library_id = track.library_id =
@ -99,7 +99,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
} }
} }
authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime))) authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
.await() .awaitSuccess()
track track
} }
} }
@ -143,7 +143,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime), body = payload.toString().toRequestBody(jsonMime),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { response -> .let { response ->
val data = response["data"]!!.jsonObject val data = response["data"]!!.jsonObject
@ -211,7 +211,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime), body = payload.toString().toRequestBody(jsonMime),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { response -> .let { response ->
val data = response["data"]!!.jsonObject val data = response["data"]!!.jsonObject
@ -253,7 +253,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
body = payload.toString().toRequestBody(jsonMime), body = payload.toString().toRequestBody(jsonMime),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
val data = it["data"]!!.jsonObject val data = it["data"]!!.jsonObject

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
@ -40,7 +40,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.add("status", track.toBangumiStatus()) .add("status", track.toBangumiStatus())
.build() .build()
authClient.newCall(POST("$apiUrl/collection/${track.media_id}/update", body = body)) authClient.newCall(POST("$apiUrl/collection/${track.media_id}/update", body = body))
.await() .awaitSuccess()
track track
} }
} }
@ -53,7 +53,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.add("status", track.toBangumiStatus()) .add("status", track.toBangumiStatus())
.build() .build()
authClient.newCall(POST("$apiUrl/collection/${track.media_id}/update", body = sbody)) authClient.newCall(POST("$apiUrl/collection/${track.media_id}/update", body = sbody))
.await() .awaitSuccess()
// chapter update // chapter update
val body = FormBody.Builder() val body = FormBody.Builder()
@ -64,7 +64,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
"$apiUrl/subject/${track.media_id}/update/watched_eps", "$apiUrl/subject/${track.media_id}/update/watched_eps",
body = body, body = body,
), ),
).await() ).awaitSuccess()
track track
} }
@ -78,7 +78,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.appendQueryParameter("max_results", "20") .appendQueryParameter("max_results", "20")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.use { .use {
var responseBody = it.body.string() var responseBody = it.body.string()
if (responseBody.isEmpty()) { if (responseBody.isEmpty()) {
@ -119,7 +119,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
suspend fun findLibManga(track: Track): Track? { suspend fun findLibManga(track: Track): Track? {
return withIOContext { return withIOContext {
authClient.newCall(GET("$apiUrl/subject/${track.media_id}")) authClient.newCall(GET("$apiUrl/subject/${track.media_id}"))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { jsonToSearch(it) } .let { jsonToSearch(it) }
} }
@ -135,7 +135,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.build() .build()
// TODO: get user readed chapter here // TODO: get user readed chapter here
val response = authClient.newCall(requestUserRead).await() val response = authClient.newCall(requestUserRead).awaitSuccess()
val responseBody = response.body.string() val responseBody = response.body.string()
if (responseBody.isEmpty()) { if (responseBody.isEmpty()) {
throw Exception("Null Response") throw Exception("Null Response")
@ -156,7 +156,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
suspend fun accessToken(code: String): OAuth { suspend fun accessToken(code: String): OAuth {
return withIOContext { return withIOContext {
client.newCall(accessTokenRequest(code)) client.newCall(accessTokenRequest(code))
.await() .awaitSuccess()
.parseAs() .parseAs()
} }
} }

View File

@ -4,7 +4,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
@ -128,7 +128,7 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
suspend fun getTrackSearch(url: String): TrackSearch = withIOContext { suspend fun getTrackSearch(url: String): TrackSearch = withIOContext {
try { try {
val serieDto: SeriesDto = authClient.newCall(GET(url)) val serieDto: SeriesDto = authClient.newCall(GET(url))
.await() .awaitSuccess()
.parseAs() .parseAs()
val track = serieDto.toTrack() val track = serieDto.toTrack()
@ -154,7 +154,7 @@ class KavitaApi(private val client: OkHttpClient, interceptor: KavitaInterceptor
suspend fun updateProgress(track: Track): Track { suspend fun updateProgress(track: Track): Track {
val requestUrl = "${getApiFromUrl(track.tracking_url)}/Tachiyomi/mark-chapter-until-as-read?seriesId=${getIdFromUrl(track.tracking_url)}&chapterNumber=${track.last_chapter_read}" val requestUrl = "${getApiFromUrl(track.tracking_url)}/Tachiyomi/mark-chapter-until-as-read?seriesId=${getIdFromUrl(track.tracking_url)}&chapterNumber=${track.last_chapter_read}"
authClient.newCall(POST(requestUrl, body = "{}".toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull()))) authClient.newCall(POST(requestUrl, body = "{}".toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())))
.await() .awaitSuccess()
return getTrackSearch(track.tracking_url) return getTrackSearch(track.tracking_url)
} }
} }

View File

@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.jsonMime import eu.kanade.tachiyomi.network.jsonMime
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
@ -67,7 +67,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
body = data.toString().toRequestBody("application/vnd.api+json".toMediaType()), body = data.toString().toRequestBody("application/vnd.api+json".toMediaType()),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
track.media_id = it["data"]!!.jsonObject["id"]!!.jsonPrimitive.long track.media_id = it["data"]!!.jsonObject["id"]!!.jsonPrimitive.long
@ -104,7 +104,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.patch(data.toString().toRequestBody("application/vnd.api+json".toMediaType())) .patch(data.toString().toRequestBody("application/vnd.api+json".toMediaType()))
.build(), .build(),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
track track
@ -115,7 +115,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
suspend fun search(query: String): List<TrackSearch> { suspend fun search(query: String): List<TrackSearch> {
return withIOContext { return withIOContext {
authClient.newCall(GET(algoliaKeyUrl)) authClient.newCall(GET(algoliaKeyUrl))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
val key = it["media"]!!.jsonObject["key"]!!.jsonPrimitive.content val key = it["media"]!!.jsonObject["key"]!!.jsonPrimitive.content
@ -142,7 +142,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
body = jsonObject.toString().toRequestBody(jsonMime), body = jsonObject.toString().toRequestBody(jsonMime),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
it["hits"]!!.jsonArray it["hits"]!!.jsonArray
@ -160,7 +160,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.appendQueryParameter("include", "manga") .appendQueryParameter("include", "manga")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
val data = it["data"]!!.jsonArray val data = it["data"]!!.jsonArray
@ -181,7 +181,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.appendQueryParameter("include", "manga") .appendQueryParameter("include", "manga")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
val data = it["data"]!!.jsonArray val data = it["data"]!!.jsonArray
@ -205,7 +205,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.add("client_secret", clientSecret) .add("client_secret", clientSecret)
.build() .build()
client.newCall(POST(loginUrl, body = formBody)) client.newCall(POST(loginUrl, body = formBody))
.await() .awaitSuccess()
.parseAs() .parseAs()
} }
} }
@ -216,7 +216,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.encodedQuery("filter[self]=true") .encodedQuery("filter[self]=true")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
it["data"]!!.jsonArray[0].jsonObject["id"]!!.jsonPrimitive.content it["data"]!!.jsonArray[0].jsonObject["id"]!!.jsonPrimitive.content

View File

@ -4,7 +4,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
@ -28,19 +28,19 @@ class KomgaApi(private val client: OkHttpClient) {
try { try {
val track = if (url.contains(READLIST_API)) { val track = if (url.contains(READLIST_API)) {
client.newCall(GET(url)) client.newCall(GET(url))
.await() .awaitSuccess()
.parseAs<ReadListDto>() .parseAs<ReadListDto>()
.toTrack() .toTrack()
} else { } else {
client.newCall(GET(url)) client.newCall(GET(url))
.await() .awaitSuccess()
.parseAs<SeriesDto>() .parseAs<SeriesDto>()
.toTrack() .toTrack()
} }
val progress = client val progress = client
.newCall(GET("${url.replace("/api/v1/series/", "/api/v2/series/")}/read-progress/tachiyomi")) .newCall(GET("${url.replace("/api/v1/series/", "/api/v2/series/")}/read-progress/tachiyomi"))
.await().let { .awaitSuccess().let {
if (url.contains("/api/v1/series/")) { if (url.contains("/api/v1/series/")) {
it.parseAs<ReadProgressV2Dto>() it.parseAs<ReadProgressV2Dto>()
} else { } else {
@ -77,7 +77,7 @@ class KomgaApi(private val client: OkHttpClient) {
.put(payload.toRequestBody("application/json".toMediaType())) .put(payload.toRequestBody("application/json".toMediaType()))
.build(), .build(),
) )
.await() .awaitSuccess()
return getTrackSearch(track.tracking_url) return getTrackSearch(track.tracking_url)
} }

View File

@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.network.DELETE
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.PUT import eu.kanade.tachiyomi.network.PUT
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@ -53,7 +53,7 @@ class MangaUpdatesApi(
url = "$baseUrl/v1/lists/series/${track.media_id}", url = "$baseUrl/v1/lists/series/${track.media_id}",
), ),
) )
.await() .awaitSuccess()
.parseAs<ListItem>() .parseAs<ListItem>()
val rating = getSeriesRating(track) val rating = getSeriesRating(track)
@ -77,7 +77,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType), body = body.toString().toRequestBody(contentType),
), ),
) )
.await() .awaitSuccess()
.let { .let {
if (it.code == 200) { if (it.code == 200) {
track.status = status track.status = status
@ -104,7 +104,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType), body = body.toString().toRequestBody(contentType),
), ),
) )
.await() .awaitSuccess()
updateSeriesRating(track) updateSeriesRating(track)
} }
@ -116,7 +116,7 @@ class MangaUpdatesApi(
url = "$baseUrl/v1/series/${track.media_id}/rating", url = "$baseUrl/v1/series/${track.media_id}/rating",
), ),
) )
.await() .awaitSuccess()
.parseAs<Rating>() .parseAs<Rating>()
} catch (e: Exception) { } catch (e: Exception) {
null null
@ -134,14 +134,14 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType), body = body.toString().toRequestBody(contentType),
), ),
) )
.await() .awaitSuccess()
} else { } else {
authClient.newCall( authClient.newCall(
DELETE( DELETE(
url = "$baseUrl/v1/series/${track.media_id}/rating", url = "$baseUrl/v1/series/${track.media_id}/rating",
), ),
) )
.await() .awaitSuccess()
} }
} }
@ -162,7 +162,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType), body = body.toString().toRequestBody(contentType),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { obj -> .let { obj ->
obj["results"]?.jsonArray?.map { element -> obj["results"]?.jsonArray?.map { element ->
@ -183,7 +183,7 @@ class MangaUpdatesApi(
body = body.toString().toRequestBody(contentType), body = body.toString().toRequestBody(contentType),
), ),
) )
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { obj -> .let { obj ->
try { try {

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.PkceUtil import eu.kanade.tachiyomi.util.PkceUtil
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
@ -43,7 +43,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.add("grant_type", "authorization_code") .add("grant_type", "authorization_code")
.build() .build()
client.newCall(POST("$baseOAuthUrl/token", body = formBody)) client.newCall(POST("$baseOAuthUrl/token", body = formBody))
.await() .awaitSuccess()
.parseAs() .parseAs()
} }
} }
@ -55,7 +55,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.get() .get()
.build() .build()
authClient.newCall(request) authClient.newCall(request)
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { it["name"]!!.jsonPrimitive.content } .let { it["name"]!!.jsonPrimitive.content }
} }
@ -69,7 +69,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendQueryParameter("nsfw", "true") .appendQueryParameter("nsfw", "true")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
it["data"]!!.jsonArray it["data"]!!.jsonArray
@ -91,7 +91,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date") .appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
val obj = it.jsonObject val obj = it.jsonObject
@ -134,7 +134,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.put(formBodyBuilder.build()) .put(formBodyBuilder.build())
.build() .build()
authClient.newCall(request) authClient.newCall(request)
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { parseMangaItem(it, track) } .let { parseMangaItem(it, track) }
} }
@ -147,7 +147,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}") .appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}")
.build() .build()
authClient.newCall(GET(uri.toString())) authClient.newCall(GET(uri.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { obj -> .let { obj ->
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
@ -199,7 +199,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.get() .get()
.build() .build()
authClient.newCall(request) authClient.newCall(request)
.await() .awaitSuccess()
.parseAs() .parseAs()
} }
} }

View File

@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.jsonMime import eu.kanade.tachiyomi.network.jsonMime
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
@ -46,7 +46,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
"$apiUrl/v2/user_rates", "$apiUrl/v2/user_rates",
body = payload.toString().toRequestBody(jsonMime), body = payload.toString().toRequestBody(jsonMime),
), ),
).await() ).awaitSuccess()
track track
} }
} }
@ -61,7 +61,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
.appendQueryParameter("limit", "20") .appendQueryParameter("limit", "20")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonArray>() .parseAs<JsonArray>()
.let { response -> .let { response ->
response.map { response.map {
@ -103,7 +103,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
.appendPath(track.media_id.toString()) .appendPath(track.media_id.toString())
.build() .build()
val mangas = authClient.newCall(GET(urlMangas.toString())) val mangas = authClient.newCall(GET(urlMangas.toString()))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
val url = "$apiUrl/v2/user_rates".toUri().buildUpon() val url = "$apiUrl/v2/user_rates".toUri().buildUpon()
@ -112,7 +112,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
.appendQueryParameter("target_type", "Manga") .appendQueryParameter("target_type", "Manga")
.build() .build()
authClient.newCall(GET(url.toString())) authClient.newCall(GET(url.toString()))
.await() .awaitSuccess()
.parseAs<JsonArray>() .parseAs<JsonArray>()
.let { response -> .let { response ->
if (response.size > 1) { if (response.size > 1) {
@ -128,7 +128,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
suspend fun getCurrentUser(): Int { suspend fun getCurrentUser(): Int {
return authClient.newCall(GET("$apiUrl/users/whoami")) return authClient.newCall(GET("$apiUrl/users/whoami"))
.await() .awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
.let { .let {
it["id"]!!.jsonPrimitive.int it["id"]!!.jsonPrimitive.int
@ -138,7 +138,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
suspend fun accessToken(code: String): OAuth { suspend fun accessToken(code: String): OAuth {
return withIOContext { return withIOContext {
client.newCall(accessTokenRequest(code)) client.newCall(accessTokenRequest(code))
.await() .awaitSuccess()
.parseAs() .parseAs()
} }
} }

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.PUT import eu.kanade.tachiyomi.network.PUT
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import okhttp3.Credentials import okhttp3.Credentials
@ -50,7 +50,7 @@ class TachideskApi {
trackUrl trackUrl
} }
val manga = client.newCall(GET("$url/full", headers)).await().parseAs<MangaDataClass>() val manga = client.newCall(GET("$url/full", headers)).awaitSuccess().parseAs<MangaDataClass>()
TrackSearch.create(TrackManager.SUWAYOMI).apply { TrackSearch.create(TrackManager.SUWAYOMI).apply {
title = manga.title title = manga.title
@ -70,7 +70,7 @@ class TachideskApi {
suspend fun updateProgress(track: Track): Track { suspend fun updateProgress(track: Track): Track {
val url = track.tracking_url val url = track.tracking_url
val chapters = client.newCall(GET("$url/chapters", headers)).await().parseAs<List<ChapterDataClass>>() val chapters = client.newCall(GET("$url/chapters", headers)).awaitSuccess().parseAs<List<ChapterDataClass>>()
val lastChapterIndex = chapters.first { it.chapterNumber == track.last_chapter_read }.index val lastChapterIndex = chapters.first { it.chapterNumber == track.last_chapter_read }.index
client.newCall( client.newCall(
@ -82,7 +82,7 @@ class TachideskApi {
.add("read", "true") .add("read", "true")
.build(), .build(),
), ),
).await() ).awaitSuccess()
return getTrackSearch(track.tracking_url) return getTrackSearch(track.tracking_url)
} }

View File

@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.core.preference.Preference
import eu.kanade.tachiyomi.core.preference.PreferenceStore import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.isInstalledFromFDroid import eu.kanade.tachiyomi.util.system.isInstalledFromFDroid
@ -34,7 +34,7 @@ class AppUpdateChecker {
return withIOContext { return withIOContext {
val result = networkService.client val result = networkService.client
.newCall(GET("https://api.github.com/repos/$GITHUB_REPO/releases/latest")) .newCall(GET("https://api.github.com/repos/$GITHUB_REPO/releases/latest"))
.await() .awaitSuccess()
.parseAs<GithubRelease>() .parseAs<GithubRelease>()
.let { .let {
lastAppCheck.set(Date().time) lastAppCheck.set(Date().time)

View File

@ -12,7 +12,7 @@ import eu.kanade.tachiyomi.extension.model.LoadResult
import eu.kanade.tachiyomi.extension.util.ExtensionLoader import eu.kanade.tachiyomi.extension.util.ExtensionLoader
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
@ -47,7 +47,7 @@ internal class ExtensionGithubApi {
try { try {
networkService.client networkService.client
.newCall(GET("${REPO_URL_PREFIX}index.min.json")) .newCall(GET("${REPO_URL_PREFIX}index.min.json"))
.await() .awaitSuccess()
} catch (e: Throwable) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" } logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" }
requiresFallbackSource = true requiresFallbackSource = true
@ -58,7 +58,7 @@ internal class ExtensionGithubApi {
val response = githubResponse ?: run { val response = githubResponse ?: run {
networkService.client networkService.client
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json")) .newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
.await() .awaitSuccess()
} }
val extensions = response val extensions = response
@ -73,7 +73,7 @@ internal class ExtensionGithubApi {
} }
networkService.client networkService.client
.newCall(GET("${url}index.min.json")) .newCall(GET("${url}index.min.json"))
.await() .awaitSuccess()
.parseAs<List<ExtensionJsonObject>>() .parseAs<List<ExtensionJsonObject>>()
.toExtensions(url, repoSource = true) .toExtensions(url, repoSource = true)
} }

View File

@ -9,6 +9,7 @@ import eu.kanade.domain.UnsortedPreferences
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.newCachelessCallWithProgress import eu.kanade.tachiyomi.network.newCachelessCallWithProgress
import eu.kanade.tachiyomi.source.PagePreviewInfo import eu.kanade.tachiyomi.source.PagePreviewInfo
import eu.kanade.tachiyomi.source.PagePreviewPage import eu.kanade.tachiyomi.source.PagePreviewPage
@ -50,7 +51,6 @@ import exh.ui.login.EhLoginActivity
import exh.util.UriFilter import exh.util.UriFilter
import exh.util.UriGroup import exh.util.UriGroup
import exh.util.asObservableWithAsyncStacktrace import exh.util.asObservableWithAsyncStacktrace
import exh.util.awaitResponse
import exh.util.dropBlank import exh.util.dropBlank
import exh.util.ignore import exh.util.ignore
import exh.util.nullIfBlank import exh.util.nullIfBlank
@ -339,7 +339,7 @@ class EHentai(
) )
if (cachedParent == null) { if (cachedParent == null) {
throttleFunc() throttleFunc()
doc = client.newCall(exGet(baseUrl + url)).await().asJsoup() doc = client.newCall(exGet(baseUrl + url)).awaitSuccess().asJsoup()
val parentLink = doc.select("#gdd .gdt1").find { el -> val parentLink = doc.select("#gdd .gdt1").find { el ->
el.text().lowercase() == "parent:" el.text().lowercase() == "parent:"
@ -612,7 +612,7 @@ class EHentai(
override suspend fun getMangaDetails(manga: SManga): SManga { override suspend fun getMangaDetails(manga: SManga): SManga {
val exception = Exception("Async stacktrace") val exception = Exception("Async stacktrace")
val response = client.newCall(mangaDetailsRequest(manga)).awaitResponse() val response = client.newCall(mangaDetailsRequest(manga)).await()
if (response.isSuccessful) { if (response.isSuccessful) {
// Pull to most recent // Pull to most recent
val doc = response.asJsoup() val doc = response.asJsoup()
@ -621,7 +621,7 @@ class EHentai(
val sManga = manga.copy( val sManga = manga.copy(
url = EHentaiSearchMetadata.normalizeUrl(newerGallery.attr("href")), url = EHentaiSearchMetadata.normalizeUrl(newerGallery.attr("href")),
) )
client.newCall(mangaDetailsRequest(sManga)).await().asJsoup() client.newCall(mangaDetailsRequest(sManga)).awaitSuccess().asJsoup()
} else { } else {
doc doc
} }
@ -790,7 +790,7 @@ class EHentai(
next = page, next = page,
cacheControl = CacheControl.FORCE_NETWORK, cacheControl = CacheControl.FORCE_NETWORK,
), ),
).awaitResponse() ).await()
} }
val doc = response2.asJsoup() val doc = response2.asJsoup()
@ -1142,7 +1142,7 @@ class EHentai(
.build() .build()
.toString(), .toString(),
), ),
).await().asJsoup() ).awaitSuccess().asJsoup()
val previews = if (doc.selectFirst("div#gdo4 .ths")!!.attr("onClick").contains("inline_set=ts_l")) { val previews = if (doc.selectFirst("div#gdo4 .ths")!!.attr("onClick").contains("inline_set=ts_l")) {
doc.body() doc.body()
.select("#gdt div a") .select("#gdt div a")
@ -1169,7 +1169,7 @@ class EHentai(
} }
override suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response { override suspend fun fetchPreviewImage(page: PagePreviewInfo, cacheControl: CacheControl?): Response {
return client.newCachelessCallWithProgress(exGet(page.imageUrl, cacheControl = cacheControl), page).await() return client.newCachelessCallWithProgress(exGet(page.imageUrl, cacheControl = cacheControl), page).awaitSuccess()
} }
/** /**

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.newCachelessCallWithProgress import eu.kanade.tachiyomi.network.newCachelessCallWithProgress
import eu.kanade.tachiyomi.source.PagePreviewInfo import eu.kanade.tachiyomi.source.PagePreviewInfo
import eu.kanade.tachiyomi.source.PagePreviewPage import eu.kanade.tachiyomi.source.PagePreviewPage
@ -55,7 +55,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
} }
override suspend fun getMangaDetails(manga: SManga): SManga { override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await() val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response) return parseToManga(manga, response)
} }
@ -175,7 +175,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
override suspend fun getPagePreviewList(manga: SManga, chapters: List<SChapter>, page: Int): PagePreviewPage { override suspend fun getPagePreviewList(manga: SManga, chapters: List<SChapter>, page: Int): PagePreviewPage {
val metadata = fetchOrLoadMetadata(manga.id()) { val metadata = fetchOrLoadMetadata(manga.id()) {
client.newCall(mangaDetailsRequest(manga)).await() client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
} }
return PagePreviewPage( return PagePreviewPage(
page, page,
@ -199,7 +199,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
GET(page.imageUrl) GET(page.imageUrl)
}, },
page, page,
).await() ).awaitSuccess()
} }
companion object { companion object {

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
@ -33,7 +33,7 @@ class EightMuses(delegate: HttpSource, val context: Context) :
} }
override suspend fun getMangaDetails(manga: SManga): SManga { override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await() val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup()) return parseToManga(manga, response.asJsoup())
} }

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
@ -32,7 +32,7 @@ class HBrowse(delegate: HttpSource, val context: Context) :
} }
override suspend fun getMangaDetails(manga: SManga): SManga { override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await() val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup()) return parseToManga(manga, response.asJsoup())
} }

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri import androidx.core.net.toUri
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
@ -52,7 +52,7 @@ class Pururin(delegate: HttpSource, val context: Context) :
} }
override suspend fun getMangaDetails(manga: SManga): SManga { override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await() val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup()) return parseToManga(manga, response.asJsoup())
} }

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.source.online.english
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
@ -47,7 +47,7 @@ class Tsumino(delegate: HttpSource, val context: Context) :
} }
override suspend fun getMangaDetails(manga: SManga): SManga { override suspend fun getMangaDetails(manga: SManga): SManga {
val response = client.newCall(mangaDetailsRequest(manga)).await() val response = client.newCall(mangaDetailsRequest(manga)).awaitSuccess()
return parseToManga(manga, response.asJsoup()) return parseToManga(manga, response.asJsoup())
} }

View File

@ -1,7 +1,7 @@
package exh.md.handlers package exh.md.handlers
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
@ -24,7 +24,7 @@ class AzukiHandler(currentClient: OkHttpClient, userAgent: String) {
suspend fun fetchPageList(externalUrl: String): List<Page> { suspend fun fetchPageList(externalUrl: String): List<Page> {
val chapterId = externalUrl.substringAfterLast("/").substringBefore("?") val chapterId = externalUrl.substringAfterLast("/").substringBefore("?")
val request = pageListRequest(chapterId) val request = pageListRequest(chapterId)
return pageListParse(client.newCall(request).await()) return pageListParse(client.newCall(request).awaitSuccess())
} }
private fun pageListRequest(chapterId: String): Request { private fun pageListRequest(chapterId: String): Request {

View File

@ -2,7 +2,7 @@ package exh.md.handlers
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -92,7 +92,7 @@ class BilibiliHandler(currentClient: OkHttpClient) {
} }
suspend fun getChapterList(mangaUrl: String): List<SChapter> { suspend fun getChapterList(mangaUrl: String): List<SChapter> {
val response = client.newCall(mangaDetailsApiRequest(mangaUrl)).await() val response = client.newCall(mangaDetailsApiRequest(mangaUrl)).awaitSuccess()
return chapterListParse(response) return chapterListParse(response)
} }
@ -115,7 +115,7 @@ class BilibiliHandler(currentClient: OkHttpClient) {
) )
private suspend fun fetchPageList(chapterUrl: String): List<Page> { private suspend fun fetchPageList(chapterUrl: String): List<Page> {
val response = client.newCall(pageListRequest(chapterUrl)).await() val response = client.newCall(pageListRequest(chapterUrl)).awaitSuccess()
return pageListParse(response) return pageListParse(response)
} }

View File

@ -1,7 +1,7 @@
package exh.md.handlers package exh.md.handlers
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@ -29,13 +29,13 @@ class ComikeyHandler(cloudflareClient: OkHttpClient, userAgent: String) {
suspend fun fetchPageList(externalUrl: String): List<Page> { suspend fun fetchPageList(externalUrl: String): List<Page> {
val httpUrl = externalUrl.toHttpUrl() val httpUrl = externalUrl.toHttpUrl()
val mangaId = getMangaId(httpUrl.pathSegments[1]) val mangaId = getMangaId(httpUrl.pathSegments[1])
val response = client.newCall(pageListRequest(mangaId, httpUrl.pathSegments[2])).await() val response = client.newCall(pageListRequest(mangaId, httpUrl.pathSegments[2])).awaitSuccess()
val request = getActualPageList(response) ?: return listOf(Page(0, urlForbidden, urlForbidden)) val request = getActualPageList(response) ?: return listOf(Page(0, urlForbidden, urlForbidden))
return pageListParse(client.newCall(request).await()) return pageListParse(client.newCall(request).awaitSuccess())
} }
suspend fun getMangaId(mangaUrl: String): Int { suspend fun getMangaId(mangaUrl: String): Int {
val response = client.newCall(GET("$baseUrl/read/$mangaUrl")).await() val response = client.newCall(GET("$baseUrl/read/$mangaUrl")).awaitSuccess()
val url = response.asJsoup().selectFirst("meta[property=og:url]")!!.attr("content") val url = response.asJsoup().selectFirst("meta[property=og:url]")!!.attr("content")
return url.trimEnd('/').substringAfterLast('/').toInt() return url.trimEnd('/').substringAfterLast('/').toInt()
} }

View File

@ -1,7 +1,7 @@
package exh.md.handlers package exh.md.handlers
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
@ -22,7 +22,7 @@ class MangaHotHandler(currentClient: OkHttpClient, userAgent: String) {
suspend fun fetchPageList(externalUrl: String): List<Page> { suspend fun fetchPageList(externalUrl: String): List<Page> {
val request = GET(externalUrl.substringBefore("?").replace(baseUrl, apiUrl).replace("viewer", "v1/works/storyDetail"), headers) val request = GET(externalUrl.substringBefore("?").replace(baseUrl, apiUrl).replace("viewer", "v1/works/storyDetail"), headers)
return pageListParse(client.newCall(request).await()) return pageListParse(client.newCall(request).awaitSuccess())
} }
fun pageListParse(response: Response): List<Page> { fun pageListParse(response: Response): List<Page> {

View File

@ -1,7 +1,7 @@
package exh.md.handlers package exh.md.handlers
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import exh.md.dto.MangaPlusResponse import exh.md.dto.MangaPlusResponse
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
@ -28,7 +28,7 @@ class MangaPlusHandler(currentClient: OkHttpClient) {
.build() .build()
suspend fun fetchPageList(chapterId: String): List<Page> { suspend fun fetchPageList(chapterId: String): List<Page> {
val response = client.newCall(pageListRequest(chapterId.substringAfterLast("/"))).await() val response = client.newCall(pageListRequest(chapterId.substringAfterLast("/"))).awaitSuccess()
return pageListParse(response) return pageListParse(response)
} }

View File

@ -4,7 +4,7 @@ import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.tachiyomi.data.track.mdlist.MdList import eu.kanade.tachiyomi.data.track.mdlist.MdList
import eu.kanade.tachiyomi.data.track.myanimelist.OAuth import eu.kanade.tachiyomi.data.track.myanimelist.OAuth
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import exh.md.utils.MdApi import exh.md.utils.MdApi
@ -35,7 +35,7 @@ class MangaDexLoginHelper(
.build() .build()
val error = kotlin.runCatching { val error = kotlin.runCatching {
val data = client.newCall(POST(MdApi.baseAuthUrl + MdApi.token, body = loginFormBody)).await().parseAs<OAuth>() val data = client.newCall(POST(MdApi.baseAuthUrl + MdApi.token, body = loginFormBody)).awaitSuccess().parseAs<OAuth>()
mangaDexAuthInterceptor.setAuth(data) mangaDexAuthInterceptor.setAuth(data)
}.exceptionOrNull() }.exceptionOrNull()
@ -72,7 +72,7 @@ class MangaDexLoginHelper(
.build(), .build(),
body = formBody, body = formBody,
), ),
).await() ).awaitSuccess()
mdList.logout() mdList.logout()
}.exceptionOrNull() }.exceptionOrNull()

View File

@ -2,7 +2,7 @@ package exh.md.service
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.MangaListDto import exh.md.dto.MangaListDto
import exh.md.dto.RatingDto import exh.md.dto.RatingDto
@ -32,7 +32,7 @@ class MangaDexAuthService(
headers, headers,
CacheControl.FORCE_NETWORK, CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun readingStatusForManga(mangaId: String): ReadingStatusDto { suspend fun readingStatusForManga(mangaId: String): ReadingStatusDto {
@ -42,7 +42,7 @@ class MangaDexAuthService(
headers, headers,
CacheControl.FORCE_NETWORK, CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun readChaptersForManga(mangaId: String): ReadChapterDto { suspend fun readChaptersForManga(mangaId: String): ReadChapterDto {
@ -52,7 +52,7 @@ class MangaDexAuthService(
headers, headers,
CacheControl.FORCE_NETWORK, CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun updateReadingStatusForManga( suspend fun updateReadingStatusForManga(
@ -66,7 +66,7 @@ class MangaDexAuthService(
body = MdUtil.encodeToBody(readingStatusDto), body = MdUtil.encodeToBody(readingStatusDto),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun readingStatusAllManga(): ReadingStatusMapDto { suspend fun readingStatusAllManga(): ReadingStatusMapDto {
@ -76,7 +76,7 @@ class MangaDexAuthService(
headers, headers,
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun readingStatusByType(status: String): ReadingStatusMapDto { suspend fun readingStatusByType(status: String): ReadingStatusMapDto {
@ -86,7 +86,7 @@ class MangaDexAuthService(
headers, headers,
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun markChapterRead(chapterId: String): ResultDto { suspend fun markChapterRead(chapterId: String): ResultDto {
@ -96,7 +96,7 @@ class MangaDexAuthService(
headers, headers,
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun markChapterUnRead(chapterId: String): ResultDto { suspend fun markChapterUnRead(chapterId: String): ResultDto {
@ -107,7 +107,7 @@ class MangaDexAuthService(
.headers(headers) .headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK) .cacheControl(CacheControl.FORCE_NETWORK)
.build(), .build(),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun followManga(mangaId: String): ResultDto { suspend fun followManga(mangaId: String): ResultDto {
@ -117,7 +117,7 @@ class MangaDexAuthService(
headers, headers,
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun unfollowManga(mangaId: String): ResultDto { suspend fun unfollowManga(mangaId: String): ResultDto {
@ -128,7 +128,7 @@ class MangaDexAuthService(
.headers(headers) .headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK) .cacheControl(CacheControl.FORCE_NETWORK)
.build(), .build(),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun updateMangaRating(mangaId: String, rating: Int): ResultDto { suspend fun updateMangaRating(mangaId: String, rating: Int): ResultDto {
@ -139,7 +139,7 @@ class MangaDexAuthService(
body = MdUtil.encodeToBody(RatingDto(rating)), body = MdUtil.encodeToBody(RatingDto(rating)),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun deleteMangaRating(mangaId: String): ResultDto { suspend fun deleteMangaRating(mangaId: String): ResultDto {
@ -150,7 +150,7 @@ class MangaDexAuthService(
.headers(headers) .headers(headers)
.cacheControl(CacheControl.FORCE_NETWORK) .cacheControl(CacheControl.FORCE_NETWORK)
.build(), .build(),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun mangasRating(vararg mangaIds: String): RatingResponseDto { suspend fun mangasRating(vararg mangaIds: String): RatingResponseDto {
@ -167,6 +167,6 @@ class MangaDexAuthService(
headers, headers,
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
} }

View File

@ -2,7 +2,7 @@ package exh.md.service
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.AggregateDto import exh.md.dto.AggregateDto
import exh.md.dto.AtHomeDto import exh.md.dto.AtHomeDto
@ -45,7 +45,7 @@ class MangaDexService(
.build(), .build(),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun viewManga( suspend fun viewManga(
@ -64,7 +64,7 @@ class MangaDexService(
.build(), .build(),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun mangasRating( suspend fun mangasRating(
@ -82,7 +82,7 @@ class MangaDexService(
.build(), .build(),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun aggregateChapters( suspend fun aggregateChapters(
@ -101,7 +101,7 @@ class MangaDexService(
.build(), .build(),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
private fun String.splitString() = replace("\n", "").split(',').trimAll().dropEmpty() private fun String.splitString() = replace("\n", "").split(',').trimAll().dropEmpty()
@ -142,18 +142,18 @@ class MangaDexService(
url, url,
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun viewChapter(id: String): ChapterDto { suspend fun viewChapter(id: String): ChapterDto {
return client.newCall(GET("${MdApi.chapter}/$id", cache = CacheControl.FORCE_NETWORK)) return client.newCall(GET("${MdApi.chapter}/$id", cache = CacheControl.FORCE_NETWORK))
.await() .awaitSuccess()
.parseAs(MdUtil.jsonParser) .parseAs(MdUtil.jsonParser)
} }
suspend fun randomManga(): MangaDto { suspend fun randomManga(): MangaDto {
return client.newCall(GET("${MdApi.manga}/random", cache = CacheControl.FORCE_NETWORK)) return client.newCall(GET("${MdApi.manga}/random", cache = CacheControl.FORCE_NETWORK))
.await() .awaitSuccess()
.parseAs(MdUtil.jsonParser) .parseAs(MdUtil.jsonParser)
} }
@ -164,7 +164,7 @@ class MangaDexService(
body = MdUtil.encodeToBody(atHomeImageReportDto), body = MdUtil.encodeToBody(atHomeImageReportDto),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
suspend fun getAtHomeServer( suspend fun getAtHomeServer(
@ -172,7 +172,7 @@ class MangaDexService(
headers: Headers, headers: Headers,
): AtHomeDto { ): AtHomeDto {
return client.newCall(GET(atHomeRequestUrl, headers, CacheControl.FORCE_NETWORK)) return client.newCall(GET(atHomeRequestUrl, headers, CacheControl.FORCE_NETWORK))
.await() .awaitSuccess()
.parseAs(MdUtil.jsonParser) .parseAs(MdUtil.jsonParser)
} }
@ -187,6 +187,6 @@ class MangaDexService(
.build(), .build(),
cache = CacheControl.FORCE_NETWORK, cache = CacheControl.FORCE_NETWORK,
), ),
).await().parseAs(MdUtil.jsonParser) ).awaitSuccess().parseAs(MdUtil.jsonParser)
} }
} }

View File

@ -1,7 +1,7 @@
package exh.md.service package exh.md.service
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.SimilarMangaDto import exh.md.dto.SimilarMangaDto
import exh.md.utils.MdUtil import exh.md.utils.MdUtil
@ -15,6 +15,6 @@ class SimilarService(
GET( GET(
"${MdUtil.similarBaseApi}$mangaId.json", "${MdUtil.similarBaseApi}$mangaId.json",
), ),
).await().parseAs() ).awaitSuccess().parseAs()
} }
} }

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
@ -52,7 +52,7 @@ class MyAnimeList : API("https://api.jikan.moe/v4/") {
.addPathSegment("recommendations") .addPathSegment("recommendations")
.build() .build()
val data = client.newCall(GET(apiUrl)).await().parseAs<JsonObject>() val data = client.newCall(GET(apiUrl)).awaitSuccess().parseAs<JsonObject>()
return data["data"]!!.jsonArray return data["data"]!!.jsonArray
.map { it.jsonObject["entry"]!!.jsonObject } .map { it.jsonObject["entry"]!!.jsonObject }
.map { rec -> .map { rec ->
@ -88,7 +88,7 @@ class MyAnimeList : API("https://api.jikan.moe/v4/") {
.addQueryParameter("q", search) .addQueryParameter("q", search)
.build() .build()
val data = client.newCall(GET(url)).await() val data = client.newCall(GET(url)).awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
return getRecsById(data["data"]!!.jsonArray.first().jsonObject["mal_id"]!!.jsonPrimitive.content) return getRecsById(data["data"]!!.jsonArray.first().jsonObject["mal_id"]!!.jsonPrimitive.content)
} }
@ -137,7 +137,7 @@ class Anilist : API("https://graphql.anilist.co/") {
} }
val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaType()) val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaType())
val data = client.newCall(POST(endpoint, body = payloadBody)).await() val data = client.newCall(POST(endpoint, body = payloadBody)).awaitSuccess()
.parseAs<JsonObject>() .parseAs<JsonObject>()
val media = data["data"]!! val media = data["data"]!!

View File

@ -3,7 +3,7 @@ package exh.uconfig
import android.content.Context import android.content.Context
import eu.kanade.domain.UnsortedPreferences import eu.kanade.domain.UnsortedPreferences
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.EHentai import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
@ -46,7 +46,7 @@ class EHConfigurator(val context: Context) {
) )
.build(), .build(),
) )
.await() .awaitSuccess()
private val EHentai.uconfigUrl get() = baseUrl + UCONFIG_URL private val EHentai.uconfigUrl get() = baseUrl + UCONFIG_URL
@ -60,7 +60,7 @@ class EHConfigurator(val context: Context) {
.url(HATH_PERKS_URL) .url(HATH_PERKS_URL)
.build(), .build(),
) )
.await().asJsoup() .awaitSuccess().asJsoup()
val hathPerks = EHHathPerksResponse() val hathPerks = EHHathPerksResponse()
@ -90,7 +90,7 @@ class EHConfigurator(val context: Context) {
private suspend fun configure(source: EHentai, hathPerks: EHHathPerksResponse) { private suspend fun configure(source: EHentai, hathPerks: EHHathPerksResponse) {
// Delete old app profiles // Delete old app profiles
val scanReq = source.requestWithCreds().url(source.uconfigUrl).build() val scanReq = source.requestWithCreds().url(source.uconfigUrl).build()
val resp = configuratorClient.newCall(scanReq).await().asJsoup() val resp = configuratorClient.newCall(scanReq).awaitSuccess().asJsoup()
var lastDoc = resp var lastDoc = resp
resp.select(PROFILE_SELECTOR).forEach { resp.select(PROFILE_SELECTOR).forEach {
if (it.text() == PROFILE_NAME) { if (it.text() == PROFILE_NAME) {
@ -129,7 +129,7 @@ class EHConfigurator(val context: Context) {
.url(source.uconfigUrl) .url(source.uconfigUrl)
.post(form) .post(form)
.build(), .build(),
).await() ).awaitSuccess()
// Persist slot + sk // Persist slot + sk
source.spPref().set(slot) source.spPref().set(slot)

View File

@ -1,17 +1,11 @@
package exh.util package exh.util
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Call import okhttp3.Call
import okhttp3.Callback
import okhttp3.Response import okhttp3.Response
import okhttp3.internal.closeQuietly
import rx.Observable import rx.Observable
import rx.Producer import rx.Producer
import rx.Subscription import rx.Subscription
import java.io.IOException
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
fun Call.asObservableWithAsyncStacktrace(): Observable<Pair<Exception, Response>> { fun Call.asObservableWithAsyncStacktrace(): Observable<Pair<Exception, Response>> {
// Record stacktrace at creation time for easier debugging // Record stacktrace at creation time for easier debugging
@ -58,34 +52,3 @@ fun Call.asObservableWithAsyncStacktrace(): Observable<Pair<Exception, Response>
subscriber.setProducer(requestArbiter) subscriber.setProducer(requestArbiter)
} }
} }
/**
* Similar to [Call.await] but it doesn't throw when the response is not successful
*/
suspend fun Call.awaitResponse(): Response {
return suspendCancellableCoroutine { continuation ->
enqueue(
object : Callback {
override fun onResponse(call: Call, response: Response) {
continuation.resume(response) {
response.closeQuietly()
}
}
override fun onFailure(call: Call, e: IOException) {
// Don't bother with resuming the continuation if it is already cancelled.
if (continuation.isCancelled) return
continuation.resumeWithException(e)
}
},
)
continuation.invokeOnCancellation {
try {
cancel()
} catch (ex: Throwable) {
// Ignore cancel exception
}
}
}
}

View File

@ -65,16 +65,11 @@ fun Call.asObservable(): Observable<Response> {
// Based on https://github.com/gildor/kotlin-coroutines-okhttp // Based on https://github.com/gildor/kotlin-coroutines-okhttp
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
suspend fun Call.await(): Response { private suspend fun Call.await(callStack: Array<StackTraceElement>): Response {
return suspendCancellableCoroutine { continuation -> return suspendCancellableCoroutine { continuation ->
enqueue( val callback =
object : Callback { object : Callback {
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
if (!response.isSuccessful) {
continuation.resumeWithException(HttpException(response.code))
return
}
continuation.resume(response) { continuation.resume(response) {
response.body.close() response.body.close()
} }
@ -83,11 +78,12 @@ suspend fun Call.await(): Response {
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
// Don't bother with resuming the continuation if it is already cancelled. // Don't bother with resuming the continuation if it is already cancelled.
if (continuation.isCancelled) return if (continuation.isCancelled) return
val exception = IOException(e).apply { stackTrace = callStack }
continuation.resumeWithException(e) continuation.resumeWithException(exception)
} }
}, }
)
enqueue(callback)
continuation.invokeOnCancellation { continuation.invokeOnCancellation {
try { try {
@ -99,6 +95,21 @@ suspend fun Call.await(): Response {
} }
} }
suspend fun Call.await(): Response {
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
return await(callStack)
}
suspend fun Call.awaitSuccess(): Response {
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
val response = await(callStack)
if (!response.isSuccessful) {
response.close()
throw HttpException(response.code).apply { stackTrace = callStack }
}
return response
}
fun Call.asObservableSuccess(): Observable<Response> { fun Call.asObservableSuccess(): Observable<Response> {
return asObservable().doOnNext { response -> return asObservable().doOnNext { response ->
if (!response.isSuccessful) { if (!response.isSuccessful) {