From a390aef131508848c75edcf21b93ba48f2aa4a09 Mon Sep 17 00:00:00 2001 From: CXwudi Date: Wed, 3 Jan 2024 18:15:25 -0500 Subject: [PATCH] :sparkles: a working SoundCloudThumbnailFinder --- .../SoundCloudThumbnailFinder.kt | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 songfinder-app/src/main/kotlin/mikufan/cx/songfinder/backend/component/thumbnailfinder/SoundCloudThumbnailFinder.kt diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/backend/component/thumbnailfinder/SoundCloudThumbnailFinder.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/backend/component/thumbnailfinder/SoundCloudThumbnailFinder.kt new file mode 100644 index 0000000..8e89f61 --- /dev/null +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/backend/component/thumbnailfinder/SoundCloudThumbnailFinder.kt @@ -0,0 +1,59 @@ +package mikufan.cx.songfinder.backend.component.thumbnailfinder + +import com.fasterxml.jackson.databind.JsonNode +import io.ktor.client.* +import io.ktor.client.call.* +import io.ktor.client.request.* +import io.ktor.http.* +import kotlinx.coroutines.withContext +import mikufan.cx.songfinder.backend.db.entity.PvService +import mikufan.cx.songfinder.backend.model.PVInfo +import mikufan.cx.songfinder.backend.model.ThumbnailInfo +import mikufan.cx.songfinder.backend.util.MyDispatchers +import org.springframework.stereotype.Component + +@Component +class SoundCloudThumbnailFinder( + private val client: HttpClient, +) : ThumbnailFinder { + override val matchedPvService = PvService.SoundCloud + + companion object { + // https://stackoverflow.com/questions/65352609/how-can-i-get-a-client-id + private val CLIENT_IDS = listOf( + "a3e059563d7fd3372b49b37f00a00bcf", + "RMDyLXBETEYF6qcE4jmndm0VF1QZt2T4" + ) + private val RANDOM_CLIENT_ID: String + get() = CLIENT_IDS.random() + } + + override suspend fun findThumbnail(pv: PVInfo): ThumbnailInfo { + val id = pv.id.split(" ").first() + val rsp = withContext(MyDispatchers.ioDispatcher) { + client.get("https://api-v2.soundcloud.com/tracks/") { + url { + appendEncodedPathSegments(id) + parameters["client_id"] = RANDOM_CLIENT_ID + } + } + } + val status = rsp.status.value + when (status) { + in (200..<300) -> { + val json = rsp.body() + val thumbnailUrlJson = json["artwork_url"] + if (thumbnailUrlJson.isNull) { + throw ThumbnailNotAvailableException("The $matchedPvService video $id does not have an artwork") + } else { + val thumbnailUrl = thumbnailUrlJson.asText() + return ThumbnailInfo(thumbnailUrl) + } + } + + else -> { + throw ThumbnailNotAvailableException("The $matchedPvService video $id is not available, status code: $status") + } + } + } +} \ No newline at end of file