Things
This commit is contained in:
parent
1e9be2c7c2
commit
c0c7a56f96
|
@ -32,13 +32,14 @@ dependencies {
|
|||
implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-core:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-auth:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-auth-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-locations-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-core-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-apache-jvm:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-logging-jvm:$ktor_version")
|
||||
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-auth-jvm:2.1.3")
|
||||
implementation("io.ktor:ktor-server-locations-jvm:2.1.3")
|
||||
implementation("io.ktor:ktor-client-core-jvm:2.1.3")
|
||||
implementation("io.ktor:ktor-client-apache-jvm:2.1.3")
|
||||
|
||||
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
|
||||
|
|
|
@ -1,27 +1,24 @@
|
|||
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.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.http.configureTrackRoutes
|
||||
import dev.fyloz.musicplayer.core.logic.TrackLogic
|
||||
import dev.fyloz.musicplayer.modules.spotify.SpotifyInjection
|
||||
import dev.fyloz.musicplayer.modules.spotify.SpotifyModule
|
||||
import dev.fyloz.musicplayer.modules.spotify.SpotifyTrackFactory
|
||||
import dev.fyloz.musicplayer.modules.Module
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.apache.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.client.plugins.logging.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.config.*
|
||||
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.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.koin.dsl.module
|
||||
import org.koin.ktor.ext.inject
|
||||
import org.koin.ktor.plugin.Koin
|
||||
import org.koin.logger.slf4jLogger
|
||||
import org.slf4j.event.Level
|
||||
|
@ -32,6 +29,11 @@ fun main() {
|
|||
}
|
||||
|
||||
fun Application.module() {
|
||||
val config = HoconApplicationConfig(ConfigFactory.load())
|
||||
|
||||
log.info("Loading modules...")
|
||||
registerModules(config)
|
||||
|
||||
install(CallLogging) {
|
||||
level = Level.DEBUG
|
||||
// filter { call -> call.request.path().startsWith("/") }
|
||||
|
@ -46,24 +48,72 @@ fun Application.module() {
|
|||
slf4jLogger()
|
||||
modules(
|
||||
RepositoryInjection.koinBeans,
|
||||
SpotifyInjection.koinBeans,
|
||||
|
||||
module {
|
||||
single { TrackFactoryProxy() }
|
||||
single { TrackLogic() }
|
||||
single {
|
||||
HttpClient {
|
||||
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
|
||||
json(Json {
|
||||
ignoreUnknownKeys = true
|
||||
})
|
||||
}
|
||||
|
||||
install(Logging) {
|
||||
level = LogLevel.ALL
|
||||
// filter { call -> call.request.path().startsWith("/") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registeredModules.values.forEach { it.setupDependencyInjection(this, config) }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val spotifyModule = SpotifyModule()
|
||||
spotifyModule.configure(this)
|
||||
registeredModules.values.forEach { it.configure(this) }
|
||||
|
||||
install(Routing) {
|
||||
spotifyModule.configureRoutes(this)
|
||||
registeredModules.values.forEach { it.configureRoutes(this) }
|
||||
|
||||
route("/api/v1") {
|
||||
configureTrackRoutes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val registeredModules = mutableMapOf<String, Module>()
|
||||
|
||||
fun ApplicationCall.getAuthorizationData(): AuthorizationData {
|
||||
val auth = AuthorizationData()
|
||||
|
||||
registeredModules.forEach { (moduleName, module) ->
|
||||
val data = module.getAuthorizationData(this)
|
||||
if (data != null) {
|
||||
auth.addModuleData(data, moduleName)
|
||||
}
|
||||
}
|
||||
|
||||
return auth
|
||||
}
|
||||
|
||||
private fun Application.registerModules(config: ApplicationConfig) {
|
||||
val enabledModules = config.property("modules.enabled").getList()
|
||||
enabledModules.forEach { registerModule(it, config) }
|
||||
}
|
||||
|
||||
private fun Application.registerModule(moduleName: String, config: ApplicationConfig) {
|
||||
log.debug("Found module '$moduleName'")
|
||||
val moduleClass = config.property("modules.$moduleName.class").getString()
|
||||
val module = loadModule(moduleClass)
|
||||
|
||||
registeredModules[moduleName] = module
|
||||
log.info("Registered module '$moduleName'")
|
||||
}
|
||||
|
||||
private fun Application.loadModule(moduleClass: String): Module {
|
||||
log.debug("Loading module class '$moduleClass'...")
|
||||
return Class.forName(moduleClass).getDeclaredConstructor().newInstance() as Module
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
package dev.fyloz.musicplayer.core
|
||||
|
||||
typealias KoinModule = org.koin.core.module.Module
|
|
@ -1,7 +1,9 @@
|
|||
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 createTrack(id: String, trackId: String): Track
|
||||
suspend fun searchTrack(query: String, auth: AuthorizationData): Collection<Track>
|
||||
suspend fun createTrack(id: String, trackId: String, auth: AuthorizationData): Track
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package dev.fyloz.musicplayer.core.factory
|
||||
|
||||
import dev.fyloz.musicplayer.core.http.auth.AuthorizationData
|
||||
import dev.fyloz.musicplayer.core.model.Track
|
||||
|
||||
class TrackFactoryProxy {
|
||||
|
@ -9,9 +10,11 @@ class TrackFactoryProxy {
|
|||
factories[type] = factory;
|
||||
}
|
||||
|
||||
suspend fun createTrack(type: String, id: String, trackId: String): Track {
|
||||
return getFactory(type).createTrack(id, trackId)
|
||||
}
|
||||
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]!!;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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.*
|
||||
|
@ -16,9 +17,15 @@ fun Route.configureTrackRoutes() {
|
|||
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)
|
||||
val track = logic.save(request.type, request.trackId, call.getAuthorizationData())
|
||||
call.respond(track)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package dev.fyloz.musicplayer.core.http.auth
|
||||
|
||||
class AuthorizationData {
|
||||
private val modulesData = mutableMapOf<String, Any>()
|
||||
|
||||
fun <T : Any> addModuleData(data: T, moduleName: String) {
|
||||
modulesData[moduleName] = data;
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> getModuleData(moduleName: String): T {
|
||||
return modulesData[moduleName] as T
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ 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 dev.fyloz.musicplayer.modules.spotify.SpotifyTrackFactory
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.util.UUID
|
||||
|
@ -15,9 +15,13 @@ class TrackLogic : KoinComponent {
|
|||
fun getAll() = repository.findAll()
|
||||
fun getById(id: String) = repository.findById(id)
|
||||
|
||||
suspend fun save(type: String, trackId: String): Track {
|
||||
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)
|
||||
val track = trackFactory.createTrack(type, id, trackId, auth)
|
||||
repository.save(track)
|
||||
return track
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package dev.fyloz.musicplayer.core.plugins
|
||||
|
||||
import io.ktor.server.plugins.callloging.*
|
||||
import org.slf4j.event.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.application.*
|
||||
|
||||
fun Application.configureMonitoring() {
|
||||
install(CallLogging) {
|
||||
level = Level.INFO
|
||||
filter { call -> call.request.path().startsWith("/") }
|
||||
}
|
||||
}
|
|
@ -1,12 +1,17 @@
|
|||
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 io.ktor.server.application.*
|
||||
import io.ktor.server.config.*
|
||||
import io.ktor.server.routing.*
|
||||
import org.koin.ktor.ext.inject
|
||||
|
||||
abstract class Module(private val moduleName: String) {
|
||||
open fun setupDependencyInjection(module: KoinModule, config: ApplicationConfig) {
|
||||
}
|
||||
|
||||
open fun configure(app: Application) {
|
||||
with(app) {
|
||||
val trackFactoryProxy by inject<TrackFactoryProxy>()
|
||||
|
@ -26,6 +31,8 @@ abstract class Module(private val moduleName: String) {
|
|||
}
|
||||
}
|
||||
|
||||
open fun getAuthorizationData(call: ApplicationCall): Any? = null
|
||||
|
||||
protected open fun Route.configureApiRoutes() {
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.SearchRequest
|
||||
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)
|
||||
url {
|
||||
parameters.append("q", query)
|
||||
parameters.append("type", type)
|
||||
parameters.append("include_external", "audio")
|
||||
parameters.append("limit", "50")
|
||||
parameters.append("offset", "0")
|
||||
}
|
||||
}.body<SearchResponse>()
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
data class SpotifyAuthorizationData(val accessToken: String)
|
|
@ -1,34 +0,0 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.Track
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class SpotifyHttpProvider {
|
||||
private val client = HttpClient {
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
ignoreUnknownKeys = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getTrackById(trackId: String, token: String): Track {
|
||||
val tmpToken =
|
||||
"Bearer BQAtodg3W_kHLVJhGLFD0YEOh5AFfxSsrvhk1n9c0ELrlQdoEkbyOXYncN1k3umPfqqR3sesLI8qpJMxJ6-98nc4Z7KenedLBGyHfvBPzWg_U8OtwWy6jEWl7MbeFJYO50GNj-XRLPv6EAA1hPrrSIOhJBvOygs6hcDAYfD-_moA"
|
||||
|
||||
val response = client.get("https://api.spotify.com/v1/tracks/$trackId") {
|
||||
accept(ContentType.Application.Json)
|
||||
headers {
|
||||
append(HttpHeaders.Authorization, tmpToken)
|
||||
}
|
||||
}
|
||||
|
||||
return response.body()
|
||||
}
|
||||
}
|
|
@ -1,58 +1,76 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.core.KoinModule
|
||||
import dev.fyloz.musicplayer.modules.Module
|
||||
import dev.fyloz.musicplayer.modules.spotify.config.SpotifyConfiguration
|
||||
import io.ktor.client.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.config.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import org.koin.ktor.ext.inject
|
||||
|
||||
class SpotifyModule : Module(moduleName) {
|
||||
override fun setupDependencyInjection(module: KoinModule, config: ApplicationConfig) {
|
||||
with(module) {
|
||||
single { SpotifyConfiguration.fromEnvironment(config) }
|
||||
}
|
||||
}
|
||||
|
||||
class SpotifyModule : Module("spotify") {
|
||||
override fun configure(app: Application) {
|
||||
super.configure(app)
|
||||
|
||||
val httpClient by app.inject<HttpClient>()
|
||||
val config by app.inject<SpotifyConfiguration>()
|
||||
|
||||
with(app) {
|
||||
authentication {
|
||||
oauth("auth-oauth-spotify") {
|
||||
oauth(oauthName) {
|
||||
urlProvider = { "http://localhost:8080/module/spotify/login-callback" }
|
||||
providerLookup = {
|
||||
OAuthServerSettings.OAuth2ServerSettings(
|
||||
name = "spotify",
|
||||
name = moduleName,
|
||||
authorizeUrl = "https://accounts.spotify.com/authorize",
|
||||
accessTokenUrl = "https://accounts.spotify.com/api/token",
|
||||
requestMethod = HttpMethod.Post,
|
||||
clientId = "1372bd3ebcad4f889994f9a3f675472b",
|
||||
clientSecret = "26ac249dc5ca4a309aa08f8cfcec9a60"
|
||||
clientId = config.clientId,
|
||||
clientSecret = config.clientSecret,
|
||||
defaultScopes = listOf("user-read-private user-read-email")
|
||||
)
|
||||
}
|
||||
client = HttpClient()
|
||||
client = httpClient
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAuthorizationData(call: ApplicationCall) = SpotifyAuthorizationData(
|
||||
call.request.cookies["Spotify-Access-Token"]!!
|
||||
)
|
||||
|
||||
override fun Route.configureModuleRoutes() {
|
||||
authenticate("auth-oauth-spotify") {
|
||||
authenticate(oauthName) {
|
||||
get("/login") {
|
||||
call.respondRedirect("https://accounts.spotify.com/authorize")
|
||||
}
|
||||
|
||||
get("/login-callback") {
|
||||
val principal: OAuthAccessTokenResponse.OAuth2? = call.principal()
|
||||
if (principal != null) {
|
||||
call.response.cookies.append("Spotify-Access-Token", principal.accessToken)
|
||||
|
||||
if (principal.refreshToken != null) {
|
||||
call.response.cookies.append("Spotify-Refresh-Token", principal.refreshToken!!)
|
||||
call.principal<OAuthAccessTokenResponse.OAuth2>()?.let {
|
||||
with(call.response.cookies) {
|
||||
append("Spotify-Access-Token", it.accessToken, maxAge = it.expiresIn)
|
||||
append("Spotify-Refresh-Token", it.refreshToken!!)
|
||||
}
|
||||
|
||||
// SpotifyTokenLogic(http)
|
||||
} else {
|
||||
call.respond(HttpStatusCode.Unauthorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTrackFactory() = SpotifyTrackFactory()
|
||||
|
||||
companion object {
|
||||
const val moduleName = "spotify"
|
||||
const val oauthName = "auth-oauth-spotify"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify
|
||||
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.AccessTokenRequest
|
||||
import dev.fyloz.musicplayer.modules.spotify.api.AccessTokenResponse
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.util.*
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class SpotifyTokenLogic : KoinComponent {
|
||||
private val httpClient by inject<HttpClient>()
|
||||
|
||||
suspend fun getAccessToken(authorizationCode: String) {
|
||||
val authorizationHeader = "1372bd3ebcad4f889994f9a3f675472b:26ac249dc5ca4a309aa08f8cfcec9a60".encodeBase64()
|
||||
|
||||
val call = httpClient.post("https://accounts.spotify.com/api/token") {
|
||||
contentType(ContentType.Application.FormUrlEncoded)
|
||||
accept(ContentType.Application.Json)
|
||||
setBody(AccessTokenRequest(authorizationCode, "http://localhost:8080/module/spotify/login-callback"))
|
||||
header("Authorization", "Basic $authorizationHeader")
|
||||
}
|
||||
|
||||
val response = call.body<AccessTokenResponse>()
|
||||
println(response.accessToken)
|
||||
}
|
||||
}
|
|
@ -1,14 +1,22 @@
|
|||
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 httpProvider = SpotifyHttpProvider()
|
||||
private val apiProvider = SpotifyApiProvider()
|
||||
|
||||
override suspend fun createTrack(id: String, trackId: String): Track {
|
||||
val spotifyApiTrack = httpProvider.getTrackById(trackId, "bla");
|
||||
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
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
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
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify.api
|
||||
|
||||
import dev.fyloz.musicplayer.modules.spotify.SpotifyTrack
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SearchResponse(
|
||||
val tracks: TrackSearchResponse
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class TrackSearchResponse(
|
||||
val href: String,
|
||||
val items: Collection<Track>,
|
||||
val limit: Int,
|
||||
val next: String,
|
||||
val offset: Int,
|
||||
val previous: String?,
|
||||
val total: Int
|
||||
)
|
|
@ -0,0 +1,15 @@
|
|||
package dev.fyloz.musicplayer.modules.spotify.config
|
||||
|
||||
import io.ktor.server.config.*
|
||||
|
||||
data class SpotifyConfiguration(
|
||||
val clientId: String,
|
||||
val clientSecret: String
|
||||
) {
|
||||
companion object {
|
||||
fun fromEnvironment(config: ApplicationConfig) = SpotifyConfiguration(
|
||||
config.property("modules.spotify.clientId").getString(),
|
||||
config.property("modules.spotify.clientSecret").getString()
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
modules {
|
||||
enabled = [ "spotify" ]
|
||||
|
||||
spotify {
|
||||
class = "dev.fyloz.musicplayer.modules.spotify.SpotifyModule"
|
||||
clientId = "1372bd3ebcad4f889994f9a3f675472b"
|
||||
clientSecret = "26ac249dc5ca4a309aa08f8cfcec9a60"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue