mirror of
https://github.com/FluxaMedia/fluxa.git
synced 2026-07-29 13:12:47 +00:00
Consolidate raw OkHttp request/response glue into a shared HttpEffectExecutor
StremioAddonManifestClient, StremioAddonResourceClient, and the trailer effect in FluxaAndroidHeadlessEnvironment each hand-rolled the same Request.Builder -> execute -> read status/body -> catch pattern. One shared executor now backs all three call sites.
This commit is contained in:
parent
f0cf10d757
commit
fc005ba1df
4 changed files with 53 additions and 35 deletions
|
|
@ -36,6 +36,7 @@ import com.fluxa.app.player.MediaPlayerController
|
|||
import com.fluxa.app.player.TorrentStreamManager
|
||||
import com.fluxa.app.player.TorrentStreamResult
|
||||
import com.fluxa.app.data.repository.CloudStreamCatalogClient
|
||||
import com.fluxa.app.data.repository.HttpEffectExecutor
|
||||
import com.fluxa.app.data.repository.toStremioType
|
||||
import com.fluxa.app.plugins.PluginManager
|
||||
import com.fluxa.app.plugins.cloudstream.ExternalExtensionRunner
|
||||
|
|
@ -111,7 +112,8 @@ class FluxaAndroidHeadlessEnvironment @Inject constructor(
|
|||
internal val gson: Gson,
|
||||
internal val profileManager: ProfileManager,
|
||||
internal val externalSyncPushCoordinator: ExternalSyncPushCoordinator,
|
||||
internal val nuvioAccountImportCoordinator: NuvioAccountImportCoordinator
|
||||
internal val nuvioAccountImportCoordinator: NuvioAccountImportCoordinator,
|
||||
internal val httpEffectExecutor: HttpEffectExecutor
|
||||
) : HeadlessPlatformEnvironment {
|
||||
|
||||
internal val primeScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||
|
|
@ -1117,19 +1119,17 @@ class FluxaAndroidHeadlessEnvironment @Inject constructor(
|
|||
|
||||
private fun executeTrailerHttpEffect(effect: NativeHeadlessEffect): HeadlessEffectCompletion {
|
||||
val payload = effect.payload
|
||||
val requestBuilder = okhttp3.Request.Builder().url(payload.string("url"))
|
||||
payload.objectValue("headers")?.forEach { (key, value) ->
|
||||
requestBuilder.header(key, value.toString())
|
||||
}
|
||||
val headers = payload.objectValue("headers")?.mapValues { it.value.toString() }.orEmpty()
|
||||
val method = payload.string("method", "GET")
|
||||
val body = payload["body"]?.let {
|
||||
gson.toJson(it).toRequestBody("application/json".toMediaType())
|
||||
}
|
||||
requestBuilder.method(method, body)
|
||||
trailerHttpClient.newCall(requestBuilder.build()).execute().use { response ->
|
||||
if (!response.isSuccessful) return error(effect, "http_${response.code}")
|
||||
return ok(effect, mapOf("body" to response.body.string()))
|
||||
val result = httpEffectExecutor.execute(trailerHttpClient, payload.string("url"), method, headers, body)
|
||||
val statusCode = result.statusCode
|
||||
if (result.error != null || statusCode == null || statusCode !in 200..299) {
|
||||
return error(effect, "http_${statusCode ?: 0}")
|
||||
}
|
||||
return ok(effect, mapOf("body" to result.body))
|
||||
}
|
||||
|
||||
internal fun ok(effect: NativeHeadlessEffect, value: Any?): HeadlessEffectCompletion =
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.fluxa.app.data.repository
|
||||
|
||||
import android.util.Log
|
||||
import com.fluxa.app.core.rust.models.NativeAddonFetchResult
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class HttpEffectExecutor @Inject constructor() {
|
||||
|
||||
fun execute(
|
||||
client: OkHttpClient,
|
||||
url: String,
|
||||
method: String = "GET",
|
||||
headers: Map<String, String> = emptyMap(),
|
||||
body: RequestBody? = null
|
||||
): NativeAddonFetchResult {
|
||||
return try {
|
||||
val requestBuilder = Request.Builder().url(url)
|
||||
headers.forEach { (key, value) -> requestBuilder.header(key, value) }
|
||||
requestBuilder.method(method, body)
|
||||
client.newCall(requestBuilder.build()).execute().use { response ->
|
||||
NativeAddonFetchResult(url = url, statusCode = response.code, body = response.body.string())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w("HttpEffectExecutor", "HTTP request failed: $url", e)
|
||||
NativeAddonFetchResult(url = url, error = e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import com.fluxa.app.common.AppStrings
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import java.net.URLEncoder
|
||||
|
||||
import javax.inject.Inject
|
||||
|
|
@ -16,6 +15,7 @@ import javax.inject.Named
|
|||
class StremioAddonManifestClient @Inject constructor(
|
||||
internal val cache: RepositoryMemoryCache,
|
||||
internal val persistentCache: AddonPersistentCache,
|
||||
internal val httpEffectExecutor: HttpEffectExecutor,
|
||||
@param:Named("StremioClient") private val manifestClient: OkHttpClient
|
||||
) {
|
||||
private val unknownName: (String?) -> String = { AppStrings.t(it, "auto.unknown") }
|
||||
|
|
@ -80,18 +80,13 @@ class StremioAddonManifestClient @Inject constructor(
|
|||
}
|
||||
}
|
||||
fetchPlan.candidateUrls.forEach { candidateUrl ->
|
||||
try {
|
||||
val httpRequest = Request.Builder().url(candidateUrl).build()
|
||||
val httpResponse = manifestClient.newCall(httpRequest).execute()
|
||||
val statusCode = httpResponse.code
|
||||
val body = httpResponse.body.string().also { httpResponse.close() }
|
||||
if (statusCode !in 200..299) return@forEach
|
||||
val descriptor = parseAddonManifest(body, candidateUrl) ?: return@forEach
|
||||
putCache(cacheKey, descriptor)
|
||||
persistentCache.putManifest(cacheKey, descriptor)
|
||||
return@withContext descriptor
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
val result = httpEffectExecutor.execute(manifestClient, candidateUrl)
|
||||
val body = result.body
|
||||
if (result.error != null || (result.statusCode ?: 0) !in 200..299 || body == null) return@forEach
|
||||
val descriptor = parseAddonManifest(body, candidateUrl) ?: return@forEach
|
||||
putCache(cacheKey, descriptor)
|
||||
persistentCache.putManifest(cacheKey, descriptor)
|
||||
return@withContext descriptor
|
||||
}
|
||||
if (decision.allowStaleFallback) persistentCache.getManifest(cacheKey)?.let {
|
||||
putCache(cacheKey, it)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.util.Log
|
|||
import com.fluxa.app.core.rust.FluxaCoreNative
|
||||
import com.fluxa.app.core.rust.models.NativeAddonFetchResult
|
||||
import com.fluxa.app.core.rust.models.NativeAddonResourceParseResult
|
||||
import okhttp3.Request
|
||||
import com.fluxa.app.data.remote.AddonDescriptor
|
||||
import com.fluxa.app.data.remote.AuthRequest
|
||||
import com.fluxa.app.data.remote.Meta
|
||||
|
|
@ -45,6 +44,7 @@ class StremioAddonResourceClient @Inject constructor(
|
|||
private val cache: RepositoryMemoryCache,
|
||||
private val persistentCache: AddonPersistentCache,
|
||||
private val addonManifestClient: StremioAddonManifestClient,
|
||||
private val httpEffectExecutor: HttpEffectExecutor,
|
||||
@param:Named("AddonResourceClient") private val httpClient: OkHttpClient
|
||||
) {
|
||||
private val stremioGson = GsonBuilder().create()
|
||||
|
|
@ -369,18 +369,8 @@ class StremioAddonResourceClient @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun fetchAddonBodyResult(url: String): NativeAddonFetchResult {
|
||||
return try {
|
||||
val httpRequest = Request.Builder().url(url).build()
|
||||
val httpResponse = httpClient.newCall(httpRequest).execute()
|
||||
val status = httpResponse.code
|
||||
val body = httpResponse.body.string().also { httpResponse.close() }
|
||||
NativeAddonFetchResult(url = url, statusCode = status, body = body)
|
||||
} catch (e: Exception) {
|
||||
Log.w("StremioAddonResourceClient", "Addon resource HTTP failed: $url", e)
|
||||
NativeAddonFetchResult(url = url, error = e.message)
|
||||
}
|
||||
}
|
||||
private fun fetchAddonBodyResult(url: String): NativeAddonFetchResult =
|
||||
httpEffectExecutor.execute(httpClient, url)
|
||||
|
||||
private fun fetchAddonResourcePayload(
|
||||
transportUrl: String,
|
||||
|
|
|
|||
Loading…
Reference in a new issue