Skip to content

Commit

Permalink
更新数据源时尝试使用代理服务
Browse files Browse the repository at this point in the history
  • Loading branch information
Him188 committed Dec 15, 2024
1 parent f2137ae commit 6e4befb
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/shared/app-data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ kotlin {
implementation(projects.utils.intellijAnnotations)
api(projects.app.shared.videoPlayer.videoPlayerApi)
api(projects.app.shared.videoPlayer.torrentSource)
implementation(libs.kotlinx.serialization.json.io)
api(libs.kotlinx.coroutines.core)
api(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.protobuf)
Expand Down Expand Up @@ -75,7 +76,6 @@ kotlin {
}
sourceSets.nativeMain.dependencies {
implementation(libs.stately.common) // fixes koin bug
implementation(libs.kotlinx.serialization.json.io)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2024 OpenAni and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license, which can be found at the following link.
*
* https://github.com/open-ani/ani/blob/main/LICENSE
*/

package me.him188.ani.app.domain.mediasource.subscription

import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.request.parameter
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsChannel
import io.ktor.utils.io.CancellationException
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.serialization.json.io.decodeFromSource
import me.him188.ani.app.data.models.ApiResponse
import me.him188.ani.app.data.models.map
import me.him188.ani.app.data.models.runApiRequest
import me.him188.ani.app.domain.mediasource.codec.MediaSourceCodecManager
import me.him188.ani.app.platform.currentAniBuildConfig
import me.him188.ani.utils.coroutines.withExceptionCollector
import me.him188.ani.utils.ktor.toSource

class MediaSourceSubscriptionRequester(
private val client: Flow<HttpClient>
) {
/**
* 执行网络请求, 下载新订阅数据. 遇到错误时将会返回 [ApiResponse.failure]
*/
suspend fun request(
subscription: MediaSourceSubscription,
): ApiResponse<SubscriptionUpdateData> {
val clientInstance = client.first()

suspend fun HttpResponse.decode() = bodyAsChannel().toSource().use {
MediaSourceCodecManager.Companion.json.decodeFromSource(
SubscriptionUpdateData.serializer(),
it,
)
}

withExceptionCollector {
// 首先直连
try {
return ApiResponse.success(clientInstance.get(subscription.url).decode())
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
collect(e) // continue
}

// 失败则尝试代理服务
return runApiRequest {
clientInstance.get(currentAniBuildConfig.aniAuthServerUrl + "/v1/subs/proxy") {
parameter("url", subscription.url)
}
}.map {
it.decode()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class MediaSourceSubscriptionUpdater(
private val subscriptions: MediaSourceSubscriptionRepository,
private val mediaSourceManager: MediaSourceManager,
private val codecManager: MediaSourceCodecManager,
private val requestSubscription: suspend (MediaSourceSubscription) -> ApiResponse<SubscriptionUpdateData>,
private val requester: MediaSourceSubscriptionRequester,
) {
/**
* @param force to ignore lastUpdated time
Expand Down Expand Up @@ -107,7 +107,7 @@ class MediaSourceSubscriptionUpdater(

@Throws(UpdateSubscriptionException::class, CancellationException::class)
private suspend fun updateSubscription(subscription: MediaSourceSubscription): Int {
val updateData = requestSubscription(subscription).valueOrElse {
val updateData = requester.request(subscription).valueOrElse {
throw RequestFailureException(it)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
package me.him188.ani.app.platform

import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -25,9 +23,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import me.him188.ani.app.data.models.map
import me.him188.ani.app.data.models.preference.configIfEnabledOrNull
import me.him188.ani.app.data.models.runApiRequest
import me.him188.ani.app.data.network.AnimeScheduleService
import me.him188.ani.app.data.network.BangumiBangumiCommentServiceImpl
import me.him188.ani.app.data.network.BangumiCommentService
Expand Down Expand Up @@ -86,8 +82,8 @@ import me.him188.ani.app.domain.media.fetch.MediaSourceManager
import me.him188.ani.app.domain.media.fetch.MediaSourceManagerImpl
import me.him188.ani.app.domain.media.fetch.toClientProxyConfig
import me.him188.ani.app.domain.mediasource.codec.MediaSourceCodecManager
import me.him188.ani.app.domain.mediasource.subscription.MediaSourceSubscriptionRequester
import me.him188.ani.app.domain.mediasource.subscription.MediaSourceSubscriptionUpdater
import me.him188.ani.app.domain.mediasource.subscription.SubscriptionUpdateData
import me.him188.ani.app.domain.session.AniAuthClient
import me.him188.ani.app.domain.session.BangumiSessionManager
import me.him188.ani.app.domain.session.OpaqueSession
Expand Down Expand Up @@ -323,6 +319,7 @@ fun KoinApplication.getCommonKoinModule(getContext: () -> Context, coroutineScop
createDefaultHttpClient {
userAgent(getAniUserAgent())
proxy(proxySettings.configIfEnabledOrNull?.toClientProxyConfig())
expectSuccess = true
}.apply {
registerLogging(logger<MediaSourceSubscriptionUpdater>())
}
Expand All @@ -333,14 +330,7 @@ fun KoinApplication.getCommonKoinModule(getContext: () -> Context, coroutineScop
get<MediaSourceSubscriptionRepository>(),
get<MediaSourceManager>(),
get<MediaSourceCodecManager>(),
requestSubscription = {
client.first().runApiRequest { get(it.url) }.map { response ->
MediaSourceCodecManager.Companion.json.decodeFromString(
SubscriptionUpdateData.serializer(),
response.bodyAsText(),
)
}
},
requester = MediaSourceSubscriptionRequester(client),
)
}

Expand Down

0 comments on commit 6e4befb

Please sign in to comment.