mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 15:29:15 +01:00
library: bound the artist bio request
This commit is contained in:
@@ -8,6 +8,7 @@ import okhttp3.OkHttpClient
|
|||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
open class SubsonicException(
|
open class SubsonicException(
|
||||||
val code: Int,
|
val code: Int,
|
||||||
@@ -55,11 +56,12 @@ class SubsonicClient(
|
|||||||
fun <T> stream(
|
fun <T> stream(
|
||||||
method: String,
|
method: String,
|
||||||
params: Map<String, String> = emptyMap(),
|
params: Map<String, String> = emptyMap(),
|
||||||
|
timeoutMs: Long? = null,
|
||||||
body: (InputStream) -> T,
|
body: (InputStream) -> T,
|
||||||
): T {
|
): T {
|
||||||
val usedTokenAuth = useTokenAuth
|
val usedTokenAuth = useTokenAuth
|
||||||
return try {
|
return try {
|
||||||
execute(method, params, body)
|
execute(method, params, timeoutMs, body)
|
||||||
} catch (failure: SubsonicException) {
|
} catch (failure: SubsonicException) {
|
||||||
if (failure.code !in TOKEN_AUTH_UNSUPPORTED_CODES || !usedTokenAuth) {
|
if (failure.code !in TOKEN_AUTH_UNSUPPORTED_CODES || !usedTokenAuth) {
|
||||||
Log.w("http", "$method failed: server code ${failure.code} \"${failure.message}\"")
|
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")
|
Log.w("http", "$method: token auth unsupported (server code ${failure.code}), retrying with plaintext")
|
||||||
disableTokenAuth()
|
disableTokenAuth()
|
||||||
execute(method, params, body)
|
execute(method, params, timeoutMs, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T> execute(
|
private fun <T> execute(
|
||||||
method: String,
|
method: String,
|
||||||
params: Map<String, String>,
|
params: Map<String, String>,
|
||||||
|
timeoutMs: Long?,
|
||||||
body: (InputStream) -> T,
|
body: (InputStream) -> T,
|
||||||
): T {
|
): T {
|
||||||
val request =
|
val request =
|
||||||
@@ -81,7 +84,9 @@ class SubsonicClient(
|
|||||||
.Builder()
|
.Builder()
|
||||||
.url(uri(method, params))
|
.url(uri(method, params))
|
||||||
.build()
|
.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) {
|
if (!response.isSuccessful) {
|
||||||
throw SubsonicException(-1, "HTTP ${response.code}", UiMessage(R.string.error_http, listOf(response.code)))
|
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? =
|
override suspend fun artistBiography(artistId: String): String? =
|
||||||
withContext(Dispatchers.IO) {
|
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)
|
SubsonicXml.artistBiography(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,6 +372,7 @@ class SubsonicSource(
|
|||||||
const val PAGE_SIZE = 500
|
const val PAGE_SIZE = 500
|
||||||
const val MAX_PAGES = 20_000
|
const val MAX_PAGES = 20_000
|
||||||
const val THUMBNAIL_SIZE = 384
|
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.onStart
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
|
||||||
|
|
||||||
private const val BIO_REFRESH_TIMEOUT_MS = 15_000L
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
class ArtistDetailViewModel(
|
class ArtistDetailViewModel(
|
||||||
@@ -102,8 +99,7 @@ class ArtistDetailViewModel(
|
|||||||
}
|
}
|
||||||
_bioLoading.value = true
|
_bioLoading.value = true
|
||||||
try {
|
try {
|
||||||
val result = withTimeoutOrNull(BIO_REFRESH_TIMEOUT_MS) { libraryRepository.refreshArtistBio(id, artistId) }
|
_bioUnavailable.value = libraryRepository.refreshArtistBio(id, artistId).isFailure
|
||||||
_bioUnavailable.value = result == null || result.isFailure
|
|
||||||
} finally {
|
} finally {
|
||||||
_bioLoading.value = false
|
_bioLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user