mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-16 23:12:12 +00:00
ref: plugin to use saved tmdb api key for tv show resolution
This commit is contained in:
parent
9a0acf7149
commit
023c497fa8
6 changed files with 129 additions and 20 deletions
|
|
@ -7,6 +7,7 @@ import com.nuvio.app.features.addons.buildAddonResourceUrl
|
|||
import com.nuvio.app.features.addons.httpGetText
|
||||
import com.nuvio.app.features.details.MetaDetailsRepository
|
||||
import com.nuvio.app.features.plugins.PluginRepository
|
||||
import com.nuvio.app.features.plugins.pluginContentId
|
||||
import com.nuvio.app.features.plugins.PluginRuntimeResult
|
||||
import com.nuvio.app.features.plugins.PluginScraper
|
||||
import com.nuvio.app.features.streams.AddonStreamGroup
|
||||
|
|
@ -243,7 +244,11 @@ object PlayerStreamsRepository {
|
|||
async {
|
||||
PluginRepository.executeScraper(
|
||||
scraper = scraper,
|
||||
tmdbId = videoId.toPluginTmdbId(),
|
||||
tmdbId = pluginContentId(
|
||||
videoId = videoId,
|
||||
season = season,
|
||||
episode = episode,
|
||||
),
|
||||
mediaType = type,
|
||||
season = season,
|
||||
episode = episode,
|
||||
|
|
@ -339,11 +344,3 @@ private fun PluginRuntimeResult.toStreamItem(scraper: PluginScraper): StreamItem
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun String.toPluginTmdbId(): String {
|
||||
return when {
|
||||
startsWith("tmdb:") -> removePrefix("tmdb:").substringBefore(":").ifBlank { this }
|
||||
startsWith("tmdb/") -> removePrefix("tmdb/").substringBefore('/').ifBlank { this }
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package com.nuvio.app.features.plugins
|
||||
|
||||
internal fun pluginContentId(
|
||||
videoId: String,
|
||||
season: Int?,
|
||||
episode: Int?,
|
||||
): String {
|
||||
val trimmed = videoId.trim()
|
||||
if (trimmed.isBlank()) return videoId
|
||||
|
||||
val withoutPrefix = when {
|
||||
trimmed.startsWith("tmdb:") -> trimmed.removePrefix("tmdb:")
|
||||
trimmed.startsWith("tmdb/") -> trimmed.removePrefix("tmdb/")
|
||||
else -> trimmed
|
||||
}
|
||||
|
||||
val withoutEpisodeSuffix = if (season != null && episode != null) {
|
||||
withoutPrefix.removeSuffix(":$season:$episode")
|
||||
} else {
|
||||
withoutPrefix
|
||||
}
|
||||
|
||||
return withoutEpisodeSuffix.substringBefore('/').ifBlank { trimmed }
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.nuvio.app.features.addons.httpGetText
|
|||
import com.nuvio.app.features.details.MetaDetailsRepository
|
||||
import com.nuvio.app.features.player.PlayerSettingsRepository
|
||||
import com.nuvio.app.features.plugins.PluginRepository
|
||||
import com.nuvio.app.features.plugins.pluginContentId
|
||||
import com.nuvio.app.features.plugins.PluginsUiState
|
||||
import com.nuvio.app.features.plugins.PluginRepositoryItem
|
||||
import com.nuvio.app.features.plugins.PluginRuntimeResult
|
||||
|
|
@ -285,7 +286,11 @@ object StreamsRepository {
|
|||
launch {
|
||||
val completion = PluginRepository.executeScraper(
|
||||
scraper = scraper,
|
||||
tmdbId = videoId.toPluginTmdbId(),
|
||||
tmdbId = pluginContentId(
|
||||
videoId = videoId,
|
||||
season = season,
|
||||
episode = episode,
|
||||
),
|
||||
mediaType = type,
|
||||
season = season,
|
||||
episode = episode,
|
||||
|
|
@ -486,14 +491,6 @@ private fun List<AddonStreamGroup>.toEmptyStateReason(anyLoading: Boolean): Stre
|
|||
}
|
||||
}
|
||||
|
||||
private fun String.toPluginTmdbId(): String {
|
||||
return when {
|
||||
startsWith("tmdb:") -> removePrefix("tmdb:").substringBefore(":").ifBlank { this }
|
||||
startsWith("tmdb/") -> removePrefix("tmdb/").substringBefore('/').ifBlank { this }
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
private fun PluginRuntimeResult.toStreamItem(
|
||||
scraper: PluginScraper,
|
||||
addonName: String = scraper.name,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package com.nuvio.app.features.plugins
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class PluginContentIdsTest {
|
||||
|
||||
@Test
|
||||
fun `series playback id strips season episode suffix`() {
|
||||
assertEquals(
|
||||
"tt2575988",
|
||||
pluginContentId(
|
||||
videoId = "tt2575988:5:8",
|
||||
season = 5,
|
||||
episode = 8,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `tmdb prefixed series playback id strips prefix and suffix`() {
|
||||
assertEquals(
|
||||
"12345",
|
||||
pluginContentId(
|
||||
videoId = "tmdb:12345:2:6",
|
||||
season = 2,
|
||||
episode = 6,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `movie id stays unchanged`() {
|
||||
assertEquals(
|
||||
"tt0133093",
|
||||
pluginContentId(
|
||||
videoId = "tt0133093",
|
||||
season = null,
|
||||
episode = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `slash prefixed tmdb id keeps base content id`() {
|
||||
assertEquals(
|
||||
"999",
|
||||
pluginContentId(
|
||||
videoId = "tmdb/999/1/2",
|
||||
season = 1,
|
||||
episode = 2,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import co.touchlab.kermit.Logger
|
|||
import com.nuvio.app.core.network.SupabaseProvider
|
||||
import com.nuvio.app.features.addons.httpGetText
|
||||
import com.nuvio.app.features.profiles.ProfileRepository
|
||||
import com.nuvio.app.features.tmdb.TmdbService
|
||||
import io.github.jan.supabase.postgrest.postgrest
|
||||
import io.github.jan.supabase.postgrest.query.Order
|
||||
import io.github.jan.supabase.postgrest.rpc
|
||||
|
|
@ -314,10 +315,15 @@ actual object PluginRepository {
|
|||
season: Int?,
|
||||
episode: Int?,
|
||||
): Result<List<PluginRuntimeResult>> {
|
||||
val resolvedTmdbId = resolvePluginTmdbId(
|
||||
tmdbId = tmdbId,
|
||||
mediaType = mediaType,
|
||||
)
|
||||
|
||||
return runCatching {
|
||||
PluginRuntime.executePlugin(
|
||||
code = scraper.code,
|
||||
tmdbId = tmdbId,
|
||||
tmdbId = resolvedTmdbId,
|
||||
mediaType = normalizePluginType(mediaType),
|
||||
season = season,
|
||||
episode = episode,
|
||||
|
|
@ -327,6 +333,19 @@ actual object PluginRepository {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun resolvePluginTmdbId(
|
||||
tmdbId: String,
|
||||
mediaType: String,
|
||||
): String {
|
||||
val trimmed = tmdbId.trim()
|
||||
if (trimmed.isBlank()) return tmdbId
|
||||
|
||||
return TmdbService.ensureTmdbId(
|
||||
videoId = trimmed,
|
||||
mediaType = mediaType,
|
||||
) ?: trimmed
|
||||
}
|
||||
|
||||
private suspend fun fetchRepositoryData(
|
||||
manifestUrl: String,
|
||||
previousScrapers: Map<String, PluginScraper>,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.nuvio.app.core.ui.NuvioInputField
|
|||
import com.nuvio.app.core.ui.NuvioPrimaryButton
|
||||
import com.nuvio.app.core.ui.NuvioSectionLabel
|
||||
import com.nuvio.app.core.ui.NuvioSurfaceCard
|
||||
import com.nuvio.app.features.tmdb.TmdbSettingsRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
|
|
@ -49,6 +50,10 @@ fun PluginsSettingsPageContent(
|
|||
}
|
||||
|
||||
val uiState by PluginRepository.uiState.collectAsStateWithLifecycle()
|
||||
val tmdbSettings by remember {
|
||||
TmdbSettingsRepository.ensureLoaded()
|
||||
TmdbSettingsRepository.uiState
|
||||
}.collectAsStateWithLifecycle()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
var repositoryUrl by rememberSaveable { mutableStateOf("") }
|
||||
|
|
@ -61,6 +66,7 @@ fun PluginsSettingsPageContent(
|
|||
val sortedRepos = remember(uiState.repositories) {
|
||||
uiState.repositories.sortedBy { it.name.lowercase() }
|
||||
}
|
||||
val hasTmdbApiKey = tmdbSettings.hasApiKey
|
||||
val repositoryNameByUrl = remember(sortedRepos) {
|
||||
sortedRepos.associate { it.manifestUrl to it.name }
|
||||
}
|
||||
|
|
@ -88,6 +94,17 @@ fun PluginsSettingsPageContent(
|
|||
NuvioInfoBadge(
|
||||
text = if (uiState.pluginsEnabled) "Plugins enabled" else "Plugins disabled",
|
||||
)
|
||||
NuvioInfoBadge(
|
||||
text = if (hasTmdbApiKey) "TMDB API key set" else "TMDB API key missing",
|
||||
)
|
||||
}
|
||||
if (!hasTmdbApiKey) {
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Text(
|
||||
text = "Plugin providers require a TMDB API key. Set it on the TMDB screen or plugin providers will not work correctly.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Row(
|
||||
|
|
@ -355,7 +372,7 @@ fun PluginsSettingsPageContent(
|
|||
Spacer(modifier = Modifier.height(12.dp))
|
||||
NuvioPrimaryButton(
|
||||
text = if (isTestingThisScraper) "Testing..." else "Test Provider",
|
||||
enabled = !isTestingThisScraper,
|
||||
enabled = hasTmdbApiKey && !isTestingThisScraper,
|
||||
onClick = {
|
||||
testingScraperId = scraper.id
|
||||
coroutineScope.launch {
|
||||
|
|
|
|||
Loading…
Reference in a new issue