Consumyroll: fix broken token caching (#1301)

This commit is contained in:
Samfun75
2023-02-20 07:01:46 -08:00
committed by GitHub
parent 5c26b17f60
commit 800f8abf8e
3 changed files with 31 additions and 41 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'Consumyroll' extName = 'Consumyroll'
pkgNameSuffix = 'all.kamyroll' pkgNameSuffix = 'all.kamyroll'
extClass = '.Consumyroll' extClass = '.Consumyroll'
extVersionCode = 14 extVersionCode = 15
libVersion = '13' libVersion = '13'
} }

View File

@ -12,23 +12,17 @@ import okhttp3.Response
import java.net.HttpURLConnection import java.net.HttpURLConnection
class AccessTokenInterceptor( class AccessTokenInterceptor(
private val baseUrl: String,
private val json: Json, private val json: Json,
private val preferences: SharedPreferences private val preferences: SharedPreferences
) : Interceptor { ) : Interceptor {
private var accessToken = preferences.getString("access_token", null).let { private var accessToken = preferences.getString(TOKEN_PREF_KEY, null) ?: ""
if (it.isNullOrBlank()) {
null
} else {
json.decodeFromString<AccessToken>(it)
}
}
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
if (accessToken == null) accessToken = refreshAccessToken() if (accessToken.isBlank()) accessToken = refreshAccessToken()
val request = chain.request().newBuilder() val parsed = json.decodeFromString<AccessToken>(accessToken)
.header("authorization", "${accessToken!!.token_type} ${accessToken!!.access_token}") val request = newRequestWithAccessToken(chain.request(), "${parsed.token_type} ${parsed.access_token}")
.build()
val response = chain.proceed(request) val response = chain.proceed(request)
@ -36,21 +30,12 @@ class AccessTokenInterceptor(
HttpURLConnection.HTTP_UNAUTHORIZED -> { HttpURLConnection.HTTP_UNAUTHORIZED -> {
synchronized(this) { synchronized(this) {
response.close() response.close()
val newAccessToken = refreshAccessToken()
// Access token is refreshed in another thread. // Access token is refreshed in another thread.
if (accessToken != newAccessToken) { accessToken = refreshAccessToken()
accessToken = newAccessToken val newParsed = json.decodeFromString<AccessToken>(accessToken)
return chain.proceed(
newRequestWithAccessToken(chain.request(), "${accessToken!!.token_type} ${accessToken!!.access_token}")
)
}
// Need to refresh an access token
val updatedAccessToken = refreshAccessToken()
accessToken = updatedAccessToken
// Retry the request // Retry the request
return chain.proceed( return chain.proceed(
newRequestWithAccessToken(chain.request(), "${accessToken!!.token_type} ${accessToken!!.access_token}") newRequestWithAccessToken(chain.request(), "${newParsed.token_type} ${newParsed.access_token}")
) )
} }
} }
@ -64,15 +49,19 @@ class AccessTokenInterceptor(
.build() .build()
} }
private fun refreshAccessToken(): AccessToken { fun refreshAccessToken(): String {
val client = OkHttpClient().newBuilder().build() val client = OkHttpClient().newBuilder().build()
val response = client.newCall(GET("https://cronchy.consumet.stream/token")).execute() val response = client.newCall(GET("$baseUrl/token")).execute()
val parsedJson = json.decodeFromString<AccessToken>(response.body!!.string()) val parsedJson = json.decodeFromString<AccessToken>(response.body!!.string()).toJsonString()
preferences.edit().putString("access_token", parsedJson.toJsonString()).apply() preferences.edit().putString(TOKEN_PREF_KEY, parsedJson).apply()
return parsedJson return parsedJson
} }
private fun AccessToken.toJsonString(): String { private fun AccessToken.toJsonString(): String {
return json.encodeToString(this) return json.encodeToString(this)
} }
companion object {
val TOKEN_PREF_KEY = "access_token_data"
}
} }

View File

@ -54,8 +54,10 @@ class Consumyroll : ConfigurableAnimeSource, AnimeHttpSource() {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
private val TokenInterceptor = AccessTokenInterceptor(baseUrl, json, preferences)
override val client: OkHttpClient = OkHttpClient().newBuilder() override val client: OkHttpClient = OkHttpClient().newBuilder()
.addInterceptor(AccessTokenInterceptor(json, preferences)).build() .addInterceptor(TokenInterceptor).build()
companion object { companion object {
private val DateFormatter by lazy { private val DateFormatter by lazy {
@ -163,18 +165,17 @@ class Consumyroll : ConfigurableAnimeSource, AnimeHttpSource() {
override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> { override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> {
val urlJson = json.decodeFromString<EpisodeData>(episode.url) val urlJson = json.decodeFromString<EpisodeData>(episode.url)
val policyJson = preferences.getString("access_token", null)!!.let { val dubLocale = preferences.getString("preferred_audio", "en-US")!!
json.decodeFromString<AccessToken>(it) val tokenJson = preferences.getString(AccessTokenInterceptor.TOKEN_PREF_KEY, null)
} ?: TokenInterceptor.refreshAccessToken()
val videoList = urlJson.ids.chunked(5).map { val policyJson = json.decodeFromString<AccessToken>(tokenJson)
it.parallelMap { media -> val videoList = urlJson.ids.filter {
runCatching { it.second == dubLocale || it.second == "ja-JP" || it.second == "en-US"
extractVideo(media, policyJson) }.parallelMap { media ->
}.getOrNull() runCatching {
} extractVideo(media, policyJson)
.filterNotNull() }.getOrNull()
.flatten() }.filterNotNull().flatten()
}.flatten()
return Observable.just(videoList.sort()) return Observable.just(videoList.sort())
} }