library: bound the artist bio request

This commit is contained in:
austinried
2026-10-19 13:14:08 +00:00
parent d4ba9c0faf
commit b379a22517
3 changed files with 11 additions and 9 deletions
@@ -8,6 +8,7 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.InputStream
import java.security.MessageDigest
import java.util.concurrent.TimeUnit
open class SubsonicException(
val code: Int,
@@ -55,11 +56,12 @@ class SubsonicClient(
fun <T> stream(
method: String,
params: Map<String, String> = emptyMap(),
timeoutMs: Long? = null,
body: (InputStream) -> T,
): T {
val usedTokenAuth = useTokenAuth
return try {
execute(method, params, body)
execute(method, params, timeoutMs, body)
} catch (failure: SubsonicException) {
if (failure.code !in TOKEN_AUTH_UNSUPPORTED_CODES || !usedTokenAuth) {
Log.w("http", "$method failed: server code ${failure.code} \"${failure.message}\"")
@@ -67,13 +69,14 @@ class SubsonicClient(
}
Log.w("http", "$method: token auth unsupported (server code ${failure.code}), retrying with plaintext")
disableTokenAuth()
execute(method, params, body)
execute(method, params, timeoutMs, body)
}
}
private fun <T> execute(
method: String,
params: Map<String, String>,
timeoutMs: Long?,
body: (InputStream) -> T,
): T {
val request =
@@ -81,7 +84,9 @@ class SubsonicClient(
.Builder()
.url(uri(method, params))
.build()
http.newCall(request).execute().use { response ->
val call = http.newCall(request)
timeoutMs?.let { call.timeout().timeout(it, TimeUnit.MILLISECONDS) }
call.execute().use { response ->
if (!response.isSuccessful) {
throw SubsonicException(-1, "HTTP ${response.code}", UiMessage(R.string.error_http, listOf(response.code)))
}
@@ -87,7 +87,7 @@ class SubsonicSource(
override suspend fun artistBiography(artistId: String): String? =
withContext(Dispatchers.IO) {
client.stream("getArtistInfo2", mapOf("id" to artistId)) { input ->
client.stream("getArtistInfo2", mapOf("id" to artistId), timeoutMs = ARTIST_BIO_TIMEOUT_MS) { input ->
SubsonicXml.artistBiography(input)
}
}
@@ -372,6 +372,7 @@ class SubsonicSource(
const val PAGE_SIZE = 500
const val MAX_PAGES = 20_000
const val THUMBNAIL_SIZE = 384
const val ARTIST_BIO_TIMEOUT_MS = 15_000L
}
}
@@ -29,9 +29,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
private const val BIO_REFRESH_TIMEOUT_MS = 15_000L
@OptIn(ExperimentalCoroutinesApi::class)
class ArtistDetailViewModel(
@@ -102,8 +99,7 @@ class ArtistDetailViewModel(
}
_bioLoading.value = true
try {
val result = withTimeoutOrNull(BIO_REFRESH_TIMEOUT_MS) { libraryRepository.refreshArtistBio(id, artistId) }
_bioUnavailable.value = result == null || result.isFailure
_bioUnavailable.value = libraryRepository.refreshArtistBio(id, artistId).isFailure
} finally {
_bioLoading.value = false
}