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

This commit is contained in:
stevenyomi 2023-01-25 11:34:31 +08:00 committed by GitHub
parent 2ef1f07aae
commit 448702e5be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 86 additions and 75 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
@ -31,7 +31,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

@ -10,7 +10,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
@ -39,7 +39,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
@ -50,7 +50,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

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) {