2026-05-30 19:47:58 +02:00
|
|
|
package at.lockstep.player.data
|
|
|
|
|
|
2026-05-31 11:41:06 +02:00
|
|
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
2026-05-30 19:47:58 +02:00
|
|
|
import okhttp3.MediaType.Companion.toMediaType
|
|
|
|
|
import okhttp3.OkHttpClient
|
|
|
|
|
import okhttp3.Request
|
|
|
|
|
import okhttp3.RequestBody.Companion.toRequestBody
|
|
|
|
|
import org.json.JSONObject
|
|
|
|
|
import java.io.IOException
|
|
|
|
|
|
2026-05-31 11:41:06 +02:00
|
|
|
sealed class MetadataFetchResult {
|
|
|
|
|
data class Found(val collection: JSONObject) : MetadataFetchResult()
|
|
|
|
|
|
|
|
|
|
data object NotFound : MetadataFetchResult()
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-30 19:47:58 +02:00
|
|
|
class MetadataSyncClient(
|
|
|
|
|
private val httpClient: OkHttpClient,
|
|
|
|
|
private val baseUrl: String,
|
|
|
|
|
) {
|
2026-05-31 11:41:06 +02:00
|
|
|
@Throws(IOException::class)
|
|
|
|
|
fun fetchMetadata(
|
|
|
|
|
accessToken: String,
|
|
|
|
|
trackId: String,
|
|
|
|
|
type: String,
|
|
|
|
|
): MetadataFetchResult {
|
|
|
|
|
val url =
|
|
|
|
|
baseUrl.toHttpUrl()
|
|
|
|
|
.newBuilder()
|
|
|
|
|
.addPathSegments("metadata")
|
|
|
|
|
.addQueryParameter("trackId", trackId)
|
|
|
|
|
.addQueryParameter("type", type)
|
|
|
|
|
.build()
|
|
|
|
|
val request =
|
|
|
|
|
Request.Builder()
|
|
|
|
|
.url(url)
|
|
|
|
|
.addHeader("Authorization", "Bearer $accessToken")
|
|
|
|
|
.get()
|
|
|
|
|
.build()
|
|
|
|
|
httpClient.newCall(request).execute().use { response ->
|
|
|
|
|
if (response.code == 404) {
|
|
|
|
|
return MetadataFetchResult.NotFound
|
|
|
|
|
}
|
|
|
|
|
val bodyText = response.body?.string().orEmpty()
|
|
|
|
|
if (!response.isSuccessful) {
|
|
|
|
|
val message =
|
|
|
|
|
runCatching { JSONObject(bodyText).optString("error") }
|
|
|
|
|
.getOrNull()
|
|
|
|
|
?.takeIf { it.isNotBlank() }
|
|
|
|
|
?: response.message
|
|
|
|
|
throw IOException(message)
|
|
|
|
|
}
|
|
|
|
|
val collection =
|
|
|
|
|
runCatching { JSONObject(bodyText).getJSONObject("collection") }
|
|
|
|
|
.getOrNull()
|
|
|
|
|
?: throw IOException("Missing collection in response")
|
|
|
|
|
return MetadataFetchResult.Found(collection)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-30 19:47:58 +02:00
|
|
|
@Throws(IOException::class)
|
|
|
|
|
fun uploadCollection(
|
|
|
|
|
accessToken: String,
|
|
|
|
|
trackId: String,
|
|
|
|
|
type: String,
|
|
|
|
|
version: Int,
|
|
|
|
|
collection: JSONObject,
|
|
|
|
|
) {
|
|
|
|
|
val payload =
|
|
|
|
|
JSONObject()
|
|
|
|
|
.apply {
|
|
|
|
|
put("trackId", trackId)
|
|
|
|
|
put("type", type)
|
|
|
|
|
put("version", version)
|
|
|
|
|
put("collection", collection)
|
|
|
|
|
}.toString()
|
|
|
|
|
val request =
|
|
|
|
|
Request.Builder()
|
|
|
|
|
.url("$baseUrl/metadata")
|
|
|
|
|
.addHeader("Authorization", "Bearer $accessToken")
|
|
|
|
|
.post(payload.toRequestBody(JSON_MEDIA))
|
|
|
|
|
.build()
|
|
|
|
|
httpClient.newCall(request).execute().use { response ->
|
|
|
|
|
if (response.isSuccessful) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
val bodyText = response.body?.string().orEmpty()
|
|
|
|
|
val message =
|
|
|
|
|
runCatching { JSONObject(bodyText).optString("error") }
|
|
|
|
|
.getOrNull()
|
|
|
|
|
?.takeIf { it.isNotBlank() }
|
|
|
|
|
?: response.message
|
|
|
|
|
throw IOException(message)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
private val JSON_MEDIA = "application/json; charset=utf-8".toMediaType()
|
|
|
|
|
}
|
|
|
|
|
}
|