Skip to content

Commit 76a2feb

Browse files
authored
Add fallback url for kitsu sync (#2552)
1 parent 81c7d90 commit 76a2feb

1 file changed

Lines changed: 63 additions & 19 deletions

File tree

  • app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers

app/src/main/java/com/lagradost/cloudstream3/syncproviders/providers/KitsuApi.kt

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import androidx.annotation.StringRes
55
import com.fasterxml.jackson.annotation.JsonProperty
66
import com.lagradost.cloudstream3.CloudStreamApp.Companion.getKey
77
import com.lagradost.cloudstream3.CloudStreamApp.Companion.setKey
8-
import com.lagradost.cloudstream3.app
98
import com.lagradost.cloudstream3.R
109
import com.lagradost.cloudstream3.Score
1110
import com.lagradost.cloudstream3.ShowStatus
1211
import com.lagradost.cloudstream3.TvType
12+
import com.lagradost.cloudstream3.app
1313
import com.lagradost.cloudstream3.mvvm.logError
1414
import com.lagradost.cloudstream3.syncproviders.AuthData
1515
import com.lagradost.cloudstream3.syncproviders.AuthLoginRequirement
@@ -22,18 +22,16 @@ import com.lagradost.cloudstream3.ui.SyncWatchType
2222
import com.lagradost.cloudstream3.ui.library.ListSorting
2323
import com.lagradost.cloudstream3.utils.AppUtils.toJson
2424
import com.lagradost.cloudstream3.utils.txt
25-
import kotlinx.coroutines.flow.asFlow
26-
import kotlinx.coroutines.flow.collect
27-
import kotlinx.coroutines.flow.onEach
28-
import kotlinx.coroutines.flow.withIndex
25+
import okhttp3.Interceptor
26+
import okhttp3.Request
2927
import okhttp3.RequestBody.Companion.toRequestBody
28+
import okhttp3.Response
3029
import java.text.SimpleDateFormat
3130
import java.time.Instant
3231
import java.time.LocalDate
3332
import java.time.format.DateTimeFormatter
3433
import java.util.Date
3534
import java.util.Locale
36-
import kotlin.collections.set
3735

3836
const val KITSU_MAX_SEARCH_LIMIT = 20
3937

@@ -42,7 +40,9 @@ class KitsuApi: SyncAPI() {
4240
override val idPrefix = "kitsu"
4341

4442
private val apiUrl = "https://kitsu.io/api/edge"
43+
private val fallbackApiUrl = "https://kitsu.app/api/edge"
4544
private val oauthUrl = "https://kitsu.io/api/oauth"
45+
private val fallbackOauthUrl = "https://kitsu.app/api/oauth"
4646
override val hasInApp = true
4747
override val mainUrl = "https://kitsu.app"
4848
override val icon = R.drawable.kitsu_icon
@@ -63,6 +63,33 @@ class KitsuApi: SyncAPI() {
6363
email = true
6464
)
6565

66+
private class FallbackInterceptor(private val apiUrl: String, private val fallbackApiUrl: String) : Interceptor {
67+
override fun intercept(chain: Interceptor.Chain): Response {
68+
val request: Request = chain.request()
69+
70+
try {
71+
72+
val response = chain.proceed(request);
73+
74+
if (response.isSuccessful) return response
75+
76+
response.close()
77+
78+
} catch (_: Exception) {
79+
}
80+
81+
val fallbackRequest: Request = request.newBuilder()
82+
.url(request.url.toString().replaceFirst(apiUrl, fallbackApiUrl))
83+
.build()
84+
85+
return chain.proceed(fallbackRequest)
86+
87+
}
88+
}
89+
90+
private val apiFallbackInterceptor = FallbackInterceptor(apiUrl, fallbackApiUrl)
91+
private val oauthFallbackInterceptor = FallbackInterceptor(oauthUrl, fallbackOauthUrl)
92+
6693
override suspend fun login(form: AuthLoginResponse): AuthToken? {
6794
val username = form.email ?: return null
6895
val password = form.password ?: return null
@@ -75,8 +102,10 @@ class KitsuApi: SyncAPI() {
75102
"grant_type" to grantType,
76103
"username" to username,
77104
"password" to password
78-
)
105+
),
106+
interceptor = oauthFallbackInterceptor
79107
).parsed<ResponseToken>()
108+
80109
return AuthToken(
81110
accessTokenLifetime = unixTime + token.expiresIn.toLong(),
82111
refreshToken = token.refreshToken,
@@ -90,7 +119,8 @@ class KitsuApi: SyncAPI() {
90119
data = mapOf(
91120
"grant_type" to "refresh_token",
92121
"refresh_token" to token.refreshToken!!
93-
)
122+
),
123+
interceptor = oauthFallbackInterceptor
94124
).parsed<ResponseToken>()
95125

96126
return AuthToken(
@@ -105,7 +135,8 @@ class KitsuApi: SyncAPI() {
105135
"$apiUrl/users?filter[self]=true",
106136
headers = mapOf(
107137
"Authorization" to "Bearer ${token?.accessToken ?: return null}"
108-
), cacheTime = 0
138+
), cacheTime = 0,
139+
interceptor = apiFallbackInterceptor
109140
).parsed<KitsuResponse>()
110141

111142
if (user.data.isEmpty()) {
@@ -123,11 +154,14 @@ class KitsuApi: SyncAPI() {
123154
val auth = auth?.token?.accessToken ?: return null
124155
val animeSelectedFields = arrayOf("titles","canonicalTitle","posterImage","episodeCount")
125156
val url = "$apiUrl/anime?filter[text]=$query&page[limit]=$KITSU_MAX_SEARCH_LIMIT&fields[anime]=${animeSelectedFields.joinToString(",")}"
157+
126158
val res = app.get(
127159
url, headers = mapOf(
128160
"Authorization" to "Bearer $auth",
129-
), cacheTime = 0
161+
), cacheTime = 0,
162+
interceptor = apiFallbackInterceptor
130163
).parsed<KitsuResponse>()
164+
131165
return res.data.map {
132166
val attributes = it.attributes
133167

@@ -160,7 +194,8 @@ class KitsuApi: SyncAPI() {
160194
val anime = app.get(
161195
url, headers = mapOf(
162196
"Authorization" to "Bearer $auth"
163-
)
197+
),
198+
interceptor = apiFallbackInterceptor
164199
).parsed<KitsuResponse>().data.attributes
165200

166201
return SyncResult(
@@ -201,7 +236,8 @@ class KitsuApi: SyncAPI() {
201236
val anime = app.get(
202237
url, headers = mapOf(
203238
"Authorization" to "Bearer $accessToken"
204-
)
239+
),
240+
interceptor = apiFallbackInterceptor
205241
).parsed<KitsuResponse>().data.firstOrNull()?.attributes
206242

207243
if (anime == null) {
@@ -224,7 +260,8 @@ class KitsuApi: SyncAPI() {
224260

225261
val animeSelectedFields = arrayOf("titles","canonicalTitle")
226262
val url = "$apiUrl/anime?filter[text]=$title&page[limit]=$KITSU_MAX_SEARCH_LIMIT&fields[anime]=${animeSelectedFields.joinToString(",")}"
227-
val res = app.get(url).parsed<KitsuResponse>()
263+
264+
val res = app.get(url, interceptor = apiFallbackInterceptor).parsed<KitsuResponse>()
228265

229266
return res.data.firstOrNull()?.id
230267

@@ -269,8 +306,10 @@ class KitsuApi: SyncAPI() {
269306
headers = mapOf(
270307
"Authorization" to "Bearer ${auth.token.accessToken}"
271308
),
309+
interceptor = apiFallbackInterceptor
272310
)
273311

312+
274313
return res.isSuccessful
275314

276315
}
@@ -316,7 +355,8 @@ class KitsuApi: SyncAPI() {
316355
"content-type" to "application/vnd.api+json",
317356
"Authorization" to "Bearer ${auth.token.accessToken}"
318357
),
319-
requestBody = data.toJson().toRequestBody()
358+
requestBody = data.toJson().toRequestBody(),
359+
interceptor = apiFallbackInterceptor
320360
)
321361

322362
return res.isSuccessful
@@ -349,9 +389,11 @@ class KitsuApi: SyncAPI() {
349389
"content-type" to "application/vnd.api+json",
350390
"Authorization" to "Bearer ${auth.token.accessToken}"
351391
),
352-
requestBody = data.toJson().toRequestBody()
392+
requestBody = data.toJson().toRequestBody(),
393+
interceptor = apiFallbackInterceptor
353394
)
354395

396+
355397
return res.isSuccessful
356398

357399
}
@@ -365,6 +407,7 @@ class KitsuApi: SyncAPI() {
365407
headers = mapOf(
366408
"Authorization" to "Bearer ${auth.token.accessToken}"
367409
),
410+
interceptor = apiFallbackInterceptor
368411
).parsed<KitsuResponse>().data.firstOrNull() ?: return null
369412

370413
return res.id.toInt()
@@ -439,7 +482,8 @@ class KitsuApi: SyncAPI() {
439482
val res = app.get(
440483
url, headers = mapOf(
441484
"Authorization" to "Bearer ${token.accessToken}",
442-
)
485+
),
486+
interceptor = apiFallbackInterceptor
443487
).parsed<KitsuResponse>()
444488
return res
445489
}
@@ -474,7 +518,7 @@ class KitsuApi: SyncAPI() {
474518

475519
val animeId = animeItem?.id
476520

477-
val description: String? = animeItem?.attributes?.synopsis
521+
val synopsis: String? = animeItem?.attributes?.synopsis
478522

479523
return LibraryItem(
480524
canonicalTitle ?: titles?.enJp ?: titles?.jaJp.orEmpty(),
@@ -489,7 +533,7 @@ class KitsuApi: SyncAPI() {
489533
posterImage?.large ?: posterImage?.medium,
490534
null,
491535
null,
492-
plot = description,
536+
plot = synopsis,
493537
releaseDate = if (startDate == null) null else try {
494538
Date.from(
495539
Instant.from(
@@ -770,4 +814,4 @@ query {
770814
val canonical: String? = null
771815
)
772816
}
773-
}
817+
}

0 commit comments

Comments
 (0)