Renamed track to song to prevent adblocker from blocking the endpoints
This commit is contained in:
parent
c0c7a56f96
commit
a73ba4cd77
|
@ -28,6 +28,7 @@ dependencies {
|
|||
implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-call-logging-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-cors:$ktor_version")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-core:$ktor_version")
|
||||
|
@ -40,6 +41,7 @@ dependencies {
|
|||
implementation("io.insert-koin:koin-ktor:$koin_version")
|
||||
implementation("io.insert-koin:koin-logger-slf4j:$koin_version")
|
||||
implementation("ch.qos.logback:logback-classic:$logback_version")
|
||||
implementation("io.ktor:ktor-server-cors-jvm:2.1.3")
|
||||
|
||||
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
|
||||
|
|
|
@ -2,13 +2,13 @@ package dev.fyloz.musicplayer.core
|
|||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import dev.fyloz.musicplayer.core.data.RepositoryInjection
|
||||
import dev.fyloz.musicplayer.core.factory.TrackFactoryProxy
|
||||
import dev.fyloz.musicplayer.core.factory.SongFactoryProxy
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.http.configureTrackRoutes
|
||||
import dev.fyloz.musicplayer.core.logic.TrackLogic
|
||||
import dev.fyloz.musicplayer.core.http.configureSongRoutes
|
||||
import dev.fyloz.musicplayer.core.logic.SongLogic
|
||||
import dev.fyloz.musicplayer.modules.Module
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.plugins.logging.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.config.*
|
||||
|
@ -16,6 +16,7 @@ import io.ktor.server.engine.*
|
|||
import io.ktor.server.netty.*
|
||||
import io.ktor.server.plugins.callloging.*
|
||||
import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.plugins.cors.routing.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.koin.dsl.module
|
||||
|
@ -50,8 +51,8 @@ fun Application.module() {
|
|||
RepositoryInjection.koinBeans,
|
||||
|
||||
module {
|
||||
single { TrackFactoryProxy() }
|
||||
single { TrackLogic() }
|
||||
single { SongFactoryProxy() }
|
||||
single { SongLogic() }
|
||||
single {
|
||||
HttpClient {
|
||||
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
|
||||
|
@ -60,10 +61,10 @@ fun Application.module() {
|
|||
})
|
||||
}
|
||||
|
||||
install(Logging) {
|
||||
level = LogLevel.ALL
|
||||
// filter { call -> call.request.path().startsWith("/") }
|
||||
}
|
||||
// install(Logging) {
|
||||
// level = LogLevel.ALL
|
||||
//// filter { call -> call.request.path().startsWith("/") }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,9 +80,19 @@ fun Application.module() {
|
|||
registeredModules.values.forEach { it.configureRoutes(this) }
|
||||
|
||||
route("/api/v1") {
|
||||
configureTrackRoutes()
|
||||
configureSongRoutes()
|
||||
}
|
||||
}
|
||||
|
||||
install(CORS) {
|
||||
allowMethod(HttpMethod.Options)
|
||||
allowMethod(HttpMethod.Put)
|
||||
allowMethod(HttpMethod.Delete)
|
||||
allowMethod(HttpMethod.Patch)
|
||||
allowHeader(HttpHeaders.Authorization)
|
||||
allowHeader("MyCustomHeader")
|
||||
anyHost() // @TODO: Don't do this in production if possible. Try to limit it.
|
||||
}
|
||||
}
|
||||
|
||||
private val registeredModules = mutableMapOf<String, Module>()
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package dev.fyloz.musicplayer.core.data
|
||||
|
||||
import dev.fyloz.musicplayer.core.data.memory.TrackMemoryRepository
|
||||
import dev.fyloz.musicplayer.core.data.memory.SongMemoryRepository
|
||||
import org.koin.dsl.module
|
||||
|
||||
object RepositoryInjection {
|
||||
val koinBeans = module {
|
||||
single<TrackRepository> { TrackMemoryRepository() }
|
||||
single<SongRepository> { SongMemoryRepository() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package dev.fyloz.musicplayer.core.data
|
||||
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
|
||||
interface SongRepository : Repository<Song>
|
|
@ -1,5 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.data
|
||||
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
|
||||
interface TrackRepository : Repository<Track>
|
|
@ -0,0 +1,8 @@
|
|||
package dev.fyloz.musicplayer.core.data.memory
|
||||
|
||||
import dev.fyloz.musicplayer.core.data.SongRepository
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
|
||||
class SongMemoryRepository : BaseMemoryRepository<Song>(), SongRepository {
|
||||
override fun getId(t: Song) = t.id
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.data.memory
|
||||
|
||||
import dev.fyloz.musicplayer.core.data.TrackRepository
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
|
||||
class TrackMemoryRepository : BaseMemoryRepository<Track>(), TrackRepository {
|
||||
override fun getId(t: Track) = t.id
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package dev.fyloz.musicplayer.core.factory
|
||||
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.SearchResultItem
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
|
||||
interface SongFactory {
|
||||
suspend fun search(query: String, auth: AuthorizationData): Collection<SearchResultItem>
|
||||
suspend fun create(id: String, songId: String, auth: AuthorizationData): Song
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package dev.fyloz.musicplayer.core.factory
|
||||
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.SearchResult
|
||||
import dev.fyloz.musicplayer.core.model.SearchResultItem
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
|
||||
typealias STR = String
|
||||
|
||||
class SongFactoryProxy {
|
||||
private val factories = mutableMapOf<String, SongFactory>()
|
||||
|
||||
fun registerFactory(type: String, factory: SongFactory) {
|
||||
factories[type] = factory;
|
||||
}
|
||||
|
||||
suspend fun search(query: String, auth: AuthorizationData): SearchResult {
|
||||
val results = mutableMapOf<String, Collection<SearchResultItem>>()
|
||||
factories.forEach { (type, factory) ->
|
||||
results[type] = factory.search(query, auth)
|
||||
}
|
||||
return results.toMap()
|
||||
}
|
||||
|
||||
suspend fun create(type: String, id: String, songId: String, auth: AuthorizationData): Song =
|
||||
getFactory(type).create(id, songId, auth)
|
||||
|
||||
private fun getFactory(type: String) = factories[type]!!;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.factory
|
||||
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
|
||||
interface TrackFactory {
|
||||
suspend fun searchTrack(query: String, auth: AuthorizationData): Collection<Track>
|
||||
suspend fun createTrack(id: String, trackId: String, auth: AuthorizationData): Track
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.factory
|
||||
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
|
||||
class TrackFactoryProxy {
|
||||
private val factories = mutableMapOf<String, TrackFactory>()
|
||||
|
||||
fun registerFactory(type: String, factory: TrackFactory) {
|
||||
factories[type] = factory;
|
||||
}
|
||||
|
||||
suspend fun search(query: String, auth: AuthorizationData) =
|
||||
factories.values.map { it.searchTrack(query, auth) }.flatten()
|
||||
|
||||
suspend fun createTrack(type: String, id: String, trackId: String, auth: AuthorizationData): Track =
|
||||
getFactory(type).createTrack(id, trackId, auth)
|
||||
|
||||
private fun getFactory(type: String) = factories[type]!!;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package dev.fyloz.musicplayer.core.http
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
abstract class HttpProvider(private val baseUrl: String) : KoinComponent {
|
||||
protected val httpClient by inject<HttpClient>()
|
||||
protected open val acceptContentType = ContentType.Application.Json
|
||||
|
||||
protected suspend inline fun <reified T> get(
|
||||
path: String,
|
||||
bearer: String? = null,
|
||||
block: HttpRequestBuilder.() -> Unit = {}
|
||||
): T =
|
||||
httpClient.get(path.toUrl()) {
|
||||
accept(acceptContentType)
|
||||
|
||||
headers {
|
||||
if (bearer != null) {
|
||||
append(HttpHeaders.Authorization, bearer.toBearer())
|
||||
}
|
||||
}
|
||||
|
||||
block()
|
||||
}.process()
|
||||
|
||||
protected suspend inline fun <reified T> HttpResponse.process(): T {
|
||||
if (this.status.isSuccess()) {
|
||||
return this.body()
|
||||
}
|
||||
|
||||
throw IllegalStateException("TODO: Unsuccessful HTTP request: ${this.body<String>()}")
|
||||
}
|
||||
|
||||
protected fun String.toUrl(): String {
|
||||
if (baseUrl.endsWith('/') && this.startsWith('/')) {
|
||||
return baseUrl + this.substring(1, this.length)
|
||||
}
|
||||
|
||||
if (!this.startsWith('/')) {
|
||||
return "$baseUrl/$this"
|
||||
}
|
||||
|
||||
return baseUrl + this
|
||||
}
|
||||
|
||||
protected fun String.toBearer() = "Bearer $this"
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package dev.fyloz.musicplayer.core.http
|
||||
|
||||
import dev.fyloz.musicplayer.core.getAuthorizationData
|
||||
import dev.fyloz.musicplayer.core.http.requests.CreateSongRequest
|
||||
import dev.fyloz.musicplayer.core.logic.SongLogic
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import org.koin.ktor.ext.inject
|
||||
|
||||
fun Route.configureSongRoutes() {
|
||||
val logic by inject<SongLogic>()
|
||||
|
||||
route("/song") {
|
||||
get("/") {
|
||||
call.respond(logic.getAll().toList())
|
||||
}
|
||||
|
||||
get("/search") {
|
||||
val query = call.request.queryParameters["q"]!!
|
||||
val songs = logic.search(query, call.getAuthorizationData())
|
||||
call.respond(songs)
|
||||
}
|
||||
|
||||
post {
|
||||
val request = call.receive<CreateSongRequest>()
|
||||
val song = logic.save(request.type, request.songId, call.getAuthorizationData())
|
||||
call.respond(song)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.http
|
||||
|
||||
import dev.fyloz.musicplayer.core.getAuthorizationData
|
||||
import dev.fyloz.musicplayer.core.http.requests.CreateTrackRequest
|
||||
import dev.fyloz.musicplayer.core.logic.TrackLogic
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import org.koin.ktor.ext.inject
|
||||
|
||||
fun Route.configureTrackRoutes() {
|
||||
val logic by inject<TrackLogic>()
|
||||
|
||||
route("/track") {
|
||||
get("/") {
|
||||
call.respond(logic.getAll().toList())
|
||||
}
|
||||
|
||||
get("/search") {
|
||||
val query = call.request.queryParameters["q"]!!
|
||||
val tracks = logic.search(query, call.getAuthorizationData())
|
||||
call.respond(tracks)
|
||||
}
|
||||
|
||||
post {
|
||||
val request = call.receive<CreateTrackRequest>()
|
||||
val track = logic.save(request.type, request.trackId, call.getAuthorizationData())
|
||||
call.respond(track)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,4 +3,4 @@ package dev.fyloz.musicplayer.core.http.requests
|
|||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class CreateTrackRequest(val type: String, val trackId: String)
|
||||
data class CreateSongRequest(val type: String, val songId: String)
|
|
@ -0,0 +1,31 @@
|
|||
package dev.fyloz.musicplayer.core.logic
|
||||
|
||||
import dev.fyloz.musicplayer.core.data.SongRepository
|
||||
import dev.fyloz.musicplayer.core.factory.SongFactoryProxy
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.SearchResult
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.util.UUID
|
||||
|
||||
class SongLogic : KoinComponent {
|
||||
private val repository by inject<SongRepository>()
|
||||
private val songFactory by inject<SongFactoryProxy>()
|
||||
|
||||
fun getAll() = repository.findAll()
|
||||
fun getById(id: String) = repository.findById(id)
|
||||
|
||||
suspend fun search(query: String, auth: AuthorizationData): SearchResult {
|
||||
return songFactory.search(query, auth)
|
||||
}
|
||||
|
||||
suspend fun save(type: String, songId: String, auth: AuthorizationData): Song {
|
||||
val id = generateId()
|
||||
val song = songFactory.create(type, id, songId, auth)
|
||||
repository.save(song)
|
||||
return song
|
||||
}
|
||||
|
||||
private fun generateId() = UUID.randomUUID().toString()
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.logic
|
||||
|
||||
import dev.fyloz.musicplayer.core.data.TrackRepository
|
||||
import dev.fyloz.musicplayer.core.factory.TrackFactoryProxy
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.util.UUID
|
||||
|
||||
class TrackLogic : KoinComponent {
|
||||
private val repository by inject<TrackRepository>()
|
||||
private val trackFactory by inject<TrackFactoryProxy>()
|
||||
|
||||
fun getAll() = repository.findAll()
|
||||
fun getById(id: String) = repository.findById(id)
|
||||
|
||||
suspend fun search(query: String, auth: AuthorizationData): Collection<Track> {
|
||||
return trackFactory.search(query, auth)
|
||||
}
|
||||
|
||||
suspend fun save(type: String, trackId: String, auth: AuthorizationData): Track {
|
||||
val id = generateId()
|
||||
val track = trackFactory.createTrack(type, id, trackId, auth)
|
||||
repository.save(track)
|
||||
return track
|
||||
}
|
||||
|
||||
private fun generateId() = UUID.randomUUID().toString()
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package dev.fyloz.musicplayer.core.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
typealias SearchResult = Map<String, Collection<SearchResultItem>>
|
||||
|
||||
@Serializable
|
||||
data class SearchResultItem(
|
||||
val songId: String,
|
||||
val name: String,
|
||||
val authors: Collection<String>
|
||||
)
|
|
@ -0,0 +1,18 @@
|
|||
package dev.fyloz.musicplayer.core.model
|
||||
|
||||
/**
|
||||
* A generic song.
|
||||
*/
|
||||
abstract class Song {
|
||||
/** The id of the song in the local system. **/
|
||||
abstract val id: String
|
||||
|
||||
/** The id of the song in the remote service. **/
|
||||
abstract val songId: String
|
||||
|
||||
/** The name of the song. **/
|
||||
abstract val name: String
|
||||
|
||||
/** The name of the authors of the song. **/
|
||||
abstract val authors: Collection<String>
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.model
|
||||
|
||||
/**
|
||||
* A generic track.
|
||||
*/
|
||||
abstract class Track {
|
||||
/** The id of the track in the local system. **/
|
||||
abstract val id: String
|
||||
|
||||
/** The id of the track in the remote service. **/
|
||||
abstract val trackId: String
|
||||
|
||||
/** The name of the track. **/
|
||||
abstract val name: String
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package dev.fyloz.musicplayer.modules
|
||||
|
||||
import dev.fyloz.musicplayer.core.KoinModule
|
||||
import dev.fyloz.musicplayer.core.factory.TrackFactory
|
||||
import dev.fyloz.musicplayer.core.factory.TrackFactoryProxy
|
||||
import dev.fyloz.musicplayer.core.factory.SongFactory
|
||||
import dev.fyloz.musicplayer.core.factory.SongFactoryProxy
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.config.*
|
||||
import io.ktor.server.routing.*
|
||||
|
@ -14,8 +14,8 @@ abstract class Module(private val moduleName: String) {
|
|||
|
||||
open fun configure(app: Application) {
|
||||
with(app) {
|
||||
val trackFactoryProxy by inject<TrackFactoryProxy>()
|
||||
trackFactoryProxy.registerFactory(moduleName, getTrackFactory())
|
||||
val songFactoryProxy by inject<SongFactoryProxy>()
|
||||
songFactoryProxy.registerFactory(moduleName, getSongFactory())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,5 +39,5 @@ abstract class Module(private val moduleName: String) {
|
|||
protected open fun Route.configureModuleRoutes() {
|
||||
}
|
||||
|
||||
protected abstract fun getTrackFactory(): TrackFactory
|
||||
protected abstract fun getSongFactory(): SongFactory
|
||||
}
|
||||
|
|
|
@ -1,26 +1,12 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.SearchRequest
|
||||
import dev.fyloz.musicplayer.core.http.HttpProvider
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.SearchResponse
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.Track
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class SpotifyApiProvider : KoinComponent {
|
||||
private val client by inject<HttpClient>()
|
||||
|
||||
suspend fun search(query: String, type: String, accessToken: String): Collection<Track> {
|
||||
val requestBody = SearchRequest(query, type, "audio", 50, 0)
|
||||
val response = client.get("https://api.spotify.com/v1/search") {
|
||||
accept(ContentType.Application.Json)
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $accessToken")
|
||||
}
|
||||
// setBody(requestBody)
|
||||
class SpotifyApiProvider : HttpProvider("https://api.spotify.com/v1") {
|
||||
suspend fun search(query: String, type: String, accessToken: String): Collection<Track> =
|
||||
get<SearchResponse>("search", accessToken) {
|
||||
url {
|
||||
parameters.append("q", query)
|
||||
parameters.append("type", type)
|
||||
|
@ -28,19 +14,8 @@ class SpotifyApiProvider : KoinComponent {
|
|||
parameters.append("limit", "50")
|
||||
parameters.append("offset", "0")
|
||||
}
|
||||
}.body<SearchResponse>()
|
||||
}.tracks.items
|
||||
|
||||
return response.tracks.items
|
||||
}
|
||||
|
||||
suspend fun getTrackById(trackId: String, accessToken: String): Track {
|
||||
val response = client.get("https://api.spotify.com/v1/tracks/$trackId") {
|
||||
accept(ContentType.Application.Json)
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, "Bearer $accessToken")
|
||||
}
|
||||
}
|
||||
|
||||
return response.body()
|
||||
}
|
||||
suspend fun getSongById(songId: String, accessToken: String): Track =
|
||||
get("tracks/$songId", accessToken)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ import org.koin.dsl.module
|
|||
|
||||
object SpotifyInjection {
|
||||
val koinBeans = module {
|
||||
single<SpotifyTrackFactory> { SpotifyTrackFactory() }
|
||||
single<SpotifySongFactory> { SpotifySongFactory() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,15 +59,15 @@ class SpotifyModule : Module(moduleName) {
|
|||
get("/login-callback") {
|
||||
call.principal<OAuthAccessTokenResponse.OAuth2>()?.let {
|
||||
with(call.response.cookies) {
|
||||
append("Spotify-Access-Token", it.accessToken, maxAge = it.expiresIn)
|
||||
append("Spotify-Refresh-Token", it.refreshToken!!)
|
||||
append("Spotify-Access-Token", it.accessToken, maxAge = it.expiresIn, path = "/api/v1")
|
||||
append("Spotify-Refresh-Token", it.refreshToken!!, path = "/api/v1")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTrackFactory() = SpotifyTrackFactory()
|
||||
override fun getSongFactory() = SpotifySongFactory()
|
||||
|
||||
companion object {
|
||||
const val moduleName = "spotify"
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SpotifySong(
|
||||
override val id: String,
|
||||
override val songId: String,
|
||||
override val name: String,
|
||||
override val authors: Collection<String>
|
||||
) : Song()
|
|
@ -0,0 +1,23 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.core.factory.SongFactory
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.SearchResultItem
|
||||
import dev.fyloz.musicplayer.core.model.Song
|
||||
|
||||
class SpotifySongFactory : SongFactory {
|
||||
private val apiProvider = SpotifyApiProvider()
|
||||
|
||||
override suspend fun search(query: String, auth: AuthorizationData): Collection<SearchResultItem> {
|
||||
val apiSongs = apiProvider.search(query, "track", auth.accessToken)
|
||||
return apiSongs.map { SearchResultItem(it.id, it.name, it.artists.map { a -> a.name }) }
|
||||
}
|
||||
|
||||
override suspend fun create(id: String, songId: String, auth: AuthorizationData): Song {
|
||||
val spotifyApiSong = apiProvider.getSongById(songId, auth.accessToken);
|
||||
return SpotifySong(id, songId, spotifyApiSong.name, spotifyApiSong.artists.map { it.name })
|
||||
}
|
||||
|
||||
private val AuthorizationData.accessToken
|
||||
get() = getModuleData<SpotifyAuthorizationData>(SpotifyModule.moduleName).accessToken
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SpotifyTrack(
|
||||
override val id: String,
|
||||
override val trackId: String,
|
||||
override val name: String
|
||||
) : Track()
|
|
@ -1,22 +0,0 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.core.factory.TrackFactory
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
|
||||
class SpotifyTrackFactory : TrackFactory {
|
||||
private val apiProvider = SpotifyApiProvider()
|
||||
|
||||
override suspend fun searchTrack(query: String, auth: AuthorizationData): Collection<Track> {
|
||||
val apiTracks = apiProvider.search(query, "track", auth.accessToken)
|
||||
return apiTracks.map { SpotifyTrack("not-an-id", it.id, it.name) }
|
||||
}
|
||||
|
||||
override suspend fun createTrack(id: String, trackId: String, auth: AuthorizationData): Track {
|
||||
val spotifyApiTrack = apiProvider.getTrackById(trackId, auth.accessToken);
|
||||
return SpotifyTrack(id, trackId, spotifyApiTrack.name)
|
||||
}
|
||||
|
||||
private val AuthorizationData.accessToken
|
||||
get() = getModuleData<SpotifyAuthorizationData>(SpotifyModule.moduleName).accessToken
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify.api
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SearchRequest(
|
||||
@SerialName("q")
|
||||
val query: String,
|
||||
|
||||
val type: String,
|
||||
|
||||
@SerialName("include_external")
|
||||
val includeExternal: String,
|
||||
|
||||
val limit: Int,
|
||||
|
||||
val offset: Int
|
||||
)
|
|
@ -1,6 +1,5 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify.api
|
||||
|
||||
import dev.fyloz.musicplayer.modules.spotify.SpotifyTrack
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
|
Loading…
Reference in New Issue